Query admission and limits
Bound executing work, wait queues, deadlines, output, operator memory, and cardinality.
Query admission protects the single engine process from concurrency and intermediate-result overload. Limits are process-wide startup controls.
Current defaults
| Control | Flag | Default |
|---|---|---|
| Executing queries | --max-concurrent-queries | Hardware concurrency, minimum 4 |
| Waiting queries | --max-waiting-queries | 128 |
| Queue wait | --queue-timeout-ms | 30,000 ms |
| Execution deadline | --query-timeout-ms | 30,000 ms |
| One-shot result rows | --query-max-result-rows | 1,000,000 |
| Rendered output | --query-max-output-bytes | 256 MiB |
| Operator scratch | --query-max-operator-memory-bytes | 512 MiB |
| Operator cardinality | --query-max-operator-cardinality | 2,000,000 |
| Cancel/deadline checkpoint | --query-checkpoint-interval | 1,024 work units |
Numeric ceilings accept 0 as disabled where stated by --help.
--max-concurrent-queries=0 disables the admission gate and
--query-timeout-ms=0 disables the deadline; reserve those settings for a
controlled bulk workload with an independent envelope.
Admission behavior
When all execution slots are occupied:
- a request joins the bounded waiting queue if space exists;
- it competes for a released slot when work completes; FIFO order is not guaranteed;
- it fails with a queue timeout if no slot arrives before the deadline; or
- it fails immediately as server busy when the queue is full or disabled.
Protocol ping is deliberately outside query admission so health remains observable under query saturation.
queue_us in system.queries and system.query_log separates admission
wait from execution work.
Execution ceilings
The monotonic query deadline is checked at bounded execution checkpoints.
CANCEL QUERY uses the same cooperative cancellation path.
Output row and byte ceilings prevent a valid query from materializing or rendering an unbounded response. Operator memory/cardinality ceilings protect hash aggregation, join, sort, window, and dedup state.
These limits are complementary: a low-row result can still have a large intermediate join or sort, and a million narrow rows can still exceed the byte ceiling.
Diagnose saturation
SELECT query_id, statement, state, elapsed_us, queue_us,
peak_memory_bytes, rows_scanned, rows_returned,
op_join_us, op_aggregate_us, op_sort_us
FROM system.queries
ORDER BY elapsed_us DESC;
SELECT ended_ms, query_id, statement, ok, error, queue_us,
exec_us, peak_memory_bytes
FROM system.query_log
WHERE ok = '0'
ORDER BY ended_ms DESC
LIMIT 100;Cancel only after recording the query and owner:
CANCEL QUERY 42;Tune safely
- Size concurrency from CPU, storage latency, and the heaviest admitted operator—not client count.
- Keep queue depth finite so overload produces bounded failure instead of hidden latency.
- Set client deadlines longer than the server deadline plus expected queue and transport time.
- Paginate or aggregate large one-shot results.
- Use
EXPLAINand pruning counters before increasing operator budgets. - Separate bulk ingest periods from latency-sensitive query service when possible.
- Load-test the combined connection, query, stream, and ingest envelope.
Retry server-busy or queue-timeout failures with bounded exponential backoff and jitter only when the operation is safe to repeat. A transport failure after DDL or DML was sent is ambiguous; reconcile server state before retrying.