This note explains connection multiplexing in ProxySQL and when it actually applies. A MySQL connection normally carries its own thread, so thousands of app connections turn into thousands of backend threads and hit the max_connections limit. ProxySQL shares a small set of backend connections across many frontend ones, at an N:M ratio instead of 1:1. The note compares that with plain connection pooling, then walks the steps of a query and lists the cases that disable multiplexing, such as open transactions, table locks, GET_LOCK, temporary tables, and user variables. Delay parameters and query rules get their own sections, followed by tuning advice.
Source: roninhub.com
Overview
- Connection Multiplexing: many frontend connections share backend connections at an N:M ratio (instead of 1:1)
- Reduces pressure on the database layer
The Problem with Thread-per-Connection (MySQL)
- Each connection spawns its own thread
- RAM/CPU usage climbs sharply with a large number of connections
- Context-switching overhead
- The
max_connectionslimit (default 151)
Architecture with ProxySQL
- Without ProxySQL: 3000 app connections = 3000 DB threads (1:1)
- With ProxySQL multiplexing: 3000 app connections share 100 backend connections (N:M)
- Benefits: Fewer direct connections to the DB, more stable performance, better use of resources, support for horizontal scaling
Connection Multiplexing vs Connection Pooling
| Criterion | Connection Pooling | Connection Multiplexing |
|---|---|---|
| Concept | Connections kept in a pool | Connections flexibly reused across many clients |
| Ratio | 1:1 | N:M |
| Resources | Medium | Low |
| Implementation | Application-level | Proxy-level |
| Session Isolation | Full | Conditional |
How It Works
- The app connects to ProxySQL
- ProxySQL analyzes the query/session
- It picks a suitable backend connection
- It sends the query and receives the result
- It returns the backend connection to the pool
- A single frontend connection can run multiple queries over different backend connections (unless a transaction is open)
Disabling Multiplexing
- When a transaction is detected, ProxySQL disables multiplexing and "pins" the backend connection until the transaction ends (to guarantee ACID)
- Other cases that disable multiplexing: user-defined variables, temporary tables, table locks, GET_LOCK, or global configuration
Cases Where Multiplexing Is Disabled
- Active Transaction: While a transaction is active
- Table Locks: LOCK TABLE/FLUSH TABLES WITH READ LOCK
- GET_LOCK: When GET_LOCK() is used
- Temporary Tables: When a temporary table is created
- Session/User Variables: When @ variables are used
- Disable by config: mysql-multiplexing = false
Delay Parameters
- Avoid errors when using auto-increment (for example: INSERT followed by SELECT LAST_INSERT_ID())
mysql-auto_increment_delay_multiplex: number of queries to delaymysql-connection_delay_multiplex_ms: delay time (ms)
Query Rules Control
- Control multiplexing per query type using query rules
multiplexing: 0= disable,1= enable,2= do not disable for queries containing @
Conclusion
- Connection Multiplexing helps optimize database performance, especially for high-concurrency systems
- You need to understand when multiplexing gets disabled, tune parameters correctly, and monitor regularly
- When configured correctly, multiplexing can cut backend connections by 80-90%
References:
See also: PostgreSQL HA Patroni Best Practices · Vitess Distributed Database Best Practices