A service holds a few long-lived connections and never connects per query

Table of Contents

1. Summary

A service process opens its database connections when it starts and keeps them for its whole life. The pool is small, as many connections as the service runs queries at once, which is its worker count. No query opens a connection of its own: a connection costs a name lookup, a TCP handshake, a SCRAM login and the session setup, milliseconds of CPU for a query that runs in a fraction of one.

2. Detail

2.1. What the pool holds

Every connection authenticates once, at start or when it replaces a broken connection. A connection carries no tenant and no party between transactions (A transaction sets its own tenant context, so any connection serves any tenant), so any connection serves any request. The pool hands a connection to one transaction at a time and takes it back when the transaction ends.

2.2. How large it is

The pool is as large as the service's worker pool (Delivery threads enqueue and a bounded pool runs the handlers), because a worker is what holds a connection, and a connection no worker can use is idle. A service with only control-plane work holds two to four. The marketdata service holds the same small pool for its reads, and each tick lane holds one more connection of the writer role, outside the pool and around the pooler (Ticks reach the store through sharded binary COPY in bounded batches). The count for the whole machine is the pooler's cap for each environment plus those lane connections (The environments share the database through a transaction pooler).

2.3. When a connection breaks

The pool replaces a broken connection in the background. The transaction that was using it ends with a retryable error (A store error says whether a retry can succeed), and its caller retries on a fresh connection.

2.4. One connection path

The generated repositories and the hand-written statements reach the store through the same pool and the same unit of work (A repository works inside an open transaction and never holds credentials). There is no second way to reach the database.

3. See also

Emacs 29.3 (Org mode 9.6.15)