Query Commands

Query converted minitrace archives with the normalized SQLite engine using presets, custom SQL, or structured commands

Sections

Terminology & Glossary
📖 Documentation
Navigation
22 sectionsv0.1
📄 Query Commands — glaze help query-commands
query-commands

Query Commands

Query converted minitrace archives with the normalized SQLite engine using presets, custom SQL, or structured commands

Topicminitracesqliteglazedsqletonqueryquery runquery commands

The query group loads converted minitrace archives into a normalized SQLite database and runs queries against it. There are two user-facing workflows:

  • query run for built-in presets, inline SQL, and SQL files against the normalized schema
  • query commands for repository-backed sqleton-style structured commands, including SQL templates and JavaScript handlers

Both workflows share the same engine: a sandboxed, read-only SQLite query runner over the normalized tables. SQL structured commands render read-only SQL against that runner; JavaScript structured commands call require("minitrace").db().RuntimeArchives().QueryCommandDefaults().Build() and can run several queries and combine or score the results in JavaScript.

Query workflow choices

Choose query run when you are exploring, prototyping, or already have raw SQL in hand. It is the shortest path from idea to result.

Choose query commands when the query should become a named, reusable analysis tool. Structured commands give you typed parameters, aliases, CLI discoverability, and a matching form in the /query web UI.

For the full structured-command authoring and repository-loading guide, see go-minitrace help structured-query-commands.

How query run works

When you run query run, go-minitrace:

  1. Expands the archive globs and fingerprints the matching .minitrace.json files
  2. Builds (or reuses from cache) a normalized SQLite database with one table per entity: sessions, turns, tool_calls, turn_tool_calls, files, annotations, handovers, metrics, attachments, events
  3. Runs either a named preset, inline SQL, or a SQL file through the sandboxed read-only query runner
  4. Streams results through Glazed for output formatting

The runner enforces an allowlist of the normalized tables plus the sessions_base compatibility view; DDL, writes, and access to sqlite_master are rejected.

query run

go-minitrace query run [flags]

Flags

FlagDefaultDescription
--archive-glob./output/active/*/*.minitrace.jsonRepeatable glob flag matching minitrace session files
--presetNamed built-in query to run
--sqlInline SQL to run against the normalized database
--sql-filePath to a SQL file to execute
--max-rows1000Maximum number of rows to return
--max-cell-chars4000Maximum number of characters per result cell
--timeout-ms5000Query timeout in milliseconds

Exactly one of --preset, --sql, or --sql-file must be specified. They are mutually exclusive.

Query modes

Preset mode runs one of the built-in queries:

go-minitrace query run \
  --archive-glob './output/active/*/*.minitrace.json' \
  --preset session-list

Inline SQL mode runs arbitrary SQL against the normalized database:

go-minitrace query run \
  --archive-glob './output/active/*/*.minitrace.json' \
  --sql "SELECT COUNT(*) AS total FROM sessions"

SQL file mode reads a query from a file. This is useful for saved query libraries:

go-minitrace query run \
  --archive-glob './output/active/*/*.minitrace.json' \
  --sql-file ./my-query.sql

Built-in presets

Presets are embedded under pkg/minitracedb/presets/ and addressed by bare name (or folder/name when ambiguous):

PresetDescription
overview/session-listOne row per session: id, framework, model, title, turns, tools, duration, read ratio, start time, source format
overview/framework-summaryAggregate stats by agent framework: session count, average tools/turns/read ratio/duration/TTFA
overview/annotationsAll annotations joined with sessions: session ID, framework, annotator, category, title, scope
timing/timing-analysisDuration, active time, TTFA, idle ratio, min/max duration by framework
tools/tool-operation-breakdownTool call counts grouped by framework and operation type (read, modify, create, execute, delegate)
tools/tool-failuresFailed tool calls with turn, tool, target, and error detail
tools/read-ratio-distributionPer-session breakdown of reads, modifies, creates, executes with read ratio
files/file-operationsEvery file touch in session order with success/failure status
files/file-timelineChronological operations on files, with result content classified into short labels

Output formatting

Query results flow through Glazed, so all standard output options work:

# Default table output
go-minitrace query run --archive-glob '...' --preset session-list

# JSON for piping
go-minitrace query run --archive-glob '...' --preset session-list --output json

# CSV for spreadsheets
go-minitrace query run --archive-glob '...' --preset session-list --output csv

# Select specific fields
go-minitrace query run --archive-glob '...' --preset session-list --fields id,framework,turns,tools

The normalized schema

The database has one table per minitrace entity:

TableContents
sessionsOne row per session: provenance, environment, timing, operational context, outcome, and rollup counts as real columns
turnsOne row per conversational turn: role, content, model, thinking, token usage
tool_callsOne row per tool call: tool name, operation type, file path, command, success, error, exit code, duration
turn_tool_callsJoin table preserving tool-call membership and ordinal per turn
filesOne row per file path touched by a tool call
annotationsOne row per annotation with scope, content, and taxonomy mappings
handoversReceived/produced handover documents per session
metricsWide per-session metrics: tokens, timing, subagents, model switches
attachmentsArtifact references (images, files) linked to turns, tool calls, or events
eventsTimeline events such as compactions, mode changes, or rate-limit snapshots

Fields that used to require UNNEST on JSON arrays are now plain rows in child tables keyed by session_id:

SELECT tc.tool_name, tc.operation_type, tc.success
FROM tool_calls tc
JOIN sessions s USING (session_id)
LIMIT 20;

Long-tail fields that never got a real column are still reachable through JSON: every table carries a raw_json column with the original record, and turns/tool calls carry framework_metadata_json:

SELECT session_id,
       json_extract(framework_metadata_json, '$.stop_reason') AS stop_reason
FROM turns
WHERE framework_metadata_json IS NOT NULL
LIMIT 10;

The sessions_base compatibility view

Session-level SQL written for the removed DuckDB engine keeps working against the sessions_base view, which reconstructs the old shape (scalar columns id, title, summary, classification, profile plus JSON blob columns provenance, flags, environment, operational_context, timing, turns, tool_calls, annotations, metrics) from the sessions table. SQLite >= 3.38 supports ->/->> on those JSON text columns:

SELECT id, environment->>'model' AS model
FROM sessions_base
LIMIT 5;

Per-tool-call and per-turn SQL should move to the tool_calls/turns tables — SQLite has no UNNEST. See go-minitrace help query-duckdb for the full migration table.

Querying annotations

Annotations synced into the archives appear in the annotations table:

SELECT a.session_id, a.scope_type, a.category, a.title
FROM annotations a
ORDER BY a.session_id;

One subtle but important rule: query run reads the .minitrace.json archive files it loads. If you created or edited annotations through go-minitrace annotate ..., run go-minitrace annotate sync --output-dir ... first so the archive contains those changes. (The web UI is different: serve ATTACHes the live annotation store as schema anno, so anno.annotations is always current there.)

Troubleshooting

ProblemCauseSolution
Query returns 0 rowsArchive glob doesn't match any filesCheck the glob path with ls first
one of preset, sql, or sql-file must be specifiedNo query mode givenAdd --preset, --sql, or --sql-file
preset, sql, and sql-file are mutually exclusiveMore than one query mode specifiedUse exactly one
access to table "..." is not allowedQuery references a table outside the allowlist (including sqlite_master)Stick to the normalized tables; use db.schema() from JS or go-minitrace help minitrace-schema for introspection
no such function: UNNEST or similarDuckDB-era SQLRewrite against the child tables; see go-minitrace help query-duckdb
Query cancelledTimeout exceededRaise --timeout-ms

Structured query commands

The query commands subgroup loads repository-backed sqleton-style command files. Repository subdirectories become nested CLI groups, so pkg/minitracecmd/core/overview/session-list.sql is exposed as go-minitrace query commands overview session-list.

Those files define:

  • a command name and help text
  • typed Glazed fields
  • optional aliases with prefilled defaults
  • a SQL template (rendered against the normalized schema; the {{TABLE_NAME}} placeholder substitutes to the sessions_base compatibility view) or a JavaScript handler

A simple example looks like this:

go-minitrace query commands overview session-list \
  --archive-glob './output/active/*/*.minitrace.json' \
  --framework codex,pi

The legacy --db-path, --table-name, and --persist-loaded flags are deprecated: SQL commands ignore them (with a warning) and always run against the normalized database built from --archive-glob. JS commands still see the values on mt.runtime but should use mt.db() instead.

The repository-backed flow is the right choice when a query should be reusable by other people, promoted into the web UI, or shared through config/env/flag-discovered command repositories.

See go-minitrace help structured-query-commands for:

  • how repository loading works
  • how to configure queryRepositories, GO_MINITRACE_QUERY_REPOSITORIES, and --query-repository
  • how to write /* sqleton ... */ command files
  • how to write .alias.yaml shortcut files

See also

  • go-minitrace help structured-query-commands — run and author sqleton-style structured query commands
  • go-minitrace help annotation-playbook — operator workflow for creating, syncing, and validating annotations
  • go-minitrace help writing-queries — how to write custom SQL against the normalized schema
  • go-minitrace help query-recipes — ready-to-use query examples
  • go-minitrace help query-duckdb — migrating saved DuckDB SQL to the normalized engine
  • go-minitrace help output-formats-and-pipelines — detailed Glazed output formatting guide
  • go-minitrace help minitrace-schema — field reference for the archive JSON and normalized tables