CONCEPT Cited by 1 source
Composable tag axes¶
Composable tag axes is the design property of a query- tagging rule engine that allows multiple orthogonal tag dimensions to coexist on the same query, with budget rules able to match on any single axis or any AND-combination of axes. Every query carries a tuple of tag values, not a single classification label; a rule matches a query if the query satisfies the rule's tag predicates.
The canonical realisation is PlanetScale Traffic Control's budget engine, where a single query can simultaneously carry — and be governed by — up to five or more independent axes.
The five canonical axes¶
The canonical five axes from the Brown post (Source: sources/2026-04-21-planetscale-patterns-for-postgres-traffic-control):
| Axis | Source | Example tag |
|---|---|---|
| Service | Postgres username (dedicated role per service) or application_name connection-string parameter |
username='pscale_api_123abc' |
| Route | HTTP middleware reads r.Pattern |
route='/api/checkout' |
| Deployment | Startup env var (DEPLOYMENT_TAG=...) |
feature='new_checkout_v2' |
| Tier | Auth middleware reads user.Tier |
tier='FREE' |
| Workload | Dedicated connection pool per workload | application_name='background-jobs' |
These are orthogonal — any one query from a web handler processing a free-tier user's checkout request on the canary deployment could carry all five tags simultaneously:
SELECT ... /* app='web', route='/api/checkout',
feature='new_checkout_v2', tier='FREE',
application_name='pscale_api_123abc' */
AND-composition semantics¶
The load-bearing rule-engine property: multiple matching
budgets all apply simultaneously and queries must satisfy every
budget they match (Source, verbatim). A query tagged
tier='free' and route='api-export' is subject to:
- The
tier='free'budget (all free-tier traffic) - The
route='api-export'budget (all export-endpoint traffic) - The
tier='free' AND route='api-export'budget (specifically free-tier export traffic, typically stricter than either alone)
All three caps apply at once; the query must pass all three to not be rejected. The strictest applicable rule wins — or more precisely, every applicable rule is independently enforced, so the query experiences the intersection of resource limits.
Why orthogonal axes beat single-label classification¶
A classification-based alternative would require every team to agree on a single taxonomy axis (priority? workload-type? tier?) and project their concern onto it — losing information the other axes captured. Orthogonal axes preserve independent concerns without requiring cross-team coordination:
- The platform team sets
application_nameper service (Pattern 1) without coordinating with… - …the web team that sets
routein middleware (Pattern 2), which doesn't need to know about… - …the release team that sets
feature=<deployment-tag>at startup (Pattern 3), which is independent of… - …the billing team that sets
tierin auth middleware (Pattern 4), which doesn't affect… - …the jobs team's dedicated
application_nameper job pool (Pattern 5).
Each team owns one axis, defines budgets on it, and compositions happen at rule-authoring time without schema coordination.
Canonical framing¶
Verbatim (Source: sources/2026-04-21-planetscale-patterns-for-postgres-traffic-control):
"Traffic Control sees all of this as a combination of tags. A budget on
tier='free'covers all free-tier traffic regardless of route. A budget onroute='api-export' AND tier='free'covers a specific combination. Multiple matching budgets all apply simultaneously and queries must satisfy every budget they match. You can build layered policies without complicated rule logic."
"Layered policies without complicated rule logic" is the canonical wiki framing of what orthogonal axes buy — each team defines its rules independently, composition is automatic.
Comparison with priority-only classification¶
The 2026-03-31 Dicken graceful-degradation post canonicalised
a priority-tier-only tagging scheme
(critical / important
/ best-effort). That's one axis. The Brown post extends to
priority + four more axes — priority is still meaningful,
but it's one dimension among many. A query can be
priority='critical' AND tier='free' AND route='/api/post'
simultaneously, with budgets potentially defined on each axis
or any combination.
Canonical relationship: priority classification is one axis; composable tag axes is the meta-framework that lets priority coexist with orthogonal axes the app team cares about.
Design constraints¶
- Axes must be orthogonal in meaning. Two axes that are
near-synonyms (e.g.
serviceandapplication_nameif the team maps them identically) produce redundant budgets without analytical value. - Cardinality per axis matters for observability. Tag cardinality explosion is its own failure mode — see concepts/per-pattern-tag-cardinality and patterns/dynamic-cardinality-reduction-by-tag-collapse. Each axis should have bounded, operator-meaningful values (avoid free-text user_id, request_id as budget-keying axes).
- Axis-writer layers must not fight. Middleware that
overwrites another middleware's tag value destroys the
compositional property. Canonical convention: read-modify-
write — each middleware calls
tagsFromContext, adds its key, callscontextWithTagswith the merged map.
Seen in¶
- sources/2026-04-21-planetscale-patterns-for-postgres-traffic-control — canonical wiki introduction. Josh Brown canonicalises five orthogonal axes (service / route / deployment / tier / workload), the AND-composition rule-engine semantics, and the "layered policies without complicated rule logic" framing.
Related¶
- concepts/sqlcommenter-query-tagging
- concepts/context-propagated-sql-tags
- concepts/query-priority-classification
- patterns/workload-class-resource-budget
- patterns/route-tagged-query-isolation
- patterns/tier-tagged-query-isolation
- patterns/dedicated-application-name-per-workload
- patterns/context-threaded-sql-tag-propagation
- systems/planetscale-traffic-control