User guide
Metrics
After running a query, result.report is a dict with timing, token
counts, and per-stage metrics.
result = query.run()
report = result.reportTop-level fields
| Key | Description |
|---|---|
wall_s | Query execution time in seconds, not counting model startup. |
boot_s | How long it took to load the model and compile kernels. |
boot_kind | "cold" if this was the first query in the session (model loaded from disk), "warm" if the model was already in memory. |
fresh_tokens | Total input tokens processed by the model. If a token's KV was evicted and the model had to reprocess it, it counts again. |
worker_total_s | Wall time including tokenization and planning, but not report writes. |
remarks | Notes from the planner and tokenizer, for example which tokenizer was selected and why. |
Per-stage metrics
report["stages"] is a list with one entry per filter or join:
| Field | Description |
|---|---|
op | "filter" or "join". |
alias | Which table alias this stage operates on. |
written_pos | The position of the predicate in the query text, counted from 0, so a stage can be matched to its explain() line whatever order the planner ran them in. |
provided_selectivity | The selectivity you set in the query, or null if you did not provide one. |
observed_selectivity | The actual fraction of rows or pairs that passed after execution. |
evaluated | How many rows (for a filter) or pairs (for a join) the model evaluated. |
Per-node metrics
report["node_metrics"] is a dict keyed by physical node id (for
example "ai_filter:r" or "ai_join:r"). These correspond to
the nodes shown in explain() output.
| Field | Description |
|---|---|
input_rows | How many rows or pairs entered this node. |
output_rows | How many passed. |
fresh_tokens | Input tokens this node processed. |
evaluated_documents | Documents evaluated (filters only). |
Boot details
When boot_kind is "cold", report["boot"] has a breakdown:
| Field | Description |
|---|---|
load_model_s | Time to load model weights onto the GPU. |
arena_s | Time to allocate the KV page pool in GPU memory. |
warm_kernels_s | Time to compile GPU kernels. |
warm_tier | "touch" on a first run (kernels compiled from scratch), "warm" when using cached kernels. |
GPU cost
GPU cost is query time multiplied by the hourly GPU price.
H100_USD_PER_HOUR uses
Modal's published H100 price ($3.9492
per hour as of September 2026).
from quail.specs import H100_USD_PER_HOUR
cost_usd = (report["wall_s"] / 3600) * H100_USD_PER_HOURIf you used multiple GPUs, multiply by the number of GPUs.