There's a problem most teams running PostgreSQL-backed job queues don't talk about until they absolutely have to: bloat. The database equivalent of digital plaque buildup.
Under sustained load, the constant churn—rows updated, rows deleted, rows marked for cleanup but never quite cleaned fast enough—creates what a PlanetScale blog post on queue health describes as a "death spiral." Dead tuples accumulate faster than autovacuum can sweep them away. Indexes swell. Performance degrades, sometimes catastrophically. Teams running popular libraries like pg-boss or Solid Queue develop rituals around this. Periodic VACUUM FULL operations. Late-night pg_repack runs. Careful, sometimes obsessive tuning of vacuum settings.
It works. Until it doesn't.
Nikolay Samokhvalov thinks he's found a way out. The founder of Postgres.ai and co-host of the Postgres FM podcast recently released PgQue, an open-source queueing system that claims to sidestep the bloat problem entirely. Not by vacuuming smarter, but by avoiding the mess in the first place—no row-level updates or deletes on the hot path. Instead, it uses snapshot-based batching and table rotation, a pattern borrowed from PgQ, the circa-2007 engine developed at Skype that never quite made it to managed Postgres providers because it required C extensions and external daemons.
PgQue launched on Hacker News on April 19, quickly gathering over a hundred upvotes and sparking discussion. The pitch: zero-bloat queuing in a single SQL file, working on any Postgres 14+ instance. RDS, Aurora, Cloud SQL, Supabase, Neon—take your pick.
Whether it delivers on that promise is another question entirely.
The Core Trick: Don't Touch the Hot Data
The insight behind PgQue is almost aggressively simple. Producers append events to tables. A background ticker—typically pg_cron running every second—snapshots batches. Consumers read from those frozen batches using per-consumer cursors. Once all consumers have processed a batch, the system uses TRUNCATE to drop the entire table, then rotates to the next one.
No row-by-row deletions. No updates that generate dead tuples. No autovacuum pressure on the event tables themselves. In preliminary laptop-based testing documented in the repository, dead-tuple growth in event tables stayed at zero across a 30-minute run.
But there's a trade-off, and Samokhvalov doesn't hide it. Latency.
Because batching happens on a tick interval, end-to-end message delivery typically runs between one and two seconds with default settings. That's glacial compared to systems that use SKIP LOCKED or advisory locks for immediate dispatch. Samokhvalov addresses this head-on in the README: "If your top priority is single-digit-millisecond dispatch, PgQue is the wrong tool." If your priority is stability under load without bloat, though? That's where it might fit.
The honesty is refreshing, if perhaps a bit unusual for a project launch.
Built for the Managed Postgres World
PgQue takes what its documentation calls an "anti-extension" stance. Everything runs in pure SQL and PLpgSQL—no shared_preload_libraries, no superuser access required. It's a single SQL file and a ticker.
That ticker requirement, though, is non-negotiable. Without it, messages simply won't deliver. Most deployments will lean on pg_cron, which several managed platforms now support. For environments lacking pg_cron, the system supports application-driven ticking, though that adds operational complexity most teams would rather avoid.
The system creates three roles for least-privilege access: pgque_reader, pgque_writer, and pgque_admin. Client libraries exist for Go, Python, and TypeScript, though Samokhvalov labels the project "early-stage as a product and API layer." Translation: expect changes.
Not Really a Queue—More Like a Stream

Here's where things get interesting. Or confusing, depending on your perspective.
In the Hacker News discussion, Samokhvalov clarified something that might trip up teams evaluating PgQue: it's not really a job queue in the traditional sense. "It's closer to Kafka topics than to a job queue," he wrote, pointing to an open GitHub issue about potentially renaming the entire project.
The semantics matter more than they might seem. PgQue uses a shared event log with per-consumer cursors—fan-out to multiple independent consumers, no ACK-then-delete pattern, no visibility timeouts. Late subscribers can catch up without duplicating data. It's an append-only log that consumers read at their own pace.
This sets it distinctly apart from most Postgres-backed queues. PGMQ, from the Tembo/pgEdge ecosystem, uses SKIP LOCKED with claim/delete semantics and visibility timeouts. River (Go), pg-boss (Node), and graphile-worker (Node) all rely on row locking. Que (Ruby) uses advisory locks but explicitly warns about bloat when vacuum can't keep pace. None natively support fan-out the way PgQue does, though pg-boss can replicate events across queues.
The project includes built-in retry with backoff and a dead-letter queue for failed processing. Experimental features—not yet in the default install—cover delayed delivery (send_at) and observability helpers, including OpenTelemetry export.
Performance: Too Early to Tell

The benchmarks are preliminary. The repository shows laptop-based testing hitting north of 85,000 events per second, with a note that "server-class numbers to follow." Producer and subscriber calls run in sub-millisecond time; the latency stems from waiting for the next tick and consumer poll interval.
Those numbers don't answer the question of whether PgQue scales for production workloads. But they align with broader industry conversations about Postgres-as-queue that have intensified recently. A January Medium post argued that "Postgres is the only Queue you need (until 50k jobs/sec)," reflecting the trend toward consolidating infrastructure when possible. PlanetScale's documentation on queue health has documented SKIP LOCKED failure modes around 800 jobs per second when consumers fall behind—failures that motivate exactly this kind of alternative pattern.
Still. Laptop benchmarks are laptop benchmarks.
Getting Your Hands On It
PgQue ships under Apache 2.0 license and lives on Samokhvalov's GitHub account. Installation is a single SQL file. The API includes send/send_batch for producers, subscribe/unsubscribe/receive/ack/nack for consumers, and helpers for queue management and lifecycle control.
Documentation covers tutorials, reference material, and comparisons to alternatives. The project also exposes lower-level PgQ primitives for developers who need direct access.
Whether PgQue proves robust in production remains to be seen. Samokhvalov is explicit that it's early days. But for teams already wrestling with vacuum tuning and bloat mitigation on existing Postgres queues—and there are plenty of them—the approach deserves attention.
Sometimes the best way to solve a problem is to design around it entirely. Whether this is one of those times, we'll find out soon enough.
