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)
- product — WHAT 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_TAGfromSNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORYand 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.