Skip to content

ADR-0011 — Session query tag auto-injection

Update date : 2026-05-27 21:55

Status: accepted Date: 2026-05-27

Context

Snowflake query history captures SQL but not its business context. Without a query tag, it is impossible to attribute credits to a client, a product, or a profile — cost allocation requires a manual join on user/role which loses the semantic context.

The common antipattern: create one warehouse per client/team/product to isolate costs. This works for attribution but generates WH proliferation, idle credits, and management overhead. The root cause is the absence of a tagging convention — not a genuine need for isolation.

Query tags on a shared warehouse give the same cost attribution through QUERY_HISTORY at zero extra infra cost. The tag is the alternative to the warehouse.

The only legitimate reason to create separate warehouses is workload lifecycle isolation — workloads that must not compete for resources and have different auto-suspend/size/concurrency needs:

Warehouse Workload Why separate
CI test runs burst, short-lived, must not block other work
Apps Streamlit sessions latency-sensitive, concurrent, user-facing
Users Snowsight / BI ad-hoc variable, unpredictable
Pipelines scheduled tasks batch, can queue, different sizing

Cost attribution across these four is still done via query tags — not by adding more warehouses.

Decision

Every SP generated or managed by the provider injects ALTER SESSION SET QUERY_TAG at the start of execution. The tag is structured JSON, derived from the manifest metadata:

ALTER SESSION SET QUERY_TAG = '{
  "client": "<client_schema>",
  "product": "<WHAT from db_name>",
  "session_id": "<session_id>",
  "profile": "<role>"
}';

Fields are populated from: - client — client schema name (multi-tenant) or schema name (standard) - productWHAT derived from db_name (ADR-0010), or schema_name for pinky suite repos - session_id — Snowflake session identifier - profile — executing role

Scope — applies to all suite sessions

Layer Where Status
pinky-provider injected in every generated SP accepted
pinky-streamlit session.py — set on session creation to implement

Consequences

  • Every query is attributable to a business context — no post-hoc join on user/role needed.
  • pinkysight reads QUERY_TAG from SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY and serves cost breakdown by client, product, and profile out of the box.
  • Zero developer effort — the tag is injected by the provider or the session layer, not written by the SP/Streamlit author.
  • The schema naming convention (ADR-0010) is the source of truth for product — consistent attribution across all repos without manual config.