Overview
Background queries allow clients to submit queries that execute independently of the client session by settingrun_query_in_background=1. Once submitted, the ClickHouse server responds immediately to the client while the query still run to completion (either success or failure) on the server side
By decoupling query execution from the client network connection, background tasks are fully resilient to client-side disconnects or transient network failures.
Background queries are mainly intended for long-running operations such as INSERT ... SELECT,
CREATE TABLE ... AS SELECT, CREATE MATERIALIZED VIEW ... POPULATE, or OPTIMIZE TABLE ... FINAL
that must not stop if the client connection drops.
Not every query can be detached from its connection. See Unsupported query forms
for the requests that are rejected instead.
A background query does not survive a server restart. Server shutdown behavior is controlled by
shutdown_wait_unfinished_queries and shutdown_wait_unfinished.
Unsupported query forms
A background query outlives the connection that submitted it, so the server must already have everything it needs to run the query at the moment it accepts it. Requests that do not satisfy this are rejected synchronously, on the submitting connection, and the query never starts.Data that streams over the connection
AnINSERT is rejected when the server would still need to read data from the submitting connection after dispatching
the query.
This can affect both INSERT ... FORMAT ... and queries that read through input. Such a request is rejected
with A query whose data streams over the connection cannot be run in the background:
clickhouse-client sends the data of an INSERT ... FORMAT ... in separate packets, so that form can never run in the background over the native protocol.
Over HTTP, either form can be accepted when the complete query and its data fit in the initial parsing buffer, which is bounded by max_query_size.
This includes an HTTP query that reads an inline payload through input. A larger body keeps streaming past the buffered query text and is rejected.
Do not rely on that size boundary: use INSERT ... SELECT, or a table function such as url or s3, for data that must be loaded in the background.
Other rejected requests
The setting is never propagated to the secondary queries of a distributed query: a background distributed
INSERT
runs its per-shard queries in the foreground, within the background initial query.
Submit a background query
Native TCP protocol
Withclickhouse-client, pass run_query_in_background as a command-line setting:
SETTINGS clause:
clickhouse-client parses most inline query settings and sends them in this settings section.
Native-protocol drivers can instead pass run_query_in_background in their per-query settings map, keeping the SQL text unchanged.
The native protocol does not return a server-generated query_id. Native clients should generate a unique ID and send it with the query.
clickhouse-client --echo-query-id does this and prints the ID before submitting the query:
HTTP protocol
For HTTP requests, passrun_query_in_background as a URL parameter:
X-ClickHouse-Query-Id header:
query_id as a URL parameter instead.
The client then knows the ID before it makes the request, and can monitor or KILL the query on the accepting node even if it never sees the response:
SETTINGS clause:
BAD_ARGUMENTS exception. The HTTP handler must decide whether to create a detached query context before the request body is parsed.
Pass the setting in the URL, or configure it at the user or profile level.
Monitor execution
Use thequery_id to check whether a query is currently running:
system.query_log for its final status:
system.query_log rather than returned over the original connection.
:::note Clustered and load-balanced deployments
system.processes, system.query_log, and KILL QUERY are node-local: each one only sees the queries of the server that answers it.
A background query belongs to the server that accepted it, which is not necessarily the one your next request reaches through a load balancer. Read the whole cluster instead:
system.query_log, and cancellation needs the cluster-wide form:
Query log flush delay
Entries are buffered before they appear insystem.query_log.
For self-managed ClickHouse, the example server configuration sets query_log.flush_interval_milliseconds to 7500.
ClickHouse Cloud entries can take up to 30 seconds to appear. Account for this delay when monitoring short-running background queries.
On a self-managed server, users with sufficient privileges can force the query log to flush. Name the log explicitly so that the other system logs are left alone:
system.query_log visible locally, so still read the log through clusterAllReplicas as described in Monitor execution.