Readyset Docs

Core Concepts

The mental model behind RDST — targets, the query registry, the semantic layer, how the LLM is used, audits and snapshots, Readyset caches, and data agents.

RDST is built around a small number of concepts that show up across nearly every command. Reading this page once will make the rest of the documentation much easier to follow.

Targets

A target is a named database connection. Every RDST command that touches a database takes --target <name>. Under the hood, a target is:

  • A short name (for example prod-orders)
  • A database type (postgresql or mysql)
  • Host, port, database, user
  • The name of an environment variable that holds the password

RDST never stores passwords in its config. It remembers the variable name, and you export the value in your shell before each session. This means passwords follow your normal shell and secret-management practices; RDST does not add a new thing to audit.

Targets come from four sources:

SourceWhen to use
rdst initThe setup wizard creates your first target interactively
rdst configure addAdd additional targets one at a time
rdst fleet import --from fleet.csvBulk import from a spreadsheet
rdst fleet discover --regions us-east-1,us-west-2Auto-register your AWS RDS and Aurora instances

Targets are local to the machine RDST is installed on. There is no central service.

The query registry

The query registry is RDST's local catalog of SQL queries it has seen or been told about. Queries land in the registry from four places:

SourceHow
rdst topAutomatically, as slow queries are detected
rdst scanAutomatically, as ORM queries are extracted from your code
rdst analyze --save-as <name>When you want to name a query for later reuse
rdst query add <name>Manually

Every query gets a short hash that you pass to any command operating on a query:

rdst analyze --hash a1b2c3d4e5f6 --target prod-orders
rdst cache add    a1b2c3d4e5f6 --target prod-orders-cache
rdst query show   a1b2c3d4e5f6

Queries are parameterized before hashing — SELECT * FROM orders WHERE id = 42 and SELECT * FROM orders WHERE id = 99 produce the same hash — so the registry tracks query shapes, not individual executions.

Browsing the registry

rdst query list
Hash          Name                       Target         Source   Last seen
────────────  ─────────────────────────  ─────────────  ───────  ──────────
a1b2c3d4e5f6  (unnamed)                  prod-orders    top      2 min ago
f6e5d4c3b2a1  order-detail               prod-orders    top      2 min ago
9a8b7c6d5e4f  (unnamed)                  prod-orders    top      2 min ago
4d3c2b1a0f9e  top-customers-by-revenue   prod-orders    analyze  1 hour ago

Show one in detail:

rdst query show a1b2c3d4e5f6
Hash:         a1b2c3d4e5f6
Name:         (unnamed)
Target:       prod-orders
First seen:   2026-04-21 10:14:02
Last seen:    2026-04-21 12:42:18
Calls:        4,812
Avg time:     53.4 ms

SQL:
  SELECT * FROM orders
  WHERE customer_id = $1
  ORDER BY created_at DESC
  LIMIT 50;

Filter or remove:

rdst query list --filter "customer_id"
rdst query delete --hash a1b2c3d4e5f6

The semantic layer

The semantic layer is a per-target YAML describing your schema in plain language: what each table represents, what each column is for, what enum values mean, and which tables relate to which.

It is the single biggest lever for improving rdst ask and rdst analyze quality on a database that RDST has never seen before. Without it, only table and column names are available. With it, questions like "top customers by revenue last month" know that customers.segment = 'AUTOMOBILE' means automotive customers and that orders.total_cents is stored in cents.

You do not build the semantic layer by hand. Run rdst schema init to introspect the database, then rdst schema annotate --use-llm to fill in descriptions, and rdst schema edit if you want to tweak anything.

The typical flow is:

rdst schema init      --target prod-orders                # introspect
rdst schema annotate  --target prod-orders --use-llm      # auto-annotate
rdst schema show      --target prod-orders                # review
rdst schema refresh   --target prod-orders                # pick up new indexes later, keep annotations

The LLM

RDST uses an LLM for:

  • Query rewrite generation (rdst analyze)
  • Natural language to SQL (rdst ask)
  • Audit insights (rdst audit, rdst fleet audit)
  • Semantic layer auto-annotation (rdst schema annotate --use-llm)
  • ORM-to-SQL translation (rdst scan)

Two things to know about how RDST uses the LLM:

It is deterministic. Every analysis call uses temperature=0.0, an explicit validation layer, and structured JSON output. Running the same rdst analyze against the same query and schema produces the same recommendations. This is deliberate: recommendations need to be reproducible for code review, CI checks, and audit trails.

It never sees your data. RDST sends query text, EXPLAIN plans, and schema metadata to the LLM. Result rows are never included. Passwords are never included. See Configuration — Security model for the full breakdown.

Audits and snapshots

An audit is a deep health report for one database target or an entire fleet. It combines:

  • Metrics (size, connections, cache hit rate, read/write ratio)
  • A sizing verdict (oversized, right-sized, under-provisioned)
  • A Readyset cache opportunity score (0–100)
  • Top queries with full EXPLAIN context
  • Optional live query capture over a --duration window
  • LLM insights (health, bottlenecks, index recommendations, Readyset candidates)

Every audit run is persisted as a snapshot. Snapshots let you:

  • Re-read a past audit with rdst audit show <run_id>
  • Compare today's audit against last month's with rdst audit --diff <baseline>
  • Diff two fleet snapshots with rdst fleet diff snap1 snap2

See Fleet and Audit for the full workflow.

Readyset caches

RDST does not just diagnose problems — it can deploy a Readyset cache for specific queries and benchmark the result against upstream.

A Readyset cache is a shallow, read-only cache of a parameterized query, maintained by a Readyset process that sits between your application and the upstream database. rdst cache commands automate the full lifecycle — deployment (local Docker, systemd service, or Kubernetes), adding caches for specific queries, and benchmarking:

rdst cache deploy --target prod-orders --mode docker           # start Readyset
rdst cache add    a1b2c3d4e5f6 --target prod-orders-cache      # cache a query
rdst query cache-compare a1b2c3d4e5f6 --target prod-orders     # benchmark
rdst cache drop-all --target prod-orders-cache --yes           # clean up

Caches are logically bound to a target

After cache deploy, a new target is automatically registered — typically named <original>-cache. That target keeps a pointer back to the database target it caches, so RDST knows the two are a pair:

  • rdst query cache-compare accepts either name and resolves the pair automatically.
  • rdst analyze against the upstream target will also measure the query against the cache, when the paired cache exists (see rdst analyze).

Each database target has at most one cache. RDST treats the first Readyset target it finds pointing at a given upstream as the cache for that target. There is no built-in way to run two different Readyset caches in front of the same database today.

Cache targets are restricted targets

A cache target (the <original>-cache entry) shows up alongside your normal database targets in rdst configure list, but it is not interchangeable with one. Cache targets only accept cache-specific commands:

CommandRuns against cache target?
rdst cache add / show / delete / drop-all / removeyes
rdst query cache-compareyes (as either side of the pair)
rdst analyze, rdst top, rdst audit, rdst ask, rdst scanno — run these against the upstream target

If you need to inspect or audit your database, always use the upstream target name, not its cache. RDST will reject cache-specific commands run against an upstream target, and vice versa.

See Readyset Cache for deployment modes and the full command surface.

Where state lives

Everything RDST stores on your machine is local to the user who installed it. There is no server, no account, no cloud persistence. Targets, the query registry, semantic layers, and audit snapshots are all managed through RDST commands — not by editing files.

The only things RDST sends over the network are:

  • The database connection itself (when you run a command against a target)
  • LLM API calls (either directly to Anthropic with your key, or through the RDST free-trial proxy)
  • Audit HTML reports (when you use the default email flow)
  • AWS API calls (only when you run rdst fleet discover)