Skip to main content
Records inserted into a QueryRunner table represent queries that the engine executes. The engine can be used for asynchronous query execution, batch execution of generated queries, directing queries to remote clusters, benchmarks, fuzzing, and testing with shadow traffic.

Creating a table

The table must be created with a subset of the allowed columns: query, database, settings. The column query is mandatory, and the other columns are optional.

Engine settings

Details

The table allows only INSERT queries. The queries are executed in the “fire and forget” mode: in case of an exception, there are no retries, and the results of SELECT queries are discarded (the only way to keep results is INSERT SELECT). The success of each query can be checked in the system.query_log table, where queries initiated by this engine are marked with is_internal = 1 on the initiating server. The queued queries are kept in memory and do not survive a server restart. On server shutdown (or DROP/DETACH of the table), the queries that have not started yet are discarded. Of the queries already being executed, those dispatched to a cluster are cancelled, while those running locally are awaited until they finish. When a query to run is itself an INSERT, its data must be inline — INSERT ... VALUES (...), INSERT ... SELECT ..., or INSERT ... FORMAT ... with the data in the query text. An INSERT that expects its data from a separate stream is not supported.

Local mode and SQL SECURITY

Without the cluster setting, the queries are executed on the local server. The user under whom they run is determined by the SQL SECURITY clause:
  • INVOKER (default): the queries run on behalf of the user who performed the INSERT.
  • DEFINER: the queries run on behalf of the specified DEFINER user. Because the inserted queries are arbitrary, granting INSERT on such a table delegates all privileges of the definer.
  • NONE: the queries run with full access, without a user. Requires the ALLOW_SQL_SECURITY_NONE grant at table creation.

Cluster mode

When the cluster setting is specified, the queries are sent to the specified cluster. The target shard is selected by shard: a fixed 1-based index ('1' by default), 'random' to pick a random shard for each query, or 'all' to run each query on every shard of the cluster. A replica within the shard is chosen according to the server’s load_balancing setting. The database column sets the default database of the connection to the remote server. Because the default database is set once per connection, each distinct database value uses its own connection pool, which is created on first use and reused for the lifetime of the table. DEFINER and SQL SECURITY have an effect only in the local mode, and combining them with the cluster setting is an error. On the remote servers, the queries are authenticated with the credentials from the cluster configuration and run as ordinary initial queries: they are recorded in system.query_log with is_initial_query = 1 and their own query_id (not linked to the INSERT that produced them). On the initiating server, the dispatched queries are recorded in system.query_log with is_internal = 1. Because the engine discards query results, it always runs the dispatched queries with discard_query_data = 1, so the result data of SELECT queries is not transferred over the network (this overrides any discard_query_data value set in the settings column).

Waiting for queries to finish

In asynchronous mode, the following query can be used to block until every query submitted to the table so far has finished:

Example

Replaying recent SELECT queries from the query log:
Last modified on July 11, 2026