CONCEPT Cited by 1 source
SQLCommenter query tagging¶
SQLCommenter is a Google-originated (google.github.io/sqlcommenter) open standard for appending key-value metadata to SQL queries as a SQL comment. The SQL is executed unchanged; the comment is inert from the database-engine perspective but observable to extensions, proxies, and log analyzers.
Syntax¶
A trailing (or inline) SQL comment with structured key-value pairs:
SELECT body, author_id, created_at FROM posts WHERE id = $1
/* category='viewPost', priority='critical' */
The application is in full control of the keys and values.
Conventional keys the SQLCommenter spec defines include
application, controller, action, framework, route,
db_driver, traceparent. Teams routinely add their own
(team, priority, category, user_id, feature_flag,
etc.).
What it enables¶
Because the comment is an inert annotation on the SQL itself rather than a side-channel, any layer that inspects the SQL text can act on it:
- Query attribution — map each query back to the application code path that issued it (patterns/actor-tagged-query-observability, concepts/actor-tagged-error).
- Aggregate statistics broken down by tag — concepts/aggregate-tag-attribution / concepts/per-pattern-tag-cardinality at the observability tier.
- Workload-class resource enforcement — patterns/workload-class-resource-budget / patterns/shed-low-priority-under-load at the control tier. Budget rules key on tag values; queries get blocked or accepted by the tag they carry.
- Search / filter surface over captured query logs —
tag:key:valuefilter syntax in the observability UI. - Priority-based load shedding — priority tiers encoded as a SQLCommenter tag at every call-site; the runtime control plane decides which class to shed.
Why comments, not side-channels¶
A few alternatives exist; SQLCommenter chose the comment-inside-SQL path deliberately:
- Dedicated metadata headers — require client modifications, don't flow through connection pools cleanly, don't work with vanilla SQL clients.
- Session variables (
SET LOCAL) — one per session, not per query; also require round-trip and don't interleave with batched queries. - Stored-proc parameters — can't be added retroactively to existing query patterns.
- Sampling / tracing context (OpenTelemetry) — orthogonal
and compatible; SQLCommenter supports
traceparentnatively.
A SQL comment travels with the query through every layer (app ORM → connection pool → wire protocol → replica fanout → query log → extension) unchanged, with no engine-side coupling.
Canonical consumers¶
- PlanetScale Insights Postgres extension — parses SQLCommenter tags at the extension layer, emits them into the observability pipeline, indexes per-tag aggregate stats.
- PlanetScale Traffic
Control — the control-plane consumer. Budget rules
match on tag values (
priority='critical',action='analytics', etc.); over-budget queries are blocked. - Google Cloud SQL Insights — Google's own first-party consumer; the spec is effectively a Google-originated convention promoted to an open standard.
Auto-populated tags alongside application-populated tags¶
Insights augments application-authored SQLCommenter tags with three auto-populated ones set at the Postgres / extension layer (Source: ):
application_name— set by the Postgres driver.username— the Postgres role that issued the query.remote_address— the client IP.
Auto-tags are available even if the application never adds a single SQLCommenter tag, giving operators a baseline attribution surface before application-level tag discipline is deployed.
Gotchas¶
- Connection pool stripping. Some ORMs / pools strip comments from SQL by default (to canonicalise for cache lookup). Has to be configured to preserve comments.
- Query-plan cache key sensitivity. If the cache key
includes comment bytes, each new tag value produces a
plan-cache miss. Postgres's
pg_stat_statementsnormalises over comments by default; mixed-extension setups may differ. - Log-line bloat. Every query in the log is now longer; downstream log-analysis pipelines must be cardinality- aware (concepts/per-pattern-tag-cardinality, patterns/dynamic-cardinality-reduction-by-tag-collapse).
- Arbitrary-string injection risk. User-controlled strings should never be interpolated into SQLCommenter tags — the same SQL-injection-hygiene rules apply as anywhere else in the SQL path.
- Tag discipline is app-level work. The comment doesn't magically appear; every query path that matters must be tagged, which is a coordination problem across a codebase.
Seen in¶
-
— canonical Go-language implementation companion. Josh Brown (2026-04-02) canonicalises SQLCommenter as the substrate for composable tag axes ([[concepts/composable- tag-axes]]) — five orthogonal axes (service / route / deployment / tier / workload) coexist on one tagged query via
context.Context-threaded propagation, AND-composed at enforcement time by Traffic Control. The Go variant is the framework-less counterpart to the 2022 Rails ORM-middleware pattern: two application helpers (appendTagsdeterministic render +tagsFromContextcopy-on-read) + a wrapperQueryContextmethod render tags at the database boundary. CanonicalappendTagsshape withsort.Strings(parts)for deterministic ordering (plan-cache stability) +url.Query Escapefor value encoding. Also canonicalises the driver- side companion to application-level tags:application_nameas a connection-string-level tag (patterns/dedicated-application-name-per-workload) set by the driver not the app — "ensures that it is always set for this service, no matter the query or connection string given." -
— earliest canonical wiki source for SQLCommenter in a Rails context. Mike Coutermarsh + Iheanyi Ekechukwu (2022-06-29) publish the how-to for enabling SQLCommenter- format tags on every ActiveRecord query via Rails 7's native
query_log_tagsframework feature + the PlanetScale-authoredactiverecord-sql_commentergem that swaps the emission format from Rails's defaultkey:valueto SQLCommenter'skey='value'. Establishes the exact byte-level format difference (Rails default vs SQLCommenter), the three-setting enable envelope (query_log_tags_enabled+query_log_tags = [...]+cache_query_log_tags), and the per-queryannotateoverride as the complementary escape hatch. Earliest wiki disclosure of Insights's>1 sectail-query capture threshold (narrower predecessor to the three-axis threshold canonicalised on 2022-09-27). Also the earliest instance in PlanetScale's own production-debugging voice of the tag-then-filter-in-Insights workflow — ~3 months before Hazen's canonical 2022-09-27actor-tag post. Canonicalises ORM-layer query-comment tag propagation as a pattern across the pre-Rails-7 Marginalia → Rails 7query_log_tags→ SQLCommenter-format migration timeline. -
sources/2026-04-21-planetscale-graceful-degradation-in-postgres — Canonical priority-classification instance:
priority categorytags on every query drive a three-tier Traffic Control budget setup. First canonical wiki explanation of SQLCommenter as a named standalone primitive.- — First canonical wiki instance of SQLCommenter paired
with Traffic Control.
action=analyticstag drives the 1-concurrent-worker cap that protects the MVCC horizon. - — Extends SQLCommenter visibility from per-query notable- query stream to per-tag aggregate statistics; auto- populated tags canonicalised.
- —
tag:key:valuefilter syntax in Insights search surface built on top of SQLCommenter tags.
Related¶
- concepts/query-tag-filter
- concepts/aggregate-tag-attribution
- concepts/actor-tagged-error
- concepts/query-priority-classification
- concepts/per-pattern-tag-cardinality
- concepts/rails-query-log-tags
- concepts/activerecord-annotate
- concepts/context-propagated-sql-tags
- concepts/composable-tag-axes
- patterns/actor-tagged-query-observability
- patterns/workload-class-resource-budget
- patterns/shed-low-priority-under-load
- patterns/query-comment-tag-propagation-via-orm
- patterns/context-threaded-sql-tag-propagation
- patterns/route-tagged-query-isolation
- patterns/tier-tagged-query-isolation
- patterns/dedicated-application-name-per-workload
- systems/planetscale-insights
- systems/planetscale-traffic-control
- systems/activerecord-sql_commenter
- systems/ruby-on-rails