PATTERN Cited by 2 sources
Query comment tag propagation via ORM¶
Pattern: instrument the ORM (or the ORM-adjacent middleware layer) to automatically attach a structured SQL comment to every query emitted during a request or unit of work, carrying the request's contextual metadata. The comment travels unchanged through connection pooling, driver layers, and any proxies to the database, and is observable on the database side by any tool that parses SQL comments.
Shape¶
At the application layer:
- Middleware captures per-request context at the beginning of the request (controller, action, background-job class, authenticated principal, request-ID, feature-flag state).
- Context is stored in request-local or thread-local storage.
- ORM hook (
ActiveSupport::Notificationssubscriber, ORM query formatter, query-log pipeline) renders the context as a structured SQL comment on every query issued. - The rendered comment string is memoised per request so per-query rendering cost is O(1) lookup.
Emitted SQL looks like:
SELECT body, author_id FROM posts WHERE id = $1
/* controller='posts', action='show', job='', user='alice@example.com' */
On the database side, the comment is inert (all SQL engines ignore leading/trailing comments at execution time) but observable by any tool that parses the SQL text — query-log analysers, proxy layers, database extensions.
Why ORM-layer, not application-layer or driver-layer¶
Three candidate altitudes for where to attach the tag:
- ORM-layer (this pattern) — tags emitted on every query the ORM issues, including ones inside library code the application author didn't write. Captures everything without requiring per-call-site discipline. Highest coverage, modest complexity.
- Application-layer per-call-site — author calls
annotate(...)at each query site. Highest precision, lowest coverage; doesn't catch library-originated queries. Useful as an override on top of ORM-layer defaults — see ActiveRecordannotate. - Driver-layer / proxy-layer — tags emitted at the SQL driver
or connection-pool layer. Cannot see request context
(driver is below the request layer). Limited to auto-tags the
driver itself can infer —
application_name,username,remote_address(Source: sources/2026-04-21-planetscale-enhanced-tagging-in-postgres-query-insights — PlanetScale Insights auto-tags). Complementary to, not replacement for, the ORM-layer pattern.
The ORM layer is the sweet spot because it sees both the request context (above it) and the query-issuance event (below it).
Canonical implementations¶
- Ruby on Rails:
- Marginalia gem (2013-ish, pre-Rails-7 canonical implementation; Basecamp).
- Rails 7+ native
query_log_tagsframework feature (2022+); framework-absorbed successor to Marginalia. - PlanetScale's
activerecord-sql_commentergem (2022-06-29) — emission-format shim on top of Rails 7query_log_tagsthat writes SQLCommenter format instead of Rails's default convention. - Django:
django-sqlcommenter(Google-maintained), analogous shape — middleware captures request context, ORM hook emits SQLCommenter-format tags. - Spring Data / Hibernate:
datasource-micrometer-sqlcommenter(Spring Cloud), analogous shape on the JVM. - Node.js: Prisma, TypeORM, Sequelize each have their own SQLCommenter integrations via extensions or hooks.
Operational properties¶
- Framework-native is cheaper than gem. Rails 7 absorbed
query_log_tagsinto the framework precisely because every non-trivial Rails app ended up installing Marginalia or equivalent. Framework-native eliminates the dependency and makes the feature available to every app by default. - Per-request memoisation is mandatory. Rendering the tag
string per query is N× work per request with N queries;
memoising per request is O(1) per query after the first.
Rails exposes this as
cache_query_log_tags = true. - Custom tag providers extend the vocabulary. Rails 7 accepts
procs or lambdas for tag values — e.g. a
feature_flag_statetag that captures which feature flags were active for the request. Pattern generalises to any key computable from the request context. - Format is a convention choice. Rails default, SQLCommenter, Marginalia's legacy format, custom in-house formats — the same pattern can emit different on-the-wire formats. The choice is downstream-tooling-driven: emit the format your query-log consumer parses.
- Connection-pool preservation required. Some ORM layers or connection pools strip comments from SQL to canonicalise for plan-cache lookup; the pattern fails silently if this happens. Must verify end-to-end that the comment reaches the database.
Complements, doesn't replace¶
- Per-query
annotateis the per-query override — for cases where the per-request baseline isn't enough. Both mechanisms compose cleanly; a query in aquery_log_tags-enabled request withannotatecarries both annotations. - Driver-layer auto-tags (Postgres
application_name,username,remote_address) provide a baseline that works even if no application-layer instrumentation is deployed. The ORM-layer pattern adds the application context the driver can't see. (Source: sources/2026-04-21-planetscale-enhanced-tagging-in-postgres-query-insights.)
Seen in¶
-
sources/2026-04-21-planetscale-patterns-for-postgres-traffic-control — canonical framework-less Go counterpart. Josh Brown (2026-04-02) canonicalises patterns/context-threaded-sql-tag-propagation — the same ORM-layer-tag-propagation shape specialised for languages without ORM middleware conventions. Go's
context.Contextis the explicit per-request storage vehicle; a wrapperQueryContext/ExecContextmethod on the database handle renders tags at query time. Same on-the-wire format (SQLCommenter), same observability outcomes, different coverage boundary: ORM-middleware covers every query the ORM issues (library queries included);context.Context- threading covers every query on actx-accepting call site (excludes legacyctx-less helpers). -
sources/2026-04-21-planetscale-identifying-slow-rails-queries-with-sqlcommenter — earliest canonical wiki instance. Coutermarsh + Ekechukwu (2022-06-29) walk the complete Rails application of the pattern — ORM-layer auto-tagging via
query_log_tags+ per-query override viaannotate+ format choice viaactiverecord-sql_commenter— and show the production debugging loop (slow-query in PlanetScale Insights → read the tag → localise the code). - sources/2026-04-21-planetscale-debugging-database-errors-with-insights
— Rafer Hazen (2022-09-27) extends the pattern to error-query
attribution. The
actortag (authenticated principal) is the canonical application-layer tag that the ORM-layer middleware captures once per request, and every query in that request carries it. Framed as the patterns/actor-tagged-query-observability pattern — the same ORM-level pattern specialised for the authenticated-user key.