Three Configuration Layers
ProxySQL uses a unique three-layer configuration system. Understanding this is essential to managing ProxySQL correctly. Each layer has a specific role:
| Layer | Location | Persistent | When Active |
|---|---|---|---|
| RUNTIME | In-memory (ProxySQL threads) | No | Always — current live config |
| MEMORY (main) | In-memory SQLite | No | Staging — only after LOAD |
| DISK | /var/lib/proxysql/proxysql.db | Yes | On startup — loaded into MEMORY |
How Config Flows
┌────────────────────────────────────────────────────────────────┐ │ DISK (proxysql.db) ←──── SAVE ... TO DISK │ │ │ │ │ │ (on startup) │ │ ▼ │ │ MEMORY (main db) ←──── Admin edits go here first │ │ │ │ │ │ LOAD ... TO RUNTIME │ │ ▼ │ │ RUNTIME ←──── What ProxySQL actually uses │ └────────────────────────────────────────────────────────────────┘
Making Changes — Correct Workflow
The correct workflow for any configuration change is always:
- Connect to Admin interface (port 6032)
- Make changes to MEMORY (INSERT/UPDATE/DELETE on main tables)
- Run LOAD ... TO RUNTIME (activates changes immediately)
- Run SAVE ... TO DISK (persists changes across restarts)
SQL — Correct Change Workflow
-- Example: Add a MySQL server and make it live + persistent
-- Step 1: Edit MEMORY
INSERT INTO mysql_servers (hostgroup_id, hostname, port)
VALUES (10, '192.168.1.100', 3306);
-- Step 2: Activate in RUNTIME
LOAD MYSQL SERVERS TO RUNTIME;
-- Step 3: Persist to DISK
SAVE MYSQL SERVERS TO DISK;
RUNTIME Tables
You can always inspect what is currently active in RUNTIME using the runtime_ prefixed tables:
SQL — Query RUNTIME Tables
-- See what servers are ACTUALLY running right now
SELECT * FROM runtime_mysql_servers;
-- See active query rules
SELECT * FROM runtime_mysql_query_rules;
-- See active users
SELECT * FROM runtime_mysql_users;
-- See active global variables
SELECT * FROM runtime_global_variables;
-- See active checksums (useful for ProxySQL cluster)
SELECT * FROM runtime_checksums_values;
💡 Note: If RUNTIME and MEMORY differ, it means you made changes but forgot to run LOAD ... TO RUNTIME. Always check runtime_ tables to verify what is actually live.
Common Mistakes
| Mistake | Consequence | Fix |
|---|---|---|
| Changed main table but forgot LOAD | Change not active — ProxySQL still uses old config | LOAD ... TO RUNTIME |
| Ran LOAD but forgot SAVE | Change lost after ProxySQL restart | SAVE ... TO DISK |
| Edited proxysql.cnf directly | Changes ignored — ProxySQL reads proxysql.db on start | Use Admin interface instead |
| Restarted without SAVE | All unsaved changes rolled back to last DISK state | Always SAVE after changes |
Reverting Changes
SQL — Revert Changes
-- Revert MEMORY to current RUNTIME state (undo unsaved edits)
LOAD MYSQL SERVERS FROM RUNTIME;
-- Revert MEMORY to last saved DISK state
LOAD MYSQL SERVERS FROM DISK;
-- Revert RUNTIME to DISK state (emergency rollback)
LOAD MYSQL SERVERS FROM DISK;
LOAD MYSQL SERVERS TO RUNTIME;
Config File — proxysql.cnf
The config file is only read on the very first start when no proxysql.db exists. After that, ProxySQL always reads from the SQLite database. The config file is useful for initial bootstrap only.
BASH — Reset to Config File
# Force ProxySQL to re-read the config file (wipes existing DB)
systemctl stop proxysql
rm /var/lib/proxysql/proxysql.db
systemctl start proxysql
⚠ Warning: This wipes your entire ProxySQL configuration. Only do this in development or when intentionally resetting.