Postgres Queues Actually Scale
Conventional wisdom says Postgres doesn't scale for queues, but this post details how to defy that. By leveraging SKIP LOCKED, careful isolation levels, and optimized indexing, the author demonstrates achieving 30,000 workflow executions per second. It's a deep dive into practical Postgres performance tuning that challenges long-held assumptions.
The Lowdown
Many believe Postgres isn't suitable for high-scale queues, advocating for dedicated systems like RabbitMQ or Redis. However, this article from DBOS challenges that notion, demonstrating how, with strategic optimizations, Postgres can indeed handle demanding queue workloads, achieving an impressive 30,000 workflow executions per second across thousands of servers.
- Rediscovering
SKIP LOCKED: The initial hurdle of worker contention—where multiple workers simultaneously try to dequeue the same tasks—is overcome using Postgres'sFOR UPDATE SKIP LOCKEDclause. This allows workers to concurrently select and lock unique sets of tasks, eliminating bottlenecks and enabling scalability beyond typical limits of ~100 workflows per second. - Mind the Transaction Isolation Levels: As concurrency increases,
REPEATABLE READisolation, often used for global queue limits, leads to frequent 'Serialization Failure' exceptions and costly retries. The solution involves conditionally switching toREAD COMMITTEDfor queues that utilize local worker limits rather than global ones, dramatically boosting throughput by avoiding serialization conflicts. - Indexes Aren't Free: At very high throughput (over ~8000 workflows/sec), inefficiencies in indexing and Postgres's auto-vacuum processes become a CPU bottleneck. The author refined indexes by making them more selective, including ordering directly in the index, and using partial indexes maintained only when relevant (e.g., for
ENQUEUEDitems or workflows with parents). This significantly reduced CPU usage by avoiding expensive sorts and minimizing index maintenance overhead.
These three key optimizations collaboratively transform Postgres into a highly capable queueing system, proving its unexpected potential for high-scale, durable execution. The article concludes by inviting readers to explore DBOS's work in this area.