Skip to content
A Publish/Subscribe implementation on top of PostgreSQL NOTIFY/LISTEN
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.


Type Name Latest commit message Commit time
Failed to load latest commit information.

PG PubSub

A Publish/Subscribe implementation on top of PostgreSQL NOTIFY/LISTEN

Linting Build Status Node CI Build Status Coverage Status dependencies Status Known Vulnerabilities js-semistandard-style


npm install pg-pubsub --save


Node.js >= 10.x Postgres >= 9.4


const PGPubsub = require('pg-pubsub');
const pubsubInstance = new PGPubsub(uri[, options]);


  [log]: Function // default: silent when NODE_ENV=production, otherwise defaults to console.log(...)


  • addChannel(channelName[, eventListener]) – starts listening on a channel and optionally adds an event listener for that event. As PGPubsub inherits from EventEmitter one also add it oneself.
  • removeChannel(channelName[, eventListener]) – either removes all event listeners and stops listeneing on the channel or removes the specified event listener and stops listening on the channel if that was the last listener attached.
  • publish(channelName, data) – publishes the specified data JSON-encoded to the specified channel. It may be better to do this by sending the NOTIFY channelName, '{"hello":"world"}' query yourself using your ordinary Postgres pool, rather than relying on the single connection of this module. Returns a Promise that will become rejected or resolved depending on the success of the Postgres call.
  • close(): Promise – closes down the database connection and removes all listeners. Useful for graceful shutdowns.
  • All EventEmitter methods are inherited from EventEmitter



const pubsubInstance = new PGPubsub('postgres://username@localhost/database');

pubsubInstance.addChannel('channelName', function (channelPayload) {
  // Process the payload – if it was JSON that JSON has been parsed into an object for you

pubsubInstance.publish('channelName', { hello: "world" });

The above sends NOTIFY channelName, '{"hello":"world"}' to PostgreSQL, which will trigger the above listener with the parsed JSON in channelPayload.


const pubsubInstance = new PGPubsub('postgres://username@localhost/database');


// pubsubInstance is a full EventEmitter object that sends events on channel names
pubsubInstance.once('channelName', function (channelPayload) {
  // Process the payload


Creating a PGPubsub instance will not do much up front. It will prepare itself to start a Postgres connection once the first channel is added and then it will keep a connection open until its shut down, reconnecting it if it gets lost, so that it can constantly listen for new notifications.

Lint / Test

  • setup a postgres database to run the integration tests
    • the easist way to do this is via docker, docker run -it -p 5432:5432 -e POSTGRES_DB=pgpubsub_test postgres
  • npm test

For an all-in-one command, try:

# fire up a new DB container, run tests against it, and clean it up!
docker rm -f pgpubsub_test || true && \
docker run -itd -p 5432:5432 -e POSTGRES_DB=pgpubsub_test --name pgpubsub_test postgres && \
npm test && \
docker rm -f pgpubsub_test
You can’t perform that action at this time.