pg.Pool
constructor
new Pool([config: object])
Every field of the config
object is entirely optional. The config passed to the pool is also passed to every client instance within the pool when the pool creates that client.
config = {// all valid client config options are also valid here// in addition here are the pool specific configuration parameters:// number of milliseconds to wait before timing out when connecting a new client// by default this is 0 which means no timeoutconnectionTimeoutMillis?: int,// number of milliseconds a client must sit idle in the pool and not be checked out// before it is disconnected from the backend and discarded// default is 10000 (10 seconds) - set to 0 to disable auto-disconnection of idle clientsidleTimeoutMillis?: int,// maximum number of clients the pool should contain// by default this is set to 10.max?: int,}
example to create a new pool with configuration:
const { Pool } = require('pg')const pool = new Pool({host: 'localhost',user: 'database-user',max: 20,idleTimeoutMillis: 30000,connectionTimeoutMillis: 2000,})
pool.connect
pool.connect(callback: (err?: Error, client?: pg.Client, release?: releaseCallback) => void) => void
Acquires a client from the pool. If the pool is 'full' and all clients are currently checked out, this will wait in a FIFO queue until a client becomes available by it being released back to the pool. If there are idle clients in the pool it will be returned to the callback on process.nextTick
. If the pool is not full a new client will be created & returned to this callback.
const { Pool } = require('pg')const pool = new Pool()pool.connect((err, client, release) => {if (err) {return console.error('Error acquiring client', err.stack)}client.query('SELECT NOW()', (err, result) => {release()if (err) {return console.error('Error executing query', err.stack)}console.log(result.rows)})})
pool.connect() => Promise<pg.Client>
const { Pool } = require('pg')const pool = new Pool();(async function() {const client = await pool.connect()await client.query('SELECT NOW()')client.release()})()
releaseCallback
release: (err?: Error)
The releaseCallback
releases an acquired client back to the pool. If you pass a truthy value in the err
position to the callback, instead of releasing the client to the pool, the pool will be instructed to disconnect and destroy this client, leaving a space within itself for a new client.
const { Pool } = require('pg')const pool = new Pool()assert(pool.totalCount === 0)assert(pool.idleCount === 0);(async function() {const client = await pool.connect()await client.query('SELECT NOW()')assert(pool.totalCount === 1)assert(pool.idleCount === 0)// tell the pool to destroy this clientclient.release(true)assert(pool.idleCount === 0)assert(pool.totalCount === 0)})()
Client instances returned from pool.connect
will have a release
method which will release them from the pool. This is the same method that is passed to the connect callback as the 3rd argument if you're using the pool with callbacks.
const { Pool } = require('pg')const pool = new Pool()pool.connect((err, client, release) => {assert(client.release === release)})
pool.query
Often we only need to run a single query on the database, so as convenience the pool has a method to run a query on the first available idle client and return its result.
pool.query(callback: (err?: Error, result: pg.Result)) => void
const { Pool } = require('pg')const pool = new Pool()pool.query('SELECT $1::text as name', ['brianc'], (err, result) => {if (err) {return console.error('Error executing query', err.stack)}console.log(result.rows[0].name) // brianc})
Promises are also supported:
pool.query() => Promise<pg.Result>
const { Pool } = require('pg')const pool = new Pool()pool.query('SELECT $1::text as name', ['brianc']).then(res => console.log(res.rows[0].name)) // brianc.catch(err => console.error('Error executing query', err.stack))
Notice in the example above no releaseCallback
was necessary. The pool is doing the acquiring and releasing internally. I find pool.query
to be a handy shortcut in a lot of situations.
pool.end
Calling pool.end
will drain the pool of all active clients, disconnect them, and shut down any internal timers in the pool. It is common to call this at the end of a script using the pool or when your process is attempting to shut down cleanly.
// again both promises and callbacks are supported:const { Pool } = require('pg')const pool = new Pool()// either this:pool.end(() => {console.log('pool has ended')})// or this:pool.end().then(() => console.log('pool has ended'))
properties
pool.totalCount: int
The total number of clients existing within the pool.
pool.idleCount: int
The number of clients which are not checked out but are currently idle in the pool.
pool.waitingCount: int
The number of queued requests waiting on a client when all clients are checked out. It can be helpful to monitor this number to see if you need to adjust the size of the pool.
events
Pool
instances are also instances of EventEmitter
.
pool.on('connect', (client: Client) => void) => void
Whenever the pool establishes a new client connection to the PostgreSQL backend it will emit the connect
event with the newly connected client. This presents an opportunity for you to run setup commands on a client.
const pool = new Pool()pool.on('connect', client => {client.query('SET DATESTYLE = iso, mdy')})
pool.on('acquire', (client: Client) => void) => void
Whenever a client is checked out from the pool the pool will emit the acquire
event with the client that was acquired.
pool.on('error', (err: Error, client: Client) => void) => void
When a client is sitting idly in the pool it can still emit errors because it is connected to a live backend. If the backend goes down or a network partition is encountered all the idle, connected clients in your application will emit an error through the pool's error event emitter. The error listener is passed the error as the first argument and the client upon which the error occurred as the 2nd argument. The client will be automatically terminated and removed from the pool, it is only passed to the error handler in case you want to inspect it.
pool.on('remove', (client: Client) => void) => void
Whenever a client is closed & removed from the pool the pool will emit the remove
event.