August 18th, 2024

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 articleLink Icon
InterestSkepticismEnthusiasm
Show HN: PgQueuer – Transform PostgreSQL into a Job Queue

PgQueuer 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.

AI: What people are saying
The comments on PgQueuer highlight various perspectives on job queue libraries and their implementations.
  • 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.
Link Icon 28 comments
By @westurner - 4 months
Does the celery SQLAlchemy broker support PostgreSQL's LISTEN/NOTIFY features?

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

By @airocker - 4 months
We use listen notify extensively and it is great. The things it lacks most for us is guaranteed single recipient. All subscribers get all notifications which leads to problems in determining who should act on the message n our case.
By @CowOfKrakatoa - 4 months
How does LISTEN/NOTIFY compare to using select for update skip locked? I thought listen/notify can lose queue items when the process crashes? Is that true? Do you need to code for those cases in some manner?
By @rtpg - 4 months
I am going to go the other direction on this... to anyone reading this, please consider using a backend-generic queueing system for your Python project.

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!

By @odie5533 - 4 months
I've been referring to this post about issues with Celery: https://docs.hatchet.run/blog/problems-with-celery

Does PgQueuer address any of them?

By @ijustlovemath - 4 months
You could even layer in PostgREST for a nice HTTP API that is available from any language!
By @martinald - 4 months
Any suggestions for something like this for dotnet?
By @fijiaarone - 4 months
You can make anything that stores data into a job queue.
By @nifal_adam - 4 months
It looks like PgQueuer integrates well with Postgres RPC calls, triggers, and cronjobs (via pg_cron). Interesting, will check it out.
By @rgbrgb - 4 months
Cool, congrats on releasing. Have you seen graphile worker? Wondering how this compares or if you're building for different use-cases.
By @_joel - 4 months
Broadcaster is one we use in production for PUB/SUB stuff with OPA/OPAL. https://pypi.org/project/broadcaster/
By @bfelbo - 4 months
How does this compare to the popular Graphile Worker library?

https://github.com/graphile/worker

By @piyushtechsavy - 4 months
Although I am more of a MySQL guy, I have been exploring PostgreSQL from sometime. Seems it has lot of features out of box.

This is very interesting tool.

By @mslot - 4 months
Nice! Seems to be pretty well-crafted.
By @CRConrad - 4 months
The name is perhaps slightly fraught with risk... I missed the second 'u', at first, so I misread it.
By @joseferben - 4 months
for typescript there is pg-boss, works great for us
By @worik - 4 months
Why so much code for Avery simple concept

One table.

Producer writes Co sumer reads

A very good idea

By @cklee - 4 months
I’ve been thinking about the potential for PostgreSQL-backed job queue libraries to share a common schema. For instance, I’m a big fan of Oban in Elixir: https://github.com/sorentwo/oban

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.

By @samwillis - 4 months
This looks like a great task queue, I'm a massive proponent of "Postgres is all you need" [0] and doubling down on it with my project that takes it to the extreme.

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.

0: https://www.amazingcto.com/postgres-for-everything/

By @aflukasz - 4 months
BTW: Good PostgresFM episode on implementing queues in Postgres, various caveats etc: https://www.youtube.com/watch?v=mW5z5NYpGeA .
By @kdunglas - 4 months
The Symfony framework (PHP) provides a similar feature, which also relies on LISTEN/NOTIFY and FOR UPDATE SKIP LOCKED: https://symfony.com/doc/current/messenger.html#doctrine-tran...

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).

By @gmag - 4 months
You might also want to look at River (https://github.com/riverqueue/river) for inspiration as they support scheduled jobs, etc.

From an end-user perspective, they also have a UI which is nice to have for debugging.

By @_medihack_ - 4 months
There is also Procrastinate: https://procrastinate.readthedocs.io/en/stable/index.html

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.

By @bdcravens - 4 months
Good Job does the same for Rails

https://github.com/bensheldon/good_job

By @mads_quist - 4 months
I really like the emergence of simple queuing tools for robust database management systems. Keep things simple and remove infrastructure complexity. Definitely a +1 from me!

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.
By @jackbravo - 4 months
Most of the small python alternatives I've seen use Redis as backend:

- https://github.com/rq/rq - https://github.com/coleifer/huey - https://github.com/resque/resque

By @redskyluan - 4 months
there seems to be a big hype to adapt pg into any infra. I love PG but this seems not be right thing.
By @est - 4 months
The most simple job queue in MySQL:

    update job_table set key=value where ... limit 1
It's simple and atomic. Unfortunately PG doesn't allow `update ... limit` syntax