prometheus/prometheus
PromQL
Active contributors: roidelapluie, codesome, krajorama, bwplotka
Purpose
PromQL is the query language used by Prometheus, Grafana, and downstream systems. The promql/ directory implements its lexer, parser, AST, and evaluation engine. The engine is purely a library — it doesn't open files or sockets; its inputs are a storage.Queryable and a query string, its output is a Result.
Directory layout
promql/
├── engine.go # The query engine (~4,700 lines).
├── functions.go # PromQL function implementations (~88,000 bytes; ~80 functions).
├── value.go # Vector, Matrix, Scalar, String result types.
├── quantile.go # Histogram quantile and friends.
├── durations.go # promql-duration-expr parsing.
├── histogram_stats_iterator.go # Stats over native histograms.
├── info.go # Implementation of the `info()` function.
├── query_logger.go # Per-query log writer.
├── parser/
│ ├── generated_parser.y # goyacc grammar (~56 KB).
│ ├── generated_parser.y.go # generated parser.
│ ├── lex.go # Hand-written lexer.
│ ├── ast.go # AST node types.
│ ├── parse.go # Parser entry points.
│ ├── printer.go # AST -> string.
│ ├── prettier.go # PromQL pretty-printing.
│ ├── functions.go # Function arity/type metadata.
│ └── posrange/ # Source position tracking.
└── promqltest/ # The PromQL test framework + golden test files.How a query is evaluated
graph TD
A[Query string] --> B[Lex]
B --> C[Parse to AST]
C --> D[Walk AST<br/>find selectors]
D --> E[Querier per timerange]
E --> F[Postings for matchers]
F --> G[Open chunk iterators]
C --> H[Engine.exec]
H --> I[Eval at each step]
G --> I
I --> J[Result: Matrix/Vector/Scalar/String]The engine has two execution modes:
- Instant query (
NewInstantQuery) — one timestamp; returns aVector(or scalar/string). - Range query (
NewRangeQuery) —start,end,step; returns aMatrix.
For both, the engine walks the AST top-down, opening queriers and chunk iterators lazily. The "step invariant" optimisation (#15094) caches sub-expressions whose result does not depend on t.
Sub-pages
- Parser and AST — the lexer, the goyacc grammar, and the AST walking utilities.
- Engine and evaluation — how the engine plans and runs queries, and how to add new functions.
Result types
Defined in promql/value.go:
| Type | What it represents |
|---|---|
Vector |
Set of samples at one timestamp, one per series. |
Matrix |
A vector per series across many timestamps. |
Scalar |
A single (t, v) pair. |
String |
A single string value (e.g. topk(0) result). |
Sample and Series carry both float values and native histograms; iterators differentiate via the chunkenc.ValueType enum.
Engine options
promql.EngineOpts (engine.go) exposes the knobs:
MaxSamples— caps total samples touched by a query (--query.max-samples).Timeout— per-query timeout (--query.timeout).LookbackDelta— staleness window (--query.lookback-delta, default 5 min).NoStepSubqueryIntervalFn— fallback step for unbounded subqueries.EnableAtModifier,EnableNegativeOffset— toggles for legacy compatibility.EnablePerStepStats— exposestotalQueryableSamplesper step (gated by--enable-feature=promql-per-step-stats).EnableExperimentalFunctions(gated by--enable-feature=promql-experimental-functions).EnableTypeAndUnitLabels,LookbackDelta.
Self-metrics
All metrics are prefixed prometheus_engine_*:
prometheus_engine_query_duration_seconds(histogram, withslicelabel:queue|prepare|inner_eval|result_sort).prometheus_engine_queries_total.prometheus_engine_queries(gauge of currently running queries).prometheus_engine_query_log_failures_total.prometheus_engine_queries_concurrent_maxand_canceled(gauges).
Concurrency
The engine implements a query gate (util/gate) limiting concurrent queries to --query.max-concurrency. Each query runs on its own goroutine, with sub-task fanout for binary operators.
Tracing
Spans are emitted for query_eval_total, query_inner_eval, and around chunk fetching. The trace ID is logged in the query log when tracing is enabled (3.11, #18189).
Integration points
- Storage: the engine takes a
storage.Queryableand astorage.ChunkQueryable. Both interfaces live instorage/interface.go. - Web API:
web/api/v1.api.queryRangeandapi.queryare the HTTP entrypoints. - Rules:
rules/manager.go::EngineQueryFuncwraps the engine for rule evaluation. - promtool:
cmd/promtool/query.gouses the engine indirectly via the HTTP API;cmd/promtool/unittest.gouses it directly. - UI: the editor in
web/ui/mantine-ui/src/promql/uses the same parser via the npm@prometheus-io/codemirror-promqlmodule.
Entry points for modification
- New PromQL function: add the implementation in
promql/functions.go, register its arity inpromql/parser/functions.go, regenerate the UI helpers viamake generate-promql-functions, and add tests inpromql/promqltest/testdata/. - New operator or syntax: edit
promql/parser/generated_parser.y, runmake parser, then implement the AST node and engine logic. - Engine optimisation: the engine has plenty of unused-sample-elimination room. New work should include a
BenchmarkRangeQueryrun before/after. - Annotation (warning/info): add to
util/annotations/. Annotations propagate throughResult.WarningsandResult.Infosand surface in the UI.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.