← All write-ups

Reliability · ECS · SQS

Deploys that don't stall the queue

Moving our background workers from Elastic Beanstalk to ECS uncovered two gaps. Deploys were freezing customers' financial queues, and shutdown signals never reached the process. Here's how I fixed both.

Fortress OS · Oct 2026 · Designed and shipped

Context

Four Node.js workers handle financial, reporting, communications, and general jobs from SQS FIFO queues, with one message group per customer organization. FIFO keeps each customer's financial messages in order. It also means one stuck message blocks everything behind it for that customer.

Three problems, one root

Leases sized from data, not guesses

Each worker now holds a short visibility lease on its current message and renews it with ChangeMessageVisibility while the handler runs. A message only reappears if a full lease passes with no renewal, which means the worker died or its event loop stalled.

That makes the lease length an event-loop question. I set each lease from the 30-day maximum of event_loop.delay.max on the production workers:

WorkerLeaseHeartbeatWhy
financial120s30sWorst stall 27s; survives two missed heartbeats
general120s30sWorst stall 10s; long jobs wait on the database, not the loop
reports600s60sSynchronous PDF layout blocks the loop for 3–4 minutes daily
comms120s30sWorst stall 10s

A bounded drain

Proving it

Outcome

The change is merged and running on our ECS environments. Production picks it up at the ECS cutover, so the leases and the drain arrive with the migration rather than after a bad deploy proves they were needed.

This write-up describes work at Fortress OS. Details are generalized, and no customer data or internal identifiers are included.