MySQL Connection Pooling
Also Known As
PDO persistent connection
PHP MySQL connection pool
ProxySQL PHP
TL;DR
Reusing database connections across requests instead of opening and closing a new connection on every request.
Explanation
Opening a MySQL connection involves TCP handshake, authentication, and session setup — typically 5–20ms. In high-traffic PHP-FPM applications, creating a new connection per request wastes significant time. PDO does not have a built-in connection pool, but PDO::ATTR_PERSISTENT enables persistent connections reused across requests within the same PHP-FPM worker process. External poolers like ProxySQL or PgBouncer are preferred for production — they provide proper connection limits, health checks, and load balancing.
Common Misconception
✗ PDO::ATTR_PERSISTENT is safe to use everywhere. Persistent connections can leak transaction state between requests — always ensure no open transaction exists before returning a persistent connection to the pool.
Why It Matters
Under load, hundreds of simultaneous short-lived connections overwhelm MySQL's max_connections limit, causing 'Too many connections' errors. Pooling keeps the connection count stable regardless of request volume.
Common Mistakes
- Using persistent connections with transactions — a crashed request leaves an open transaction on a reused connection.
- Setting max_connections too low in MySQL without a connection pooler — causing connection queue timeouts.
- Opening multiple PDO instances in the same script — use a singleton or DI container to share one connection.
Avoid When
- Avoid PDO::ATTR_PERSISTENT when using transactions — a crashed request can leave an open transaction on a reused connection.
- Do not use persistent connections with different database users in the same pool — connections are reused regardless of credentials.
When To Use
- Use PDO::ATTR_PERSISTENT for simple single-server apps where max_connections is a concern.
- Use ProxySQL or PgBouncer for multi-server production environments needing health checks and load balancing.
Code Examples
✗ Vulnerable
// New connection on every request — 10ms × 1000 req/s = 10s wasted per second
function getUser(int $id): array {
$pdo = new PDO($dsn, $user, $pass); // new connection every call
return $pdo->query("SELECT * FROM users WHERE id = $id")->fetch();
}
✓ Fixed
// ProxySQL handles pooling externally — PHP connects to ProxySQL port
$pdo = new PDO('mysql:host=127.0.0.1;port=6033;dbname=app', $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
// OR: PDO persistent for single-server low-traffic apps
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
31 Mar 2026
Views
17
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 6
Unknown AI 2
Google 1
Meta AI 1
Ahrefs 1
Also referenced
How they use it
crawler 11
Related categories
⚡
DEV INTEL
Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
Use PDO::ATTR_PERSISTENT => true for simple cases, or deploy ProxySQL in front of MySQL for production connection management
📦 Applies To
PHP 5.1+
web
cli
🔗 Prerequisites
🔍 Detection Hints
new PDO() inside a function or loop — new connection on every call
Auto-detectable:
✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: File