Queries Overview
A query is a named, parameterized read against one or more projection tables. You declare queries in .queries.causet files. The compiler converts them to parameterized SQL. At runtime, the query service binds inputs and executes against the fork’s projection schema.
Callers do not write SQL. They call a query by name with typed parameters.
How queries fit into the read path
Write path: Intents emit events → projection worker UPSERTs rows.
Read path: Named queries compile to SQL over those rows → query service returns JSON.
Projections and queries are eventually consistent with the ledger. There is a lag between a write and when it appears in query results.
Execution flow
- Client calls
POST .../queries/{query_name}with a JSONparamsbody. - Query service resolves the active IR version for the fork.
- Compiled SQL template loads from the IR; parameters bind.
- Optional Redis cache check (if
cache_ttl_secondsis configured). - SQL executes in the tenant schema
{platform}_{application}_{fork}. - Results return as a JSON array.
Declaring queries
# app.causet
includes:
queries: [./queries/**/*.queries.causet]Each query names a from projection table, optional input params, filters, joins, and limits. The compiler validates table references and parameter types at build time.
In this section
| Page | What it covers |
|---|---|
| Concept | Why queries exist, read vs write path, eventual consistency |
| Defining Queries | from, input, fields, top-level schema |
| Filters & Joins | WHERE operators, joins, order, limit |
| Aggregates | group_by, aggregate, coalesce_zero |
| Caching | Redis TTL and staleness trade-offs |
| Best Practices | Common mistakes and production guidance |
| Examples | Concert-app query catalog |
Next steps
- Projections — tables queries read from
- Intents — write path that produces events
- Defining Queries — DSL syntax