Blue/Green Stateful Workers: Drain In-Flight Jobs Before Old Tasks Die

Blue/Green Stateful Workers: Drain In-Flight Jobs Before Old Tasks Die
5 views
Stateless HTTP blue/green is easy: drain connections. Stateful queue workers die messily—SIGTERM mid-batch duplicates SQS messages or abandons Kinesis checkpoints. The unfair advantage is a drain protocol: stop pulling, finish in-flight with a deadline, checkpoint, then exit—wired into ECS deployment circuit breakers.
⚡ TL;DR: On SIGTERM set accepting=false; stop ReceiveMessage / shard lease renewals; await in-flight with timeout < stopTimeout; delete/checkpoint only after success; size ECS stopTimeout above max job duration. Pair with Graceful Shutdown for Node and Lambda SQS Partial Batch Failures.

Blue/Green Stateful Workers: production guidance

text
RUNNING → DRAINING (SIGTERM) → IDLE (in-flight=0) → EXIT 0
 ↘ DEADLINE → nack/extend visibility → EXIT 1 (deploy retries)
typescript
// ✅ Node SQS worker drain
import { Consumer } from "sqs-consumer";

let accepting = true;
const inFlight = new Set<Promise<void>>();

const app = Consumer.create({
 queueUrl: process.env.QUEUE_URL!,
 handleMessage: async (msg) => {
 if (!accepting) throw new Error("draining"); // ✅ don't start new work
 const p = processMessage(msg).finally(() => inFlight.delete(p));
 inFlight.add(p);
 await p;
 },
 bodyParser: JSON.parse,
});

async function shutdown(signal: string) {
 console.info({ signal, msg: "drain_start", inFlight: inFlight.size });
 accepting = false;
 app.stop(); // stop polling
 const deadline = Date.now() + 25_000; // < ECS stopTimeout (30s)
 while (inFlight.size && Date.now() < deadline) {
 await Promise.race([...inFlight, sleep(200)]);
 }
 if (inFlight.size) {
 console.error({ left: inFlight.size, msg: "drain_timeout" });
 process.exit(1); // ✅ visibility timeout will redeliver
 }
 process.exit(0);
}

process.on("SIGTERM", () => void shutdown("SIGTERM"));
app.start();

Kinesis / EventBridge considerations

Source Drain action Risk if ignored
SQS Stop receive; let visibility expire on timeout Duplicate or lost ack
Kinesis Stop lease renew; checkpoint after record success Rewind / skip
DynamoDB Streams Same as Kinesis iterator Dual processing
ECS deployment stopTimeout > max handle time SIGKILL mid-write
bash
# ✅ ECS task def: stopTimeout seconds must exceed drain deadline
# stopTimeout: 60
# ❌ default 30s with 45s video transcodes → SIGKILL every deploy

Blue/green cutover order

  1. Start green tasks; wait healthy.
  2. Shift queue consumers by draining blue (desired count ↓) while green polls.
  3. For singleton lease workers, transfer DynamoDB lease before killing blue (Lease-Based ECS Leadership).
  4. Verify DLQ rate and lag gauges flat across the cut.
❌ Cutting load balancer first on a dual HTTP+SQS task — HTTP drains while SQS still receives until SIGTERM.

Closing checklist

✅ Dos – ✅ Gate new work on an accepting flag – ✅ Track in-flight promises/goroutines explicitly – ✅ Set stopTimeout > drain deadline > p99 job time – ✅ Make handlers idempotent for inevitable duplicates – ✅ Alert on drain timeouts per deploy ❌ Don’ts – ❌ Don’t ack before side effects commit – ❌ Don’t ignore SIGTERM (ECS will SIGKILL) – ❌ Don’t share one process for HTTP and multi-minute jobs without separate drain budgets – ❌ Don’t shrink visibility timeout below max processing time

Related reading

Last updated on September 11, 2026 Related: Claude Code: The Developer Workflow That Replaces 80% of Manual Coding Tasks; Copilot Workspace Tasks: Spec-Driven Changes Across Microservice Boundaries; Secure AI Sandboxes: Ephemeral ECS Tasks for Agent Tool Execution.

Watch: 100 Days of AI on YouTube

Short videos from CheatCoders, one AI engineering topic per day.

Open the playlist on YouTube · CheatCoders on YouTube

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a comment

No account needed. Name and email are optional.