What Are You Delegating?

Every abstraction is a trade: it removes work by making decisions for you. Those decisions are still being made — just not by you, and not visibly. For each abstraction: what it genuinely handles, what remains yours, and the escape hatch.

What are you delegating to a managed message queue?
Architecture
You write
1await queue.publish('order.created', { orderId })
The abstraction handles
  • Durable storage of the message until it is acknowledged
  • Delivery to consumers, redelivery on failure, dead-letter routing
  • Scaling consumers independently of producers
  • Buffering bursts the consumer cannot absorb in real time
Still your responsibility
  • At-least-once — the queue guarantees delivery, not uniqueness; deduplication is yours
  • Idempotent consumers — a worker that dies after the side effect and before the ack will see the message again
  • Ordering — global order is not a thing; per-key order is a partitioning decision you make
  • Backpressure — a queue absorbs a burst; it cannot fix a sustained producer > consumer imbalance
  • The outbox — publishing after commit, or committing after publish, loses or duplicates events under failure
Know your escape hatch

When: Messages are duplicated, reordered, or the backlog never drains.

Drop to: The delivery semantics: acks, visibility timeouts, partition keys, consumer lag — and an outbox table in your own database.

The queue did not break. It delivered exactly what it promised, which was not what you assumed.

Go deeper on this one: