Running Queries
Inspect what the cluster is executing right now with bzrk ps, tell a slow query from a stuck one, see where each query came from, and stop one
bzrk ps lists the queries a cluster is executing, and bzrk kill stops one.
The listing is cluster-wide. A query runs on one query pod; the gateway asks
every pod and merges the answers. A pod that cannot be reached is left out of
the result and is missing from the POD column.
Reading a row
bzrk psQUERY ID POD ELAPSED QUEUED IDLE SPAN SEGMENTS CHUNKS READ ROWS
0199f3a2-7c41-7db3-9f0e-2a1b4c6d8e10 berserk-query-1 1m2s - 200ms 7d 42.0% 1200/3000 1204331
who: alice@example.com (session) from 203.0.113.7
claims: bzrk-cli 1.0.19 · cli
window: 7d 2026-08-27T09:12:00Z → 2026-09-03T09:12:00Z
search "error" | summarize count() by bin(timestamp, 1m)| Column | Meaning |
|---|---|
QUERY ID | Server-side id, and the handle bzrk kill takes |
POD | Which query pod is running it: its pod name, or its address when the pod does not know its name |
ELAPSED | How long since the query arrived |
QUEUED | How long it waited for an execution slot; - when it never waited |
IDLE | Since the last frame reached the client; - before the first one |
SPAN | How much time the query covers; see The window a query scans |
SEGMENTS | Share of the segments the query overlaps that it has finished, the progress bzrk search shows; - while still planning |
CHUNKS READ | Chunks read against chunks that must be read after pruning |
ROWS | Rows processed so far |
SEGMENTS and CHUNKS READ measure different things: many small segments
finish while a few large ones are still being read, so SEGMENTS can be near
100% while CHUNKS READ is low.
ELAPSED, QUEUED and IDLE are durations of the execution; SPAN is the
time range the query asks about.
IDLE tells a slow query from a stuck one: a query four minutes in whose last
frame was 200 ms ago is working, and one whose last frame was three minutes ago
is not. QUEUED does the same at the start: a query a minute old that has not
started is waiting for a slot, and shows no progress because it has not been
planned yet.
Buffered surfaces show no idle time
IDLE reads - for the whole life of a query on a buffered surface (the
Kusto REST endpoints), which delivers its result once, at the end.
The window a query scans
SPAN is how much time the query covers. Nothing else in the row tells a
ten-minute lookback from a thirty-day one: both can show the same elapsed time,
progress and chunk counts for a while.
The window: line under the row gives the bounds of the span. A query that
bounds ingest time gets an ingest: line of the same shape, and the column
marks an ingest-only span as i30d, so it is not read as an event window.
The window is the server's resolution of the request: relative bounds like
24h ago are resolved against the now captured when the request arrived. It
is not a client claim.
A self-bounded query reports no span
SPAN reads - when the request had no window and the query bounds itself in
KQL (| where timestamp > ago(1h)). The coordinator derives that window while
planning, after the listing entry is made, so the pod answering bzrk ps does
not know it. Pass --since, or your surface's equivalent, to make the span
visible.
--full adds every execution statistic the engine reports (slices, chunk
coverage, skip reasons by kind, bytes scanned and skipped, fetch and snapshot
time, state-cache reuse), the set bzrk search --stats prints for a finished
query.
Where a query came from
Under each row are up to three lines: who asked, what the client says it is, and the query.
who: grafana-dev (service_token) from 203.0.113.7
claims: grafana-plugin 1.4.0 · dashboard · Ingest health › p99 latency · user alice
search "error" | summarize count() by bin(timestamp, 1m)who: is what the server established. The gateway authenticated the
caller, resolved the credential and passed the result to the query pod. A client
cannot set any of it: the gateway strips the headers these travel in from every
inbound request.
| Field | |
|---|---|
| principal | Email for a user, principal name for a service |
| authn method | session, cli_token, service_token or trusted_proxy |
| client address | Left-most X-Forwarded-For from the trusted edge proxy, else the TCP peer |
claims: is what the client says about itself. Nothing verifies it, so the
listing keeps it on its own line.
| Field | |
|---|---|
| app + version | The program that issued the query |
| surface | cli, dashboard, explore, alerting, … |
| dashboard › panel | Title when the client sent one, uid or panel number otherwise |
| user | The person behind a shared credential |
| agent | The agent driving the client, when there is one |
The Berserk Grafana datasource plugin authenticates the whole organization with
one service principal, so who: names the same principal for every panel,
and claims: … user alice names the person. The plugin takes the login from
Grafana, not from anything the browser sets, but it is still the plugin's
claim.
A line with nothing to say is omitted: a client that reports nothing about
itself has no claims:.
The listing is not private
Any authenticated caller sees every running query, with its full text and the identity that submitted it.
Structured output
--json keeps the verified and the claimed fields in separate objects:
{
"query_id": "0199f3a2-7c41-7db3-9f0e-2a1b4c6d8e10",
"pod": "10.0.1.5:9510",
"query": "search \"error\" | summarize count() by bin(timestamp, 1m)",
"attested": {
"principal_type": "service",
"principal_name": "grafana-dev",
"authn_method": "service_token",
"client_ip": "203.0.113.7"
},
"claimed": {
"app": "grafana-plugin",
"app_version": "1.4.0",
"surface": "dashboard",
"end_user": "alice",
"dashboard_uid": "abc123",
"dashboard_title": "Ingest health",
"panel_title": "p99 latency"
},
"window": {
"span_ms": 604800000,
"since": "2026-08-27T09:12:00Z",
"until": "2026-09-03T09:12:00Z",
"ingest_span_ms": null,
"ingest_since": null,
"ingest_until": null,
"now": "2026-09-03T09:12:00Z",
"bypass_state_cache": false
},
"elapsed_ms": 62000,
"idle_ms": 200
}--csv and --tsv carry the same fields, flattened with the prefix kept:
attested.principal_name, claimed.dashboard_title.
The query text is stored truncated, with a trailing …, and the table shows it
on one line. --json gives the stored text.
Attributing your own client
Every field under claims: comes from one optional message on the query
request. The CLI reports itself, its version and its driving agent; the Grafana
plugin reports the dashboard, panel and Grafana login, on both its streaming and
its one-shot paths.
- It travels on the request, not in a header. The gateway drops every
inbound
x-bzrk-*header, so a header cannot carry it. The Kusto-compatible HTTP endpoints are the exception: a stock Grafana datasource pointed at them is attributed from the dashboard headers Grafana sends. - Nothing acts on it. Claims are display strings, capped in length and stripped of control characters on arrival. No planning, routing or authorization decision reads them.
Stopping a query
bzrk kill 0199f3a2-7c41-7db3-9f0e-2a1b4c6d8e10Asked query 0199f3a2-7c41-7db3-9f0e-2a1b4c6d8e10 to stop. It stops at its next work boundary.Cancellation is cooperative. The command returns once the signal is delivered
(--json reports signalled, not "stopped"), and the query stops at its next
work boundary, not mid-chunk. The client running it sees its stream end with
who stopped it:
warning: incomplete result — the query was killed by alice@example.com via `bzrk kill` before it finished, so these rows are a partial answer."No pod is running query …" (not_found in --json) usually means the query
finished between bzrk ps and bzrk kill.
After the fact
bzrk ps sees only queries in flight. The same provenance is recorded on each
query's completion event, so the dashboards and principals behind past load can
be queried; see Observability for where those
events land. The anonymized usage record
carries none of it.