Skip to main content
Run SQL queries against Braintrust. In a terminal, bt sql opens an interactive editor with query history. Pass a query directly or pipe from stdin for scripting.
Most SQL data-source functions also accept an object name in place of its ID. See Querying by name.
When a project is selected through bt switch, --project, or BRAINTRUST_DEFAULT_PROJECT, use FROM logs as shorthand for that project’s logs. bt resolves the project and replaces the shorthand with project_logs('<project-id>') before sending the query. Use project_logs('<project-name-or-id>') when the query should name a project directly instead of using the selected context.

Interactive controls

Query syntax

  • A FROM clause is required (logs, project_logs(...), experiment(...), or dataset(...))
  • FROM logs requires a selected project
  • Prefer filtering with WHERE; use HAVING only after aggregation
  • Joins, subqueries, unions, and window functions are not supported
  • Use explicit column aliases and type casts for clarity
  • Paginate large results with OFFSET '<cursor_token>' (not supported with --async)
For tips on query performance and common pitfalls, see SQL best practices.

Flags

For async query flags, see Async query flags.

Async queries

Async queries are only available on the Enterprise plan.
On Braintrust-hosted deployments, synchronous queries time out after 30 seconds. For longer queries, pass --async to run the query in the background. Async queries process rows in batches, in the order Braintrust stores them, so they can select and filter rows but can’t aggregate, deduplicate, or sort them. count(), sum(), GROUP BY, SELECT DISTINCT, ORDER BY, and OFFSET aren’t supported. For runtime, result size, retention, and concurrency limits, see Limits.

Run an async query

With --async, the CLI submits the query, polls until it finishes, and prints the results. Async queries need an object ID in the FROM clause. Passing a name, such as project_logs('project-name'), fails with a “Missing read access” error. To query a project by name, select it with -p and use FROM logs. bt looks up the project and sends its ID.
  • --async needs the query up front, as an argument or through stdin. It doesn’t open the interactive prompt.
  • The SQL linter doesn’t check async queries, so narrow a broad query before you run it.
  • bt downloads every page of results before printing them. For large exports, submit without waiting and fetch the results in pages with the API.

Submit without waiting

Pass --no-wait to submit the query and exit immediately. The CLI prints the submit response as JSON, including the query’s id.
bt has no command to resume a submitted query. Use the id with the API to check its status, fetch results, or cancel it.

Async query flags

If --wait-timeout expires, bt exits with an error that includes the query’s id. The query keeps running, so you can use the id with the API to fetch its results or cancel it.