Skip to main content

Pool

Manages a pool of pooled connections to a PostgreSQL server (built on top of lightning-pool). Pool.query()/Pool.execute() acquire a connection, run the statement, and release the connection back automatically. Call acquire() directly when you need to hold a connection across several statements (e.g. a transaction).

Constructor​

new Pool(config?: PoolConfiguration | string)

ArgumentTypeDefaultDescription
configPoolConfiguration | stringPool configuration object or a connection string
import { Pool } from 'postgrejs';

const pool = new Pool({
host: 'localhost',
database: 'my_database',
max: 10,
});

Properties​

KeyTypeReadonlyDescription
configPoolConfigurationtrueReturns the pool's configuration object
acquiredConnectionsnumbertrueReturns the number of connections that are currently acquired
idleConnectionsnumbertrueReturns the number of unused (idle) connections in the pool
totalConnectionsnumbertrueReturns the total number of connections in the pool, idle or in use
pendingAcquiresnumbertrueReturns how many callers are waiting for a connection to be free; one that gave up after acquireTimeoutMillis is no longer counted. Since 3.15.0

Methods​

start()​

Starts the pool. Not required to be called explicitly — the pool starts automatically the first time acquire() is called.

start(): void

acquire()​

Obtains a connection from the connection pool. The caller is responsible for calling connection.close() (or release()) when done with it.

acquire(): Promise<Connection>

import { Pool } from 'postgrejs';

const pool = new Pool('postgres://localhost/my_database');
const connection = await pool.acquire();
try {
await connection.startTransaction();
await connection.query('update my_table set ref=1 where id=1');
await connection.commit();
} finally {
await connection.close();
}

release()​

Releases an acquired connection back to the pool. Equivalent to calling connection.close() on a pooled connection.

release(connection: Connection): Promise<void>

ArgumentTypeDefaultDescription
connectionConnectionThe connection to release

close()​

Shuts down the pool and destroys all resources.

close(terminateWait?: number): Promise<void>

ArgumentTypeDefaultDescription
terminateWaitnumber10000Time in ms to wait for active queries per connection before forcing termination
await pool.close();

execute()​

Acquires a connection, executes a script on it using the Simple Query protocol, and releases the connection.

execute(sql: string, options?: PoolScriptExecuteOptions): Promise<ScriptResult>

ArgumentTypeDefaultDescription
sqlstringSQL script that will be executed
optionsPoolScriptExecuteOptionsScriptExecuteOptions plus pipeline

query()​

Acquires a connection, runs a query on it using the Extended Query protocol, and releases the connection (unless cursor: true is set, in which case the connection is held until the returned Cursor is closed).

query(sql: string, options?: PoolQueryOptions): Promise<QueryResult>

ArgumentTypeDefaultDescription
sqlstringSQL script that will be executed
optionsPoolQueryOptionsQueryOptions plus pipeline
import { Pool } from 'postgrejs';

const pool = new Pool('postgres://localhost/my_database');
const result = await pool.query('select * from my_table where id=$1', {
params: [1],
});
console.log(result.rows);

PoolQueryOptions and PoolScriptExecuteOptions add one option on top of the connection-level options:

PropertyTypeDefaultDescription
pipelinebooleanfalseWhen true, lets this one-shot call share an in-flight pooled connection with other pipelined calls instead of acquiring one exclusively — subject to the pool's pipelineMaxQueries/pipelineMaxConnections. Ignored for statements that start a transaction or a COPY, and for query() when cursor: true is set.

transaction()​

Acquires a connection, runs fn inside a transaction on it via Connection.transaction(), and releases the connection back to the pool however that ends. A transaction can't be spread across separate Pool.query() calls, because each is free to land on a different connection; this method is how several statements share one.

transaction<T>(fn: (connection: Connection) => Promise<T>, options?: TransactionOptions): Promise<T>

ArgumentTypeDefaultDescription
fn(connection: Connection) => Promise<T>Run inside the transaction, on the acquired connection.
optionsTransactionOptionsIsolation level, read-only, deferrable — see Transaction Modes
import { Pool } from 'postgrejs';

const pool = new Pool('postgres://localhost/my_database');
await pool.transaction(async tx => {
await tx.query('insert into orders (total) values ($1)', { params: [total] });
await tx.query('update stock set n = n - 1 where sku = $1', { params: [sku] });
});

prepare()​

Acquires a connection and creates a PreparedStatement on it. The connection is held until the statement is closed, and is released back to the pool automatically when statement.close() is called.

prepare(sql: string, options?: StatementPrepareOptions): Promise<PreparedStatement>

ArgumentTypeDefaultDescription
sqlstringSQL script that will be executed
optionsStatementPrepareOptionsPrepare options

listen()​

Registers a listener on the given NOTIFY channel. The pool keeps one dedicated connection open for all of its listened channels, reconnecting (and re-issuing LISTEN) automatically if that connection drops.

listen(channel: string, callback: NotificationCallback): Promise<void>

ArgumentTypeDefaultDescription
channelstringName of the channel
callbackNotificationCallbackListener callback function
await pool.listen('my_event', (msg) => {
console.log(msg.channel, msg.payload);
});

unListen()​

Removes the existing registration for NOTIFY events on the given channel.

unListen(channel: string): Promise<void>

ArgumentTypeDefaultDescription
channelstringName of the channel

unListenAll()​

Removes existing registration for NOTIFY events on all channels, and closes the pool's dedicated notification connection.

unListenAll(): Promise<void>

Events​

acquire​

Triggered when a connection is acquired from the pool (forwarded from the underlying lightning-pool instance). The argument is the pool's internal connection resource, not the public Connection instance handed back by acquire().

(resource: object) => void

release​

Triggered when an acquired connection is returned to the pool (forwarded from the underlying pool's return event). Same internal-resource argument as acquire.

(resource: object) => void

destroy​

Triggered when a connection is destroyed and removed from the pool — an ordinary eviction (idle timeout, close(), a failed validation) as much as a connection that died unexpectedly. reason is what tells them apart.

(resource: object, reason?: ConnectionLostError) => void

ArgumentTypeDefaultDescription
resourceobjectSame internal-resource argument as acquire
reasonConnectionLostErrorOnly set when this connection's socket closed on its own rather than being evicted normally

error​

Two unrelated situations share this event, told apart by their shape:

(err: Error, info: { requestTime: number; tries: number; maxRetries: number }) => void — the pool failed to create a new connection (e.g. during acquire()'s retry loop).

(err: ConnectionLostError) => void — a pooled connection died rather than being evicted normally; also reported on destroy as its reason. Emitted with no second argument, which is what keeps the two cases unambiguous: check for info or err.code === '08006'.

ArgumentTypeDefaultDescription
errError | ConnectionLostErrorThe connection-creation error, or the reason a pooled connection was lost
infoobjectrequestTime, the attempt count so far, and the configured max retries — absent for a lost connection
pool.on('error', (err, info) => {
if (!info) console.warn('pooled connection lost:', err.processID);
else console.error('could not create a connection:', err);
});

notice​

Triggered whenever a pooled connection receives a NoticeResponse — a RAISE NOTICE, or PostgreSQL's own "table does not exist, skipping" from DROP TABLE IF EXISTS. The event carries the connection, the same as destroy, because a pool.query() caller never holds a Connection, so a notice raised by their own statement could not reach them any other way. Like debug/execute/query, only forwarded while something is listening on the pool.

(msg: DatabaseError, connection: Connection) => void

ArgumentTypeDefaultDescription
msgDatabaseErrorThe notice, shaped like an error
connectionConnectionThe pooled connection it arrived on
pool.on('notice', (msg, connection) => console.log(msg.severity, msg.message));
await pool.query('drop table if exists no_such_table'); // logs: NOTICE table "no_such_table" does not exist, skipping

debug​

Forwarded from any connection acquired after this event already had a listener attached on the pool — see Connection's debug event. Because the forwarding is wired up at acquire() time, a listener added after a connection was acquired misses that connection's debug events.

(event: { location: string; message: string; sql?: string; [key: string]: any }) => void

execute​

Forwarded from any connection acquired after this event already had a listener attached on the pool — see Connection's execute event. Same acquire-time-only caveat as debug.

(sql: string, options?: ScriptExecuteOptions) => void

query​

Forwarded from any connection acquired after this event already had a listener attached on the pool — see Connection's query event. Same acquire-time-only caveat as debug.

(sql: string, options?: QueryOptions) => void