PHPackages                             senza1dio/database-pool - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. senza1dio/database-pool

ActiveLibrary[Database &amp; ORM](/categories/database)

senza1dio/database-pool
=======================

Enterprise-grade database connection pooling for PHP with circuit breaker, auto-scaling, and PostgreSQL/MySQL/SQLite support. Battle-tested at 100k+ concurrent users.

v1.0.0(3mo ago)523MITPHPPHP ^8.0CI passing

Since Jan 23Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/senza1dio/database-pool)[ Packagist](https://packagist.org/packages/senza1dio/database-pool)[ Docs](https://github.com/senza1dio/database-pool)[ RSS](/packages/senza1dio-database-pool/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (5)Versions (2)Used By (0)

🚀 Database Connection Manager for Long-Running PHP
==================================================

[](#-database-connection-manager-for-long-running-php)

[![PHP Version](https://camo.githubusercontent.com/911a83e2aa6fe73660ab613629a95c76622bf03049a7344e80c5ea72d4ef9c7d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e302d626c7565)](https://php.net)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)[![PSR-3](https://camo.githubusercontent.com/791113d6ea3a428d507913c4a2a0d73b6c5b305ff9192767e4b1cc8f2a01b24a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5053522d2d332d6c6f676765722d6f72616e6765)](https://www.php-fig.org/psr/psr-3/)

**Advanced connection management for Swoole, RoadRunner, and ReactPHP.**

Not a magic performance multiplier for classic PHP-FPM. This is a **connection manager** with circuit breaker, auto-release, and query optimization designed for **persistent runtime environments**.

---

🔴 CRITICAL: Understand Pool Scope
---------------------------------

[](#-critical-understand-pool-scope)

**⚠️ ONE POOL PER PROCESS - NOT GLOBAL COORDINATION**

This library creates **process-local pools**, not a global shared pool:

- **Swoole/RoadRunner:** One pool per worker → TRUE pooling (workers are persistent)
- **PHP-FPM:** One pool per worker → NOT TRUE pooling (worker-isolated, pool dies after request)
- **CLI scripts:** One pool per execution → Pooling only useful if script runs &gt;1 second

**This is NOT a global connection manager** like PgBouncer or ProxySQL. If you need global pooling, use a dedicated connection pooler at the database layer.

---

⚠️ READ THIS FIRST: When to Use This Package
--------------------------------------------

[](#️-read-this-first-when-to-use-this-package)

### ✅ PRIMARY USE CASES (Where It Actually Works)

[](#-primary-use-cases-where-it-actually-works)

**1. Long-Running PHP Processes (RECOMMENDED)**

- ✅ **Swoole** - Full pooling, 10-100x performance
- ✅ **RoadRunner** - Persistent workers, connection reuse
- ✅ **ReactPHP** - Event loop optimization
- ✅ **PHP CLI Daemons** - Queue processors, long-running workers

**Why:** Process survives across requests, pool genuinely reuses connections.

**2. PHP-FPM (LIMITED BENEFITS)**

- ⚠️ **NOT true pooling** - Each worker has isolated pool
- ⚠️ Requires `enablePersistentConnections(true)` + singleton pattern
- ⚠️ Benefits limited to **per-worker connection caching**, not global pooling
- ⚠️ `persistent connections ≠ connection pool`

**Reality Check:** PHP-FPM worker isolation means:

- Worker A pool ≠ Worker B pool
- No cross-worker connection sharing
- Benefit comes from PDO persistent connections, not this library
- This library adds circuit breaker + auto-release, but NOT true pooling

**Expected Benefits:** Minimal (2-3% improvement from features, not pooling)

### ❌ WHEN NOT TO USE (CRITICAL)

[](#-when-not-to-use-critical)

**Standard PHP-FPM/Apache**

- ❌ **NO TRUE POOLING** - Worker isolation prevents connection sharing
- ❌ Pool destroyed at end of each request (`__destruct()` closes all)
- ❌ "Persistent connections" are PDO feature, not this library's benefit
- ❌ Adds complexity without meaningful gains

**Reality:** If you're using standard PHP-FPM, you're better off with:

- Native PDO persistent connections (if needed)
- Simple connection singleton
- Standard error handling

**Single-Request CLI Scripts**

- ❌ One execution = one connection, pooling unnecessary
- ✅ Circuit breaker + auto-release still useful

**When in doubt:** If your PHP process lives &lt;1 second, you don't need this.

### 🎯 Expected Results (Realistic)

[](#-expected-results-realistic)

**Swoole/RoadRunner** (persistent workers):

- **Environment:** Long-running process with true pooling
- **Results:** 10-100x reduction in connection overhead
- **Benefits:**
    - ✅ Global connection pool (shared across ALL requests)
    - ✅ Connection reuse guaranteed (pool persists across requests)
    - ✅ Circuit breaker preventing cascade failures
    - ✅ Auto-release preventing connection leaks
    - ✅ Query optimization (prepared statements, type-aware binding)

**PHP-FPM** (per-worker pooling):

- **Environment:** Static singleton + persistent connections
- **Results:** 20-80ms saved per request (when connection reused within same worker)
- **Reality:**
    - ⚠️ Per-worker optimization (NOT global pooling)
    - ⚠️ 50 workers = 50 separate pools (50×N connections total)
    - ⚠️ Connection reuse depends on traffic pattern (worker must be "warm")
    - ✅ Circuit breaker, auto-release still useful (2-3% improvement)

**Key Insight:** True pooling requires persistent runtime (Swoole/RoadRunner). PHP-FPM benefits are limited to per-worker connection caching. For global pooling with PHP-FPM, use external pooler (PgBouncer, ProxySQL).

### 📊 Benchmarks: What You ACTUALLY Save

[](#-benchmarks-what-you-actually-save)

**Per-Connection Overhead** (measured, PostgreSQL 16):

```
TCP 3-way handshake:       10-30ms  (network roundtrip)
PostgreSQL authentication:  5-20ms  (password hash verification)
Initial queries (SET):      5-30ms  (timezone, plan_cache_mode, etc.)
───────────────────────────────────
TOTAL per new PDO():       20-80ms  (depends on network latency + DB load)

```

**Connection Reuse** (with this package):

```
array_pop($idleConnections):  ~0.1ms  (O(1) operation)
Health check (if idle >30s):  ~2-5ms  (SELECT 1 query)
───────────────────────────────────
TOTAL per reused connection:  0.1-5ms

```

**Savings**: **20-80ms per request** (when connection reused successfully).

**⚠️ IMPORTANT**: This saving is:

- ✅ **Real** - measured in production
- ⚠️ **Per-worker** - NOT global across all workers
- ⚠️ **Conditional** - requires singleton pattern + persistent connections
- ❌ **Not guaranteed** - depends on traffic pattern (worker must be "warm")

**Real-World Scenario** (50 workers, 500 req/sec, 90% pool hit rate):

```
Without pooling:
  500 req/sec × 60ms = 30,000ms overhead/sec (cumulative across workers)
  = equivalent to 30 CPU-seconds wasted per second

With pooling (90% hit rate):
  50 req/sec (pool miss) × 60ms = 3,000ms
  450 req/sec (pool hit) × 0.1ms = 45ms
  = 3,045ms overhead/sec

Savings: ~27 CPU-seconds/sec (90% reduction in connection overhead)

```

**REALITY CHECK**: These are **cumulative savings across all workers**, not end-to-end request latency reduction. Your API won't go from "500ms → 50ms" unless connection overhead was your ONLY bottleneck (rare).

More realistic: "120ms → 60ms" if connection overhead was 50% of request time.

---

✨ Features
----------

[](#-features)

### Core Features

[](#core-features)

- ✅ **Connection Pooling** - Reuse connections (effective in Swoole/RoadRunner)
- ✅ **Auto-Scaling** - Dynamically scales from 5 to 400+ connections (long-running processes)
- ✅ **Circuit Breaker** - Automatic failure detection and graceful degradation
- ✅ **SSL/TLS Support** - Enterprise security for PostgreSQL and MySQL
- ✅ **Auto-Release** - Connections automatically returned to pool (prevents leaks)
- ✅ **Input Validation** - Query size limits (1MB) and param count limits (1000) for memory protection
- ✅ **Multi-Database** - PostgreSQL, MySQL, SQLite support
- ✅ **Framework Agnostic** - Works with Laravel, Symfony, or pure PHP
- ✅ **PSR-3 Logging** - Integrates with Monolog, Laravel Log, Symfony Logger

### Enterprise Features

[](#enterprise-features)

- ✅ **Type-Aware Parameter Binding** - Automatic boolean/integer/null binding for PostgreSQL/MySQL
- ✅ **Query Result Caching** - Redis/Memcached integration for SELECT query caching
- ✅ **Connection Warmup** - Pre-create connections to avoid cold start latency
- ✅ **Connection Retry Logic** - Exponential backoff (3 retries) on transient failures
- ✅ **Monitoring Hooks** - New Relic, Datadog, custom metrics integration
- ✅ **Transaction Safety** - Auto-rollback uncommitted transactions on connection release
- ✅ **Slow Query Detection** - Automatic logging of queries &gt;100ms (configurable)
- ✅ **Prepared Statement Caching** - Reuse prepared statements (PostgreSQL optimization)

---

📦 Installation
--------------

[](#-installation)

```
composer require senza1dio/database-pool
```

**Requirements:**

- PHP 8.0+
- ext-pdo

**Recommended:**

- ext-redis (for distributed locking at scale)
- ext-pgsql, ext-mysqli, or ext-sqlite3

---

🚀 Quick Start
-------------

[](#-quick-start)

### Swoole/RoadRunner (Recommended)

[](#swooleroadrunner-recommended)

```
