Show HN: PgQueuer – Transform PostgreSQL into a Job Queue
PgQueuer is a Python job queue library using PostgreSQL, offering efficient concurrency, real-time notifications, and easy installation via pip. It includes examples for consumers and producers, with additional resources available.
Read original articlePgQueuer is a high-performance job queue library for Python that leverages PostgreSQL for managing job queues. It is designed for simplicity and efficiency, making it easy to integrate into existing Python applications. Key features include straightforward integration with Python applications, efficient concurrency handling through PostgreSQL's `FOR UPDATE SKIP LOCKED`, and real-time notifications using `LISTEN` and `NOTIFY` for job status updates. Installation is done via pip with the command `pip install PgQueuer`. The library provides examples for both consumers and producers. The consumer example demonstrates setting up a long-lived consumer to process jobs, while the producer example shows how to enqueue jobs. Additional resources include documentation, source code on GitHub, and a community discussion platform on Discord. PgQueuer is particularly suitable for developers seeking a reliable job queue system within their Python applications.
- PgQueuer is a minimalist job queue library for Python using PostgreSQL.
- It features efficient concurrency handling and real-time notifications.
- Installation is simple via pip.
- The library includes examples for both job consumers and producers.
- Additional resources are available for documentation and community support.
- Many users compare PgQueuer to other job queue systems, particularly those using Redis, and express interest in its PostgreSQL integration.
- There are discussions about the advantages of using PostgreSQL's LISTEN/NOTIFY features versus other methods like SELECT FOR UPDATE SKIP LOCKED.
- Some commenters express concerns about potential issues with message loss and the need for robust error handling in job queues.
- Several users suggest alternative libraries and frameworks, indicating a diverse ecosystem of job queue solutions across different programming languages.
- There is a general appreciation for simplifying infrastructure and leveraging PostgreSQL's capabilities for job management.
Similar support in SQLite would simplify testing applications built with celery.
How to add table event messages to SQLite so that the SQLite broker has the same features as AMQP? Could a vtable facade send messages on tablet events?
Are there sqlite Triggers?
Celery > Backends and Brokers: https://docs.celeryq.dev/en/stable/getting-started/backends-...
/? sqlalchemy listen notify: https://www.google.com/search?q=sqlalchemy+listen+notify :
asyncpg.Connection.add_listener
sqlalchemy.event.listen, @listen_for
psychopg2 conn.poll(), while connection.notifies
psychopg2 > docs > advanced > Advanced notifications: https://www.psycopg.org/docs/advanced.html#asynchronous-noti...
PgQueuer.db, PgQueuer.listeners.add_listener; asyncpg add_listener: https://github.com/janbjorge/PgQueuer/blob/main/src/PgQueuer...
asyncpg/tests/test_listeners.py: https://github.com/MagicStack/asyncpg/blob/master/tests/test...
/? sqlite LISTEN NOTIFY: https://www.google.com/search?q=sqlite+listen+notify
sqlite3 update_hook: https://www.sqlite.org/c3ref/update_hook.html
Why? Mainly because those systems offer good affordances for testing and running locally in an operationally simple way. They also tend to have decent default answers for various futzy questions around disconnects at various parts of the workflow.
We all know Celery is a buggy pain in the butt, but rolling your own job queue likely ends up with you just writing a similary-buggy pain in the butt. We've already done "Celery but simpler", it's stuff like Dramatiq!
If you have backend-specific needs, you won't listen to this advice. But think deeply how important your needs are. Computers are fast, and you can deal with a lot of events with most systems.
Meanwhile if you use a backend-generic system... well you could write a backend using PgQueuer!
Does PgQueuer address any of them?
This is very interesting tool.
One table.
Producer writes Co sumer reads
A very good idea
Given that there are many Sidekiq-compatible libraries across various languages, it might be beneficial to have a similar approach for PostgreSQL-based job queues. This could allow for job processing in different languages while maintaining compatibility.
Alternatively, we could consider developing a core job queue library in Rust, with language-specific bindings. This would provide a robust, cross-language solution while leveraging the performance and safety benefits of Rust.
What I would love is a Postgres task queue that does multi-step pipelines, with fan out and accumulation. In my view a structured relational database is a particularly good backend for that as it inherently can model the structure. Is that something you have considered exploring?
The one thing with listen/notify that I find lacking is the max payload size of 8k, it somewhat limits its capability without having to start saving stuff to tables. What I would really like is a streaming table, with a schema and all the rich type support... maybe one day.
It also supports many other backends including AMQP, Beanstalkd, Redis and various cloud services.
This component, called Messenger, can be installed as a standalone library in any PHP project.
(Disclaimer: I’m the author of the PostgreSQL transport for Symfony Messenger).
From an end-user perspective, they also have a UI which is nice to have for debugging.
Procrastinate also uses PostgreSQL's LISTEN/NOTIFY (but can optionally be turned off and use polling). It also supports many features (and more are planned), like sync and async jobs (it uses asyncio under the hood), periodic tasks, retries, task locks, priorities, job cancellation/aborting, Django integration (optional).
DISCLAIMER: I am a co-maintainer of Procrastinate.
For handling straightforward asynchronous tasks like sending opt-in emails, we've developed a similar library at All Quiet for C# and MongoDB: https://allquiet.app/open-source/mongo-queueing
In this context:
LISTEN/NOTIFY in PostgreSQL is comparable to MongoDB's change streams.
SELECT FOR UPDATE SKIP LOCKED in PostgreSQL can be likened to MongoDB's atomic read/update operations.
- https://github.com/rq/rq - https://github.com/coleifer/huey - https://github.com/resque/resque
update job_table set key=value where ... limit 1
It's simple and atomic. Unfortunately PG doesn't allow `update ... limit` syntax