Transactional outbox delivery
Budget for backlog recovery as well as ordinary traffic
A publisher sized only for normal arrivals may never catch up after an outage. Estimate spare throughput and protect the database while draining delayed work.
In this article
Compare arrival and service rates
Measure events created per second and the publisher's sustained successful delivery rate under realistic conditions. The difference is the capacity available to reduce a backlog while new events continue arriving.
For an illustrative workload, arrivals of 100 events per second and delivery capacity of 150 leave 50 events per second for catch-up. A backlog of 30,000 events would take about ten minutes to drain at those steady rates. Real variation, retries and consumer limits can make it longer.
Do not use peak benchmark throughput as sustained capacity without testing the database and destination under the same load.
Include storage and polling work
Outbox rows consume storage and indexes until the retention process removes or archives them. Frequent empty polls also create database work, while large batches can hold resources and produce bursty broker traffic.
Tune polling and batch size against latency requirements and observed load. A shorter interval is not automatically better if it competes with the business transactions that create the events.
Keep cleanup separate from publication correctness. Deleting records too early can remove recovery evidence, while retaining everything indefinitely can burden the primary database.
Respect downstream capacity
Draining the outbox quickly can overwhelm consumers or external systems. Measure the complete path and use bounded concurrency or rate controls where needed.
Prioritisation requires an explicit ordering policy. Moving urgent events ahead may be reasonable across independent aggregates, but it can violate a per-order sequence if applied blindly.
Isolate permanently failing events according to the business rule so they do not consume endless attempts or block unrelated work. Keep their age and unresolved status visible rather than making the backlog look healthy by hiding them.
Rehearse an outage-sized backlog
Pause publication in a controlled environment, accumulate a representative backlog and resume while ordinary traffic continues. Measure database load, oldest-event age, consumer lag and failure rates.
Use the results to set recovery expectations and reserve capacity. Include operator effort for poison events and reconciliation in the operating cost.
A dependable outbox service has enough headroom to recover from plausible interruptions without damaging the primary application. Normal-day throughput is only one part of that capacity decision.
Primary sources
AWS: transactional outbox patternPostgreSQL: SELECT and SKIP LOCKEDReferences checked 11 September 2026.