The stats database

This database contains metrics gathered by ProxySQL with respect to its internal functioning. Here you will find information on how often certain counters get triggered and the execution times of the queries that pass through ProxySQL.

  • A user that connects to Admin with admin-stats_credentials credentials can only access this schema.
  • Generally, the tables from this database are populated on the fly when the SQL query against them is execute, by examining in-memory data structures.

Here are the tables from the “stats” database:


Table stats.global_variables exists only to facilitate connections from libraries that issues SELECT @@max_allowed_packet or similar. Its content can be ignored:


This table is meant to display memory usage of various structures inside ProxySQL.

At today, only few structures are tracked (SQLite, Auth module, Query Digests), but in future a lot more internal structures will be tracked, exporting more metrics.

The most important values to monitor in this table are the ones related to jemalloc (the memory allocator built inside ProxySQL). A detailed description of the various values is available at the jemalloc website.

In short:

  • jemalloc_allocated : bytes allocated by the application
  • jemalloc_active: bytes in pages allocated by the application
  • jemalloc_mapped: bytes in extents mapped by the allocator
  • jemalloc_metadata: bytes dedicated to metadata
  • jemalloc_resident: bytes in physically resident data pages mapped by the allocator

Other memory metrics:

  • Auth_memory : memory used by the authentication module to store user credentials and attributes
  • SQLite3_memory_bytes : memory used by the embedded SQLite
  • query_digest_memory : memory used to store data related to stats_mysql_query_digest


Table stats_mysql_commands_counters keeps records of all types of queries executed, and collects statistics based on their execution time, grouping them into buckets:

The fields have the following semantics:

  • command – the type of SQL command that has been executed. Examples: FLUSH, INSERT, KILL, SELECT FOR UPDATE, etc.
  • Total_Time_us – the total time spent executing commands of that type, in microseconds
  • total_cnt – the total number of commands of that type executed
  • cnt_100us, cnt_500us, …, cnt_10s, cnt_INFs – the total number of commands of the given type which executed within the specified time limit and the previous one. For example, cnt_500us is the number of commands which executed within 500 microseconds, but more than 100 microseconds (because there’s also a cnt_100us field). cnt_INFs is the number of commands whose execution exceeded 10 seconds.

Note: statistics for table stats_mysql_commands_counters are processed only if global variable mysql-commands_stats is set to true . This is the default, and used for other queries processing. It is recommended to NOT disable it.


Here is the statement used to create the stats_mysql_connection_pool table:

Each row represents a backend server within a hostgroup. The fields have the following semantics:

  • hostgroup – the hostgroup in which the backend server belongs. Note that a single backend server can belong to more than one hostgroup
  • srv_host, srv_port – the TCP endpoint on which the mysqld backend server is listening for connections
  • status – the status of the backend server. Can be ONLINE, SHUNNED, OFFLINE_SOFT, OFFLINE_HARD. See the description of the mysql_servers table above for more details about what each status means
  • ConnUsed – how many connections are currently used by ProxySQL for sending queries to the backend server
  • ConnFree – how many connections are currently free. They are kept open in order to minimize the time cost of sending a query to the backend server
  • ConnOK – how many connections were established successfully.
  • ConnERR – how many connections weren’t established successfully.
  • Queries – the number of queries routed towards this particular backend server
  • Bytes_data_sent – the amount of data sent to the backend. This does not include metadata (packets’ headers)
  • Bytes_data_recv – the amount of data received from the backend. This does not include metadata (packets’ headers, OK/ERR packets, fields’ description, etc)
  • Latency_us – the current ping time in microseconds, as reported from Monitor

This table exports statistics on backend servers. Servers are identified based on their hostgroup, address and port, and the information available is related to connections, queries and traffic.

In the above it is possible to note how multiplexing is efficient (few used connections).


Querying table stats_mysql_connection_pool_reset is equivalent to querying stats_mysql_connection_pool, with the only difference that all statistics are reset to 0 at the end of the SELECT statement.






One of the most important tables in “stats” schema is “stats_mysql_global” which exports counters related to various ProxySQL’s internals.

Here is the statement used to create the stats_mysql_global table:

Each row represents a global statistic at the proxy level related to MySQL including:

  • Key Memory Usage
  • Prepared Statements
  • Query Cache
  • Processing Time
  • Global Connections
  • Threads / Workers
  • Connection Pooling
  • Transactions
  • SQL Statements

The same output is available using the SHOW MYSQL STATUS command.


Variable description:

  • ProxySQL_Uptime – the total uptime of ProxySQL in seconds
  • Active_Transactions – provides a count of how many client connections are currently processing a transaction
  • Client_Connections_aborted – client failed connections (or closed improperly)
  • Client_Connections_connected – client connections that are currently connected
  • Client_Connections_created – total number of client connections created
  • Server_Connections_aborted – backend failed connections (or closed improperly)
  • Server_Connections_connected – backend connections that are currently connected
  • Server_Connections_created – total number of backend connections created
  • Client_Connections_non_idle – number of client connections that are currently handled by the main worker threads. If ProxySQL isn’t running with “–idle-threads”, Client_Connections_non_idle is always equal to “Client_Connections_connected”
  • Backend_query_time_nsec – time spent making network calls to communicate with the backends
  • mysql_backend_buffers_bytes – buffers related to backend connections if “fast_forward” is used (0 means fast_forward is not used)
  • mysql_frontend_buffers_bytes – buffers related to frontend connections (read/write buffers and other queues)
  • mysql_session_internal_bytes – other memory used by ProxySQL to handle MySQL Sessions
  • Com_frontend_stmt_prepare / Com_frontend_stmt_execute / Com_frontend_stmt_close – represent the number of “PREPARE / EXECUTE / CLOSE” executed by clients. It is common for clients to prepare a statement, execute the statement once, and then close it so these 3 metrics’ values are often almost identical.
  • Com_backend_stmt_prepare / Com_backend_stmt_execute / Com_backend_stmt_close – represent the number of “PREPARE” / “EXECUTE” / “CLOSE” executed by ProxySQL against the backends. Com_backend_stmt_execute should roughly match Com_frontend_stmt_execute. ProxySQL tracks and re-uses prepared statements across connections where possible so Com_backend_stmt_prepare is generally much smaller than Com_frontend_stmt_prepare. Com_backend_stmt_close is always 0 in the current implementation as ProxySQL never closes prepared statements as it is inefficient (a network round trip would be wasted). Instead, when “mysql-max_stmts_per_connection” is reached in a backend connection and the connection returns to the connection pool and is reset (implicitly closing all prepared statements)
  • MySQL_Thread_Workers – number of MySQL Thread workers i.e. “mysql-threads”
  • MySQL_Monitor_Workers – The number of monitor threads. By default it is twice the number of worker threads, initially capped to 16 yet more threads will be created checks are being queued. Monitor threads perform blocking network operations and do not consume much CPU
  • ConnPool_get_conn_success – number of requests where a connection was already available in the connection pool
  • ConnPool_get_conn_failure – number of requests where a connection was not available in the connection pool and either a new connection had to be created or no backend was available
  • ConnPool_get_conn_immediate – number of connections that a MySQL Thread obtained from its own local connection pool cache. This value tends to be large only when there is high concurrency.
  • Questions – the total number of client requests / statements executed
  • Slow_queries – the total number of queries with an execution time greater than “mysql-long_query_time” milliseconds
  • MyHGM_myconnpoll_get – the number of requests made to the connection pool
  • MyHGM_myconnpoll_get_ok – the number of successful requests to the connection pool (i.e. where a connection was available)
  • MyHGM_myconnpoll_push – the number of connections returned to the connection pool
  • MyHGM_myconnpoll_destroy – the number of connections considered unhealthy and therefore closed
  • MyHGM_myconnpoll_reset – the number of connections that have been reset / re-initialized using “COM_CHANGE_USER”
  • SQLite3_memory_bytes – memory used by SQLite
  • ConnPool_memory_bytes – memory used by the connection pool to store connections metadata
  • Stmt_Client_Active_Total – the total number of prepared statements that are in use by clients
  • Stmt_Client_Active_Unique – this variable tracks the number of unique prepared statements currently in use by clients
  • Stmt_Server_Active_Total – the total number of prepared statements currently available across all backend connections
  • Stmt_Server_Active_Unique – the number of unique prepared statements currently available across all backend connections
  • Stmt_Cached – this is the number of global prepared statements for which ProxySQL has metadata
  • Stmt_Max_Stmt_id – when a new global prepared statement is created, a new “stmt_id” is used. Stmt_Max_Stmt_id represents the maximum “stmt_id” ever used. When metadata for a prepared statement is dropped, the “stmt_id” may be reused
  • Query_Cache_Memory_bytes – memory currently used by the query cache (more details later)
  • Query_Cache_Entries – number of entries currently stored in the query cache
  • Query_Cache_Memory_bytes – memory usage of the query cache
  • Query_Cache_Purged – number of entries purged by the Query Cache due to TTL expiration
  • Query_Cache_bytes_IN – number of bytes sent into the Query Cache
  • Query_Cache_bytes_OUT – number of bytes read from the Query Cache
  • Query_Cache_count_GET – number of read requests
  • Query_Cache_count_GET_OK – number of successful read requests
  • Query_Cache_count_SET – number of write requests
  • Query_Processor_time_nsec – the time spent inside the Query Processor to determine what action needs to be taken with the query (internal module)


The “stats_mysql_gtid_executed” table provides statistics related to GTID tracking for consistent reads. The table shows the GTID sets and number of events executed on each backend node.

For example, here we can see a difference in GTID sets between the master (mysql1) and slaves (mysql2, mysql3):


Because of multiplexing, it is possible that a client prepares a PS in a backend connection but that connection is not free when that same client wants to execute the PS.
Furthermore, it is possible that multiple clients prepare the same PS.
ProxySQL addresses these 2 issues in the following ways:

  • for every unique PS , a global stmt_id is generated and its metadata are stored internally in a global cache
  • each client preparing a PS gets a stmt_id that is local to that client, but mapped to the global stmt_id
  • on every backend connection where a PS is prepared, the stmt_id returned by the backend is mapped to the global stmt_id

In other words, a global stmt_id can have multiple clients stmt_id associated to it, and multiple backends stmt_id associated to it.
Table stats_mysql_prepared_statements_info shows some of the metadata associated to the PS (global_stmt_id, schemaname, username, digest and query), as well as the number of reference counters for client connections (ref_count_client) and backend connections (ref_count_server).


Here is the statement used to create the stats_mysql_processlist table:

The fields have the following semantics:

  • ThreadID – the internal ID of the thread within ProxySQL. This is a 0-based numbering of the threads
  • SessionID – the internal global numbering of the ProxySQL sessions, or clients’ connections (frontend). It’s useful to be able to uniquely identify such a session, for example in order to be able to kill it, or monitor a specific session only.
  • user – the user with which the MySQL client connected to ProxySQL in order to execute this query
  • db – the schema currently selected
  • cli_host, cli_port – the (host, port) pair of the TCP connection between the MySQL client and ProxySQL
  • hostgroup – the current hostgroup. If a query is being processed, this is the hostgroup towards which the query was or will be routed, or the default hostgroup. The routing is done by default in terms of the default destination hostgroup for the username with which the MySQL client connected to ProxySQL (based on mysql_users table, but it can be modified on a per-query basis by using the query rules in mysql_query_rules
  • l_srv_host, l_srv_port – the local (host, port) pair of the TCP connection between ProxySQL and the backend MySQL server from the current hostgroup
  • srv_host, srv_port – the (host, port) pair on which the backend MySQL server is listening for TCP connections
  • command – the type of MySQL query being executed (the MySQL command verb)
  • time_ms – the time in millisecond for which the query has been in the specified command state so far
  • info – the actual query being executed

Please note that this is just a snapshot in time of the actual MySQL queries being run. There is no guarantee that the same queries will be running a fraction of a second later.
Here is what the results look like:

Note: ProxySQL also supports the commands SHOW PROCESSLIST and SHOW FULL PROCESSLIST to return information related to current sessions.

stats_mysql_query_digest and stats.stats_mysql_query_digest_reset

Here is the statement used to create the stats_mysql_query_digest table:

  • before 2.0
  • since 2.0.0
  • since 2.0.6

Each row represents a class of queries all having the same parameters (but with different values) routed through ProxySQL. Here’s how a typical result looks like:

The fields have the following semantics:

  • hostgroup – the hostgroup where the query was sent. A value of -1 represent a query hitting the Query Cache
  • schemaname – the schema that is currently being queried
  • username – the username with which the MySQL client connected to ProxySQL
  • client_address – the address of the client if mysql-query_digests_track_hostname=true
  • digest – a hexadecimal hash that uniquely represents a query with its parameters stripped
  • digest_text – the actual text with its parameters stripped
  • count_star – the total number of times the query has been executed (with different values for the parameters)
  • first_seen – unix timestamp, the first moment when the query was routed through the proxy
  • last_seen – unix timestamp, the last moment (so far) when the query was routed through the proxy
  • sum_time – the total time in microseconds spent executing queries of this type. This is particularly useful to figure out where the most time is spent in your application’s workload, and provides a good starting point for where to improve
  • min_time, max_time – the range of durations to expect when executing such a query. min_time is the minimal execution time seen so far, while max_time represents the maximal execution time, both in microseconds.
  • sum_rows_affected – the total number of rows affected
  • sum_rows_sent – the total number of rows sent. This doesn’t currently count the number of rows returned from the Query Cache

Note that the time in this table refers to the time elapsed between the time in which ProxySQL receives the query from the client, and the time in which ProxySQL is ready to send the query to the client. Therefore these times represent the elapsed time as close as possible as seen from the client. To be more precise, it is possible that before executing a query, ProxySQL needs to change charset or schema, find a new backend if the current one is not available anymore, run the query on a different backend if the current one fails, or wait for a connection to become free because currently all the connections are in use.

Note: statistics for table stats_mysql_query_digest are processed only if global variable mysql-query_digests is set to true . This is the default, and used for other queries processing. It is recommended to NOT disable it.

The stats_mysql_query_digest_reset table is identical in content and structure, but querying it also atomically resets the internal statistics to zero.


Table stats_mysql_query_digest_reset is identical to stats_mysql_query_digest, but reading from stats_mysql_query_digest_reset causes all statistics to be reset at the end of the SELECT.


Table stats_mysql_query_rules exports how many times query rules were matching traffic. Here is the statement used to create the stats_mysql_query_rules table:

The fields have the following semantics:

  • rule_id – the id of the rule, can be joined with the main.mysql_query_rules table on the rule_id field.
  • hits – the total number of hits for this rule. One hit is registered if the current incoming query matches the rule. Each time a new query that matches the rule is processed, the number of hits is increased.

Note that hits is reset every time query rules are loaded to runtime, either through explicit LOAD MYSQL QUERY RULES TO RUNTIME or through implicit resync via ProxySQL Cluster.


Table stats_mysql_users reports a list of users, their current number of frontend connections, and the total number of frontend connections they can create (as defined in mysql_users.max_connections).


ProxySQL instances that are part of a cluster regularly monitor each other to understand if a reconfiguration needs to be triggered.
It is possible to query the current view of the Cluster through the table stats_proxysql_servers_checksums:

The columns represent:

  • hostname : address of the proxy (remote or local)
  • port : port of the proxy (remote or local)
  • name : name of the module being synchronized
  • version: every time a configuration is loaded (locally), its version number is increased by 1
  • epoch: this is the time when the specific configuration was created (either locally, or remotely before being imported)
  • checksum: the checksum of the configuration itself. This is the information that proxies use to detect configuration changes
  • changed_at: this is the time when the specific configuration was loaded locally. Note that it is different than epoch, which represents when the configuration was created
  • updated_at: this is the last time the local ProxySQL checked the checksum of the remote ProxySQL instance. If this value is not increased, it means that the local ProxySQL cannot fetch data from the remote ProxySQL
  • diff_check: the number of checks in a row in which it was detected that the remote configuration is different than the local one. When a threshold is reached, an automatic reconfiguration is triggered


ProxySQL instances in a Cluster regularly exchange global statuses.
Some of these statuses are visible in stats_proxysql_servers_metrics:



Currently unused – this table was created to show general statistics related to all the services configured in the proxysql_servers table.