Cos'è pg-boss
pg-boss è una libreria JavaScript/TypeScript per Node.js che trasforma un database PostgreSQL in una coda di job production-ready. Nata dal lavoro di Tim Jones, si propone come alternativa minimalista ma robusta a sistemi come Redis Queue, BullMQ, RabbitMQ o servizi gestiti come AWS SQS. La sua premessa è semplice: se già usi Postgres, puoi gestire code, retry, cron e dead letter queue senza aggiungere altri servizi alla tua architettura.
A differenza di molte soluzioni che richiedono un broker dedicato, pg-boss sfrutta funzionalità native di PostgreSQL — in particolare SKIP LOCKED, advisory lock e transazioni ACID — per garantire exactly-once delivery, concorrenza sicura e consistenza tra i dati applicativi e lo stato dei job. Questo lo rende particolarmente interessante per startup, PMI e agenzie che costruiscono SaaS su stack Node.js + PostgreSQL e vogliono ridurre la complessità operativa.
A cosa serve
pg-boss serve ogni volta che un'applicazione deve eseguire lavori in background in modo affidabile. Esempi tipici includono:
- invio di email, notifiche push o messaggi WhatsApp in modo asincrono;
- elaborazione di fatture, report PDF o esportazioni CSV;
- sincronizzazioni con API esterne, CRM o piattaforme di pagamento;
- webhooks: ricezione, validazione e inoltro affidabile verso endpoint di terze parti;
- flussi di onboarding, cleanup programmati e manutenzione del database;
- workflow più complessi con dipendenze tra job, schedule ricorrenti e gestione dei fallimenti.
La libreria è adatta sia a semplici script Node.js che a architetture più articolate basate su Server Actions di Next.js, API route, worker dedicati in container o processi pm2. Grazie al supporto per cron e job schedulati, può sostituire anche semplici scheduler Unix o servizi esterni come cron-job.org.
Come funziona
pg-boss si installa come pacchetto npm e si collega a un'istanza PostgreSQL esistente. Al primo avvio crea automaticamente le tabelle, gli indici e le stored procedure necessarie per la gestione della coda. Non richiede file di migrazione manuali, anche se in contesti enterprise è possibile gestirli esplicitamente con strumenti come Drizzle, Prisma o Flyway.
Il flusso base prevede tre concetti:
-
Pubblicazione (send): il codice applicativo inserisce un job in coda passando un nome di coda e un payload JSON. L'operazione avviene all'interno della stessa transazione del database che gestisce il business logic, garantendo che il job venga creato solo se il dato sottostante viene effettivamente salvato.
-
Sottoscrizione (work): uno o più worker si registrano su una coda. pg-boss assegna loro i job in modo atomico grazie a
SELECT ... FOR UPDATE SKIP LOCKED, impedendo che due worker elaborino lo stesso messaggio. Se un worker fallisce, il job viene rispedito in coda fino a un numero massimo di retry configurabile. -
Stati e lifecycle: ogni job attraversa stati come
created,retry,completed,cancelledofailed. È possibile interrogare questi stati, cancellare job futuri, riprogrammarli o spostarli in una dead letter queue per analisi successive.
Oltre alle code semplici, pg-boss offre funzionalità avanzate: job con ritardo (startAfter), ripetizioni cron, batching, job figli, rate limiting per coda, elaborazione in parallelo con controllo della concorrenza, e un'architettura a "team" che permette di bilanciare il carico tra più istanze di worker. La versione 12 ha introdotto miglioramenti significativi in termini di performance, API async/await più pulite e supporto TypeScript nativo.
Perché conta
Il valore principale di pg-boss sta nel co-locare dati e coda nello stesso database. Questa scelta architetturale ha conseguenze pratiche importanti.
Primo, elimina il rischio di inconsistenze tra lo stato applicativo e lo stato della coda. Quando un utente completa un ordine, la transazione Postgres può salvare l'ordine e pubblicare il job di conferma email nello stesso momento: o succedono entrambe le cose, o non succede nulla. Senza questa garanzia, si finisce spesso a scrivere codice di compensazione complesso.
Secondo, riduce il costo e la complessità operativa. Per una startup o un'agenzia che gestisce molti progetti, non dover provisioningare, monitorare e aggiornare Redis o un message broker separato significa meno infrastruttura da mantenere, meno rotte di rete e meno superficie d'attacco.
Terzo, pg-boss è serverless-friendly. Essendo basato su Postgres, funziona bene con piattaforme come Vercel, Railway, Render o AWS Lambda, dove un broker stateful come Redis può essere costoso o problematico in termini di connessioni. I worker possono essere avviati come processi separati, container o funzioni schedulate.
Quarto, la libreria è matura e mantenuta attivamente. Alla data di redazione di questa scheda è disponibile la versione 12.x, con release frequenti, documentazione completa e una community che la usa in produzione. La licenza MIT la rende adatta a progetti commerciali senza vincoli.
Limiti e quando sceglierlo
pg-boss non è la soluzione ideale per ogni scenario. Se il volume di messaggi è molto elevato (decine di migliaia di job al secondo) o se la latenza di enqueue/dequeue è critica al millisecondo, un broker in-memory come Redis o un sistema specializzato come Apache Kafka possono offrire performance superiori. Allo stesso modo, se l'applicazione richiede pattern complessi di publish/subscribe o streaming eventi, conviene valutare strumenti nativamente pensati per quel modello.
Dove pg-boss eccelle è nel tipico SaaS B2B italiano: applicazioni Next.js o Node.js con Postgres, carichi moderati-alti, necessità di affidabilità e semplicità operativa. Per founder, PM e sviluppatori di agenzie che vogliono aggiungere elaborazioni asincrone senza ingolfare lo stack, rappresenta un compromesso eccellente tra potenza e leggerezza.
Dove trovarlo
Il codice sorgente è disponibile su GitHub al repository timgit/pg-boss, distribuito con licenza MIT. Il pacchetto è pubblicato su npm come pg-boss e la documentazione ufficiale — con esempi d'uso, API reference e guide sul deployment — è ospitata su GitHub Pages. Per iniziare basta un'istanza PostgreSQL 12 o superiore e Node.js 18 o superiore.
