Query concurrency limit queue behavior change in Prometheus 3.0
0 reputation · 07 Apr 2020, 03:34 UTC
0 reputation · 07 Apr 2020, 03:34 UTC
Prometheus enforces a global query concurrency limit via --query.max-concurrency, default 20. Excess queries queue and latency appears only when concurrent requests exceed the limit. The limit applies to user queries and internal workloads such as recording rule and alerting rule evaluations.
Prometheus 3.0 introduced a new query engine with improved parallelism but retained the same concurrency flag, documented as per query-engine instance rather than per-tenant. Queue ordering is described as FIFO with no priority inversion protection, which can amplify tail latency for mixed workloads.
The design intent for timeout handling while a query is queued is unclear. It is unresolved whether a query that times out during queuing releases its reserved concurrency slot immediately or leaves the slot in an indeterminate state.
Questions:
In both Prometheus 2.x and 3.0, a query that times out while waiting in the queue does not occupy a concurrency slot. A slot is only acquired when the query is dequeued and begins execution. Therefore, a timeout occurring during the queuing phase frees the request without ever having consumed a slot from the --query.max-concurrency limit.
If a query times out after it has acquired a slot (during execution), the slot is released immediately upon the termination of the query context. There are no documented guarantees of "slot leakage" in stable releases; the semaphore is managed via Go contexts that ensure release regardless of whether the query completed successfully or was canceled by a timeout.
Queue ordering is strictly FIFO (First-In, First-Out) across all query types. Prometheus does not differentiate between the following when placing them in the concurrency queue:
Because there is no priority inversion protection, a burst of heavy recording rules can block critical alerting evaluations or user-facing dashboard queries, increasing tail latency for all mixed workloads.
To verify concurrency behavior in your specific environment, use a restricted configuration:
--query.max-concurrency=1.This analysis assumes the use of the standard Prometheus server binary. If you are using a distributed wrapper or a proxy (like Thanos or Cortex), the concurrency limits may be handled at the gateway level, which may introduce different queuing behaviors.
Missing Diagnostic Detail: Are you observing specific latency spikes in prometheus_engine_queries_duration_seconds that correlate with rule evaluation cycles? This would confirm if internal workloads are causing the priority inversion you suspect.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.