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.
An ORMAn HTTP client or SDKA managed database or cloud platformAn identity providerAn LLM or coding agentA web frameworkA library functionA managed message queueA cacheA container runtime and orchestrator
What are you delegating to a managed message queue?
ArchitectureYou 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: