Redis connection pooling from PHP: persistent connections vs pools
Running into connection exhaustion on Redis when traffic spikes. We connect with Predis, new connection per request.
Options I see:
- pconnect() with phpredis
- Connection pool in the application layer (only works in long-running processes)
- Twemproxy or Envoy in front of Redis
What are people actually doing in production?
pconnect() with phpredis is the standard answer for FPM setups. The connection is kept alive in the FPM worker process and reused across requests. Works well but you need to be aware of connection count: num_workers x num_servers.
Twemproxy is unmaintained at this point. Envoy or KeyDB proxy are better choices if you actually need connection multiplexing. But in most cases phpredis pconnect is enough and simpler.
For Swoole-based setups the framework handles connection pools natively. Hyperf has a redis pool built in. With FPM you do not get true pooling, just persistent connections at the worker level.
Redis max connections default is 10000. You hit it before you hit any PHP limit in most cases. Check redis-cli info clients for connected_clients during peak. If it is near maxclients, pool or proxy is needed.
Also: AUTH and SELECT calls add latency if they happen on every pconnect. phpredis has a bug where pconnect does not track which DB was selected. Keep all code on DB 0 or always call SELECT explicitly after pconnect.
We switched to phpredis pconnect and reduced Redis CPU by 15% just from not doing the handshake on every request. The connection negotiation overhead is not zero.