Scaling the workers sometimes exacerbates the problem because you run into connection limits or polling hammering the DB.
I love the idea of pg as a queue, but I'm a more skeptical of it after dealing with it in production
11–20 of 41 posts
Scaling the workers sometimes exacerbates the problem because you run into connection limits or polling hammering the DB.
I love the idea of pg as a queue, but I'm a more skeptical of it after dealing with it in production
It's Kafka like one event stream and multiple independent worker cursors.
It's more SNS than SQS or Kafka than Rabbitmq/Nats
Any database that supports SKIP LOCKED is fine including MySQL, MSSQL, Oracle etc.
Even SQLite makes a fine queue not via skip locked but because writes are atomic.
I got Claude to analyze the code and it's not really comparable to SKIP LOCKED queues. It's more like Kafka. There's no job queue semantics with acks, workers taking from same job pool. It's Kafka like one event stream and multiple independent worker cursors. It's more SNS than SQS or Kafka than Rabbitmq/Nats
it's explained in README:
> Category: River, Que, and pg-boss (and Oban, graphile-worker, solid_queue, good_job) are job queue frameworks. PgQue is an event/message queue optimized for high-throughput streaming with fan-out.
I think it's great that projects like this exist where people are building middleware in different ways than others. Still, as someone who routinely uses shared memory queues, the idea of considering a queue built inside a database to be "zero bloat" leaves me scratching my head a bit. I can see why someone would want that, but once person's feature is bloat to someone else.
In Postgres land bloat refers to dead tuples that are left in place during certain operations and need to be vacuumed later. It’s challenging to write a queue that doesn’t create bloat, hence why this project is citing it as a feature.
The vacuum pressure is real. Using a system with the skip locked technique + polling caused massive DB perf issues as the queue depth grew. The query to see the current jobs in the queue ended up being the main performance bottleneck, which cause slower throughput, which caused a larger queue depth, which etc. Scaling the workers sometimes exacerbates the problem because you run into connection limits or polling hamm…
The vacuum pressure is real. Using a system with the skip locked technique + polling caused massive DB perf issues as the queue depth grew. The query to see the current jobs in the queue ended up being the main performance bottleneck, which cause slower throughput, which caused a larger queue depth, which etc. Scaling the workers sometimes exacerbates the problem because you run into connection limits or polling hamm…
Because the docs say:
PgQue avoids that whole class of problems. It uses snapshot-based batching and TRUNCATE-based table rotation instead of per-row deletion.
Would be great if you could specify if you had problems with the exact implementation linked by op or if you did write about a different thing, thanks!This is a log.
It's not really solving the problems you claim it solves. It's not, for instance, a replacement for SKIP LOCKED based queues.
Earlier quoted context omitted.
In Postgres land bloat refers to dead tuples that are left in place during certain operations and need to be vacuumed later. It’s challenging to write a queue that doesn’t create bloat, hence why this project is citing it as a feature.
Can’t you just partition the table by time (or whatever) and drop old partitions and not worry about vacuuming? Why do you need to keep around completed jobs forever?