PATTERN Cited by 1 source
Enforcement throttler proxy¶
Pattern¶
Put the throttler in the query path — as a proxy, or embedded in an existing one — so it can actively delay or reject database requests rather than asking the client to respect an advisory answer. The throttler becomes a barrier, not an adviser. Clients cannot bypass it and may not even be aware of its existence.
Canonical instance: systems/vitess-transaction-throttler.
"An alternative throttling enforcement design puts the throttler between the client and the system. The throttler runs as a proxy, or integrates with an existing proxy, to be able to throttle client requests. Such is the Vitess transaction throttler, which can actively delay database query execution when system performance degrades. Clients cannot bypass the throttler, and may not even be aware of its existence."
— Shlomi Noach, Source: sources/2026-04-21-planetscale-anatomy-of-a-throttler-part-3
Why enforcement¶
The collaborative check-API model has a structural hole: clients that don't consult the throttler can inflict the exact load the throttler was installed to prevent.
"A rogue client might neglect to connect to the throttler and just go ahead and send some massive workload."
The cooperative model can defend itself via client identity logging + audits, but cannot prevent the harm in real time. An enforcement throttler can — it physically sits between the client and the database.
Shape¶
Two deployment shapes:
1. Standalone proxy¶
A dedicated hop between clients and the database.
The proxy inspects every query, consults system health metrics, and delays, rejects, or passes each one.
2. Embedded in existing proxy¶
The throttler is a module inside an already-present proxy (VTGate/VTTablet in Vitess, PgBouncer plugin in Postgres, etc.). Canonical case: Vitess's transaction throttler lives inside VTTablet's query-execution path.
Enforcement action is typically delay, not outright rejection: the query holds in a queue until system metrics drop below threshold, then executes. This gives callers back-pressure in the form of latency instead of errors.
Costs and trade-offs¶
1. Client-identification inference¶
The most-cited cost:
"As such, it's more complicated to identify the clients, and the throttler must rely on domain-specific attributes made available by the client/connection/query to be able to distinguish between clients and implement any needed prioritization."
A cooperative throttler gets identity for free — the client says who it is. An enforcement throttler sees a query and has to infer the client. Available signals:
- SQL comments (SQLCommenter-style tags)
- Session variables / connection attributes
- Auth scope / service identity / upstream tags
- Query shape (bulk write vs point lookup)
- Connection source (replica vs primary)
None are perfect; several are easily spoofable by clients.
2. Always in path¶
Unlike the cooperative model where the throttler is an out-of-band endpoint, the barrier is load-bearing for every query. Its availability is a hard dependency; its per-query latency overhead directly adds to end-to-end latency.
3. Less helpful in regular client workloads¶
For cooperative batch tools (gh-ost, online DDL, VDiff)
the enforcement shape is overkill — you already trust these
clients. Enforcement pays off specifically for OLTP traffic
from unmodified application code you can't audit.
Composition with cooperative throttling¶
The two shapes are complementary, not exclusive. Vitess deploys both:
- Cooperative tablet throttler for internal batch subsystems (VReplication, VDiff, online DDL) — rich client identity, cheap per-check, easy to tune.
- Enforcement transaction throttler for OLTP traffic — active delay on unmodified application queries, no cooperation required.
The cooperative throttler protects against "well-behaved background jobs doing too much good work"; the enforcement throttler protects against "production traffic becoming a rogue client in aggregate under overload."
Relationship to connection-pool admission¶
An enforcement throttler is structurally a query-level admission control. It composes with but is orthogonal to:
- Connection-pool saturation (concepts/connection-pool-exhaustion) — admission at the connection level.
- Rate-limit proxies — admission at the request level with no awareness of system health.
Only the enforcement throttler gates by system-health metrics at query grain.
Failure modes¶
- Throttler latency becomes workload latency. The pattern exchanges rejection errors for latency; both feed back into application behaviour.
- Queue buildup under sustained overload. If metrics stay above threshold, queued queries accumulate. Needs a max-queue-age / bounded-queue policy.
- Identity spoofing. Clients who learn that SQL comments affect throttler behaviour can game them. Mix connection-level identity (harder to spoof) with query-level.
- Downstream unawareness. Clients that expect "immediate connection refused on overload" may timeout differently when overload instead manifests as slow responses.
Seen in¶
- sources/2026-04-21-planetscale-anatomy-of-a-throttler-part-3 — canonical wiki introduction. Shlomi Noach names the enforcement shape as the answer to the rogue-client structural hole in the cooperative model, introduces Vitess's transaction throttler as the canonical instance, and calls out the client-identification inference cost.
Related¶
- concepts/database-throttler
- concepts/throttler-client-identity
- concepts/throttler-client-starvation
- patterns/collaborative-throttler-check-api
- patterns/probabilistic-rejection-prioritization
- patterns/deprioritize-all-except-target
- systems/vitess-transaction-throttler
- systems/vitess-throttler
- systems/vitess