Knex: Timeout acquiring a connection. The pool is probably full
The error is Knex: Timeout acquiring a connection. The pool is probably full. Under load the app stops responding and the logs fill with it. The counterintuitive part is that this is almost never CPU load. It is connection starvation, and the single best tell separates it from a genuinely overloaded app in one glance: check CPU. An app that is dead with CPU near zero is out of database connections, not out of compute. This is the structural sibling of a slow API, and worth reading alongside Why is your Strapi API slow?.
00· Before anything
First: check CPU
This is the best single tell in the whole category. When the pool timeout appears, look at CPU on the application instances. An app that is unresponsive with CPU near zero is starved of database connections, not of compute; a genuinely overloaded app runs hot. That one glance tells you whether you are on this page.
From there it is arithmetic. Multiply your replica count by pool.max and compare it against the database's max_connections. If the total exceeds the ceiling, you have found it. If it is comfortably under, go looking for a fan-out query.
-- the database's ceiling
SHOW max_connections;
-- your usage: replicas × pool.max must stay under itDo this before you raise pool.max. Increasing the pool on every replica is the most common way to make this worse: more replicas, each opening a bigger pool, is exactly what exhausts the database's ceiling.
Likely causes · The order I check them
Cause 01 of 05
Horizontal scaling: replicas × pool.max exceeds the database ceiling
Fine on one instance, fails once you scale out, and bites hardest when everything restarts at once and every replica opens its pool together.
Replica count times pool.max against the database's max_connections. Over the ceiling is your answer.
Each instance opens its own connection pool. Nothing coordinates them, so total connection demand is replicas times pool.max, which quietly passes the database's limit.
Size pool.max in config/database so that replicas times the pool stays comfortably under max_connections, leaving headroom for migrations and admin connections. Scale the pool down as you scale replicas up, not the other way around.
Cause 02 of 05
A fan-out query in a hot endpoint
Fine at ten requests a minute, fatal at ten a second. One endpoint is implicated.
Look for Promise.all over the document service in your hot paths. That is the recurring shape: one request grabbing many connections at once.
Serialise the fan-out, or batch it into a single query. A request that opens ten connections in parallel needs only a handful of concurrent requests to drain the pool.
This is the connection-pool version of the N+1 problem covered in the slow-API page. If the arithmetic in the confirm step is under the ceiling, this is almost always where the connections are going.
Cause 03 of 05
Something bulk is running against the same database
Timeouts that correlate with a clock rather than with traffic: the same minute each night, or during a deploy.
Line the timeout up against what else touches the database on a schedule: a transfer, a backup, an import.
Move bulk work off the primary, or off peak, or give it its own connection budget so it cannot starve request handling.
Cause 04 of 05
Local development pointed at the production database
The production pool exhausts for no traffic reason, sometimes before a local Strapi even finishes booting.
A developer's machine pointed at the production database opens a full pool of its own, on top of every replica.
Point development at a development database. Never let a laptop hold production connections.
Cause 05 of 05
Overlapping cron tasks holding connections open
Timeouts that build up over time rather than spiking, with cron jobs in the mix.
Cron tasks that run longer than their interval overlap, and each overlapping run holds connections open.
Guard cron tasks against overlap, and make sure each releases its connections when it finishes.
06
On Strapi Cloud the connection pool is not customer-tunable and pool usage cannot be monitored. The diagnostic path there is narrower: correlate the exact minute of the timeout against what else ran, since you cannot resize the pool or watch it fill.
07
If it's none of these
If CPU is high rather than near zero, you are not connection-starved, you are genuinely loaded, and the slow-API diagnosis applies instead: unbounded population, missing indexes, unpaginated collections. Start with Why is your Strapi API slow?. And confirm the database instance itself is not undersized: a small database with a low max_connections ceiling hits this far sooner than the app's pool settings suggest.
Common questions
Usually no. If you are horizontally scaled, a bigger pool on every replica multiplies the demand on the database and makes the timeout arrive sooner. Size the pool against replicas times max versus the database ceiling, and fix the fan-out if the arithmetic is already under the ceiling.
Connection starvation, not load. A compute-bound app runs hot; an app waiting on a connection it cannot acquire sits idle. That single observation puts you on this page rather than the slow-API one.
No. The pool is not customer-tunable there and pool usage is not exposed, so the diagnosis is correlation: match the timeout's timing against transfers, backups, imports and deploys.
Diagnosed everything and still stuck?
S/01 — Performance & Architecture Rescue.
A fixed-scope week that finds the cause and fixes what's causing it.