Connection Pooling

Sombra uses connection pooling to efficiently manage database connections and prevent unbounded connections to upstream databases. This approach maintains a pool of connections for each database endpoint and stores these pools in an LRU (Least Recently Used) cache.

Pooling is the biggest lever for how fast Sombra processes DSRs against a database. For recommended starting values, how to verify pooling is on, and how pooling interacts with rate limits, see Database Integration Throughput.

To enable connection pooling, you must set the environment variable ODBC_POOL_CACHE_SIZE based on the number of upstream database servers being scanned, plus some buffer to prevent cache misses.

The following environment variables allow you to configure the connection pooling behavior:

Environment VariableDescriptionDefaultRequired
ODBC_POOL_CACHE_SIZEMaximum size of LRU cache to store the connection pool per databaseNoneYes
ODBC_POOL_CACHE_TTL_MSHow long (in milliseconds) each connection pool lives in the LRU cache before it is closed and recreated on next use3600000 (1 hour)No
ODBC_QUERY_TIMEOUT_IN_SECONDSMaximum time to wait for each ODBC query to execute before returning to the application60 secondsNo
ODBC_CONNECTION_TIMEOUT_IN_SECONDSNumber of seconds to wait for a request on the connection to complete before returning to the application0No
ODBC_LOGIN_TIMEOUT_IN_SECONDSNumber of seconds to wait for a login request to complete before returning to the application10No
ODBC_CONNECTION_POOL_SIZEMaximum number of open connections the pool will create100No
ODBC_CONNECTION_INITIAL_POOL_SIZEInitial number of connections created in the pool10No
ODBC_CONNECTION_POOL_SIZE_INCREMENTNumber of additional connections to create when all of the pool's connections are in use10No
REUSE_ODBC_CONNECTIONSWhether or not to reuse an existing connection instead of creating a new onetrueNo
ODBC_CONNECTION_POOL_SIZE_SHRINKWhether or not the number of connections should shrink to initialSize as they free uptrueNo
UV_THREADPOOL_SIZENumber of Node.js (libuv) threadpool threads per Sombra process. Each in-flight ODBC call holds one thread until the database answers.16 (Sombra image)No
ODBC_MAX_CONCURRENT_OPERATIONSMaximum native ODBC calls (connect, prepare, execute, close) running at once per Sombra process. Calls above the cap wait for a free slot.UV_THREADPOOL_SIZE minus a quarter of the pool, keeping at least 2 threads free (12 of 16)No

Sombra keeps part of the libuv threadpool free so slow or hung database calls cannot block DNS lookups and other outbound HTTP calls. Each Sombra process runs at most ODBC_MAX_CONCURRENT_OPERATIONS native ODBC calls at once; calls above the cap wait for a free slot. By default, the cap is UV_THREADPOOL_SIZE minus one quarter of the pool, with at least 2 threads reserved (12 of 16). To increase database concurrency, raise UV_THREADPOOL_SIZE; for example, 128 threads gives a default cap of 96. Set ODBC_MAX_CONCURRENT_OPERATIONS directly only when you need a specific cap, and keep it below UV_THREADPOOL_SIZE. Sombra logs Limiting native ODBC calls to N of M libuv threadpool threads at startup.

For high-volume DSR processing, the configuration below is a good starting point. Redeploy Sombra after changing these values, check that your database's connection limits leave room for the larger pools, and confirm pooling is on with the checks in Database Integration Throughput.

UV_THREADPOOL_SIZE=128
ODBC_POOL_CACHE_SIZE=20
ODBC_CONNECTION_INITIAL_POOL_SIZE=20
ODBC_CONNECTION_POOL_SIZE=100
ODBC_CONNECTION_POOL_SIZE_INCREMENT=20
ODBC_CONNECTION_POOL_SIZE_SHRINK=false
ODBC_POOL_CACHE_TTL_MS=86400000