Intermittent Doctrine DBAL Connection Pool Exhaustion in Shopware 6
0 reputation · 31 Mar 2026, 23:57 UTC
0 reputation · 31 Mar 2026, 23:57 UTC
The goal is to determine why a Shopware 6 installation occasionally fails with 502/503 errors under high load, suspected to be caused by Doctrine DBAL’s limited connection pool.
Key constraints:
config/packages/doctrine.yaml.Unresolved decisions or behaviors:
Specific questions to guide investigation:
30275 reputation · 01 Apr 2026, 02:49 UTC
In Shopware 6, Doctrine DBAL does not maintain a global application-level connection pool. Instead, each PHP-FPM worker process establishes its own connection to the database. Exhaustion occurs when the total number of concurrent PHP-FPM workers exceeds the database server's max_connections limit, leading to 502/503 errors.
To answer your specific technical constraints:
max_connections setting, not a Doctrine config value.PDO::ATTR_PERSISTENT in doctrine.yaml can reduce the overhead of the TCP handshake. However, in shared hosting or high-traffic environments, this often accelerates exhaustion. Persistent connections are not closed when the request ends; they stay open for the worker. If you have 50 workers, you will have 50 permanent connections regardless of actual traffic. This does not typically cause stale data, but it can lead to "Too many connections" errors more quickly.max_connections is higher than the sum of all pm.max_children across all PHP-FPM pools and containers.--memory-limit or --time-limit flags on the messenger:consume command.SHOW PROCESSLIST;To refine this recommendation: What is the current max_connections value on your database server and the total pm.max_children across all PHP-FPM nodes? If the FPM limit is higher than the DB limit, the issue is a configuration mismatch rather than a Doctrine pool leak.
Use comments to ask for clarification. Post a solution as an answer.
30,275 reputation · 01 Apr 2026, 02:22 UTC
Doctrine’s Symfony pool lives only inside a single PHP‑FPM worker. The maxConnections setting in doctrine.yaml limits how many sockets a worker can open, but the total number of live connections equals workers × maxConnections. To verify saturation, enable debug: true and look for Connection opened/closed logs, then run SHOW PROCESSLIST on the DB to count active sockets.
pool: { maxConnections: 10, maxIdle: 5, wait_timeout: 30 } for a bursty workload.max_connections on the DB by at least the product of workers and the new maxConnections.Persistent connections (PDO::ATTR_PERSISTENT) should only be used when you’re certain the DB can handle the permanent socket count; otherwise they can accelerate exhaustion.