Query cost guardrails

Embed
Preview of the card
<a href="https://forumulate.com/p/watchtower/docs/cost-guardrails"><img src="https://forumulate.com/api/public/orgs/watchtower/spaces/docs/pages/8fbace42-8868-4911-8884-53c2b6f373af/social-card.svg?v=3e7ae33eec8b" alt="Query cost guardrails" width="600" height="315"></a>

Every query is estimated with EXPLAIN ESTIMATE (cached 60 s per plan) and checked against the project's budgets before it runs.

  • Budgets: PUT|GET|DELETE /v1/projects/{prj}/query-budgets. Scopes project, user, agent; limits max_bytes_per_query and max_bytes_per_day; mode warn (flag the response) or enforce (422 query_too_expensive with the estimate and a hint to narrow the range). Agents have their own budgets, separate from users.

  • Attribution: each ClickHouse query carries {project, user, route, class, dashboard, tile, rule, agent} in log_comment; one query_cost_v1 row is written per query by a bounded async batcher (rows are dropped, never blocked on, when the queue is full).

  • Reports: GET /v1/projects/{prj}/query-cost?group_by=user|route|dashboard&from&to.

  • Slow queries: the slow_queries view over query_cost_v1 (5 s and over).

  • Result cache: in-memory LRU (256 MiB), key includes the project; 60 s TTL for ranges that touch now, 1 h for historical ranges; errors and partial results are never cached; ?no_cache=1 bypasses it. Ranges over 6 h are split into step-aligned 24 h chunks.

Updated