QueriesConcept

Queries — Concept

A query is a named, parameterized read against one or more projection tables. You declare it in the DSL; the compiler produces a parameterized SQL template; the query service executes it at runtime.

Callers never write SQL. They call a query by name with typed inputs.


Why queries exist

The write path (actions → ledger) optimizes for correctness and per-entity ordering. It is not optimized for arbitrary read patterns — joins, filters, aggregates, leaderboards.

Projections materialize event data into PostgreSQL tables shaped for your read patterns. Queries are the typed API on top of those tables:

  • Parameter validation before SQL runs
  • Tenant isolation per fork (schema-scoped)
  • Optional Redis caching
  • No ad-hoc SQL in application code

Queries vs entity reads vs projections

MechanismWhat it readsConsistency
Entity read APICurrent entity snapshot from runtimeStrong — immediately after write
Projection tableMaterialized rows from eventsEventual — lags ledger by ms–seconds
Named queryCompiled SQL over projection(s)Eventual — same as underlying projection

After submitting an action, a projection query may not reflect the write yet. Design callers for eventual consistency, or use the entity read API when you need the latest snapshot.


How execution works

  1. Client calls the query endpoint with params matching the declared input schema.
  2. Query service resolves the active IR version for the fork.
  3. It loads the compiled SQL template and binds parameters.
  4. Optional Redis cache check (if cache_ttl_seconds is set).
  5. SQL executes in the tenant schema {platform}_{app}_{fork}.
  6. Results return as JSON.

Where queries live in your app

# app.causet
includes:
  queries: [./queries/**/*.queries.causet]

Each .queries.causet file declares named queries under the queries: key. Queries reference projection table names from your projections: definitions — they cannot query arbitrary SQL tables.


IR-compiled, not hand-written SQL

The compiler validates that:

  • from references a declared projection table
  • input types match filter parameters
  • Joins connect projection-to-projection only
  • Aggregate queries include group_by

At deploy, the SQL template is baked into causet.projections.json. Changing a query requires a new release.


Next steps