Skip to main content
The examples on this page use @runloop/api-client in TypeScript. See the Remote Agents SDK repository and full SDK documentation.

What This Is

Every Axon includes its own private, embedded SQLite database for structured state. Use it to store configuration, queues, indexes, checkpoints, and relational data that belongs to a single Axon. The database is accessed through the SDK:
  • axon.sql.query() — execute a single SQL statement
  • axon.sql.batch() — execute multiple statements atomically in one transaction

When to Use SQL vs Events

Use the SQL database when you need querying, transactions, or secondary indexes. Use the event stream or Broker when you need messaging or coordination with external runtimes.

Semantics and Guarantees

Axon SQL semantics
  • One database per Axon — each Axon has its own isolated SQLite instance.
  • Private — the database is not visible from other Axons or external connections.
  • Durable — data persists for the lifetime of the Axon.
  • query() — executes exactly one SQL statement.
  • batch() — runs all statements atomically in a single transaction. If any statement fails, all writes are rolled back.
  • Serialized — concurrent queries against the same Axon are serialized server-side.

Getting Started

This walkthrough creates an Axon, initializes a schema, writes rows, reads them back, and runs a transaction — everything you need to start using Axon SQL.

Create Schema

Use batch() to set up tables and indexes together. IF NOT EXISTS makes schema creation idempotent so it is safe to run on every startup.
Schema tips:
  • Use INTEGER PRIMARY KEY for auto-incrementing IDs (SQLite aliases this to rowid).
  • Store timestamps as ISO 8601 text via datetime('now') or as milliseconds in an INTEGER column.
  • Add indexes for columns you filter or sort on frequently.
  • Wrap schema setup in batch() so all tables and indexes are created atomically.

Insert and Query Data

query() executes a single SQL statement and returns a SqlQueryResultView.

Use Parameters Safely

Use ?-style positional placeholders and pass values via the params array. This prevents SQL injection and lets the database optimize repeated queries.
Always use parameterized queries for user-provided values. Never interpolate strings directly into SQL.

Run Atomic Transactions

batch() runs multiple statements in a single transaction. If any statement fails, the entire transaction is rolled back — no partial writes.

Understand Results

Query Result

query() returns a SqlQueryResultView: Each SqlColumnMetaView has name (column name or alias) and type (declared type: TEXT, INTEGER, REAL, BLOB, or empty). SqlResultMetaView contains: Example response for SELECT id, title, done FROM tasks WHERE done = 0:

Batch Result

batch() returns a SqlBatchResultView containing a results array with one entry per statement. Each entry is a SqlStepResultView with either:
  • success — a SqlQueryResultView (same structure as a single query result)
  • error — a SqlStepErrorView with a message string

Handle Errors

query() raises an exception for invalid SQL or execution errors. Catch it in your application code:
batch() executes atomically — if any statement fails, all writes are rolled back. Each step result includes either success or error, so you can inspect individual failures:
Constraint violations (e.g. UNIQUE, NOT NULL, FOREIGN KEY) behave the same way — the failing statement produces an error in the step result and the entire batch is rolled back.

Common Patterns

Key-Value Store

A simple key-value table for agent state, configuration, or checkpoints:

Task Queue

A FIFO queue with claim semantics using UPDATE ... LIMIT 1:

Schema Versioning

Track schema migrations with a version table so schema setup is safe to re-run:

Limits and Caveats

  • The Axon SQL database uses standard SQLite semantics. Supported types are TEXT, INTEGER, REAL, BLOB, and NULL.
  • Booleans are represented as integers (0 / 1).
  • query() executes exactly one SQL statement. Multi-statement strings are not supported in a single query() call — use batch() instead.
  • Axons Overview — Event streams, publishing, and subscribing
  • Broker — Bridging Axons to agents running in Devboxes
  • SDKs — SDK installation and reference docs