PATTERN Cited by 1 source
Hook colocation for zero overhead¶
Pattern¶
When a new capability requires the same hook points and similar measurements to an existing extension that already installs those hooks, merge the new capability into the existing extension rather than shipping a second extension that installs the same hook.
The optimisation: each hook invocation traverses a chain of all installed extensions, and each extension that performs measurement (e.g. timing the query, counting I/O) pays that measurement cost. Loading two extensions that both hook ExecutorRun and both measure query resource consumption doubles both costs. Colocating the logic in one extension pays once.
Canonical instance¶
From sources/2026-04-21-planetscale-behind-the-scenes-how-database-traffic-control-works:
"When we first started planning for Traffic Control, we knew we would use a Postgres extension with a hook on ExecutorRun to decide whether or not each statement would be allowed to run. Initially, we wrote a new extension for this. We soon realized that there are two ways to choose which queries to block: based on static analysis of the individual query, or based on cumulative measurements of resource usage over time. We split the extension along those lines. Blocking based on static analysis got merged into the project that became pg_strict. Blocking based on cumulative resource usage became Traffic Control. It turns out Traffic Control needed the same hook points and much of the same information that pginsights already had. So rather than duplicate all that code and impose the extra runtime overhead of another extension, we taught pginsights how to block queries."
What was merged¶
| Component | Before | After |
|---|---|---|
pginsights |
Passive telemetry extension — hooks ExecutorRun and ProcessUtility, times queries, reports aggregates |
Adds blocking capability using the same hook entries and same measurements |
| Traffic Control | Planned as separate extension hooking ExecutorRun independently |
Lives inside pginsights; shares hook entry and measurement code |
pg_strict |
(none — was the other half of the original single Traffic Control plan) | Separate extension for static-analysis blocking (different concern, no shared measurement) |
What stayed separate¶
Static-analysis blocking (pg_strict) was not colocated with pginsights because its decision logic doesn't share data with the telemetry pipeline — it analyses the parsed SQL statement itself, not runtime resource consumption. Colocation pays off when the new capability shares both hook points and measurements; when only hook points are shared (and measurements differ), colocation is a weaker win.
When to apply¶
- New capability needs the same hook points as an existing extension. ✅
- New capability needs the same runtime measurements the existing extension already computes. ✅
- Merging does not significantly complicate the existing extension's semantics or dependencies. ✅
- Operators already run the existing extension (so colocation doesn't force adoption of an unrelated feature). ✅
When not to apply¶
- Capabilities that gate on fundamentally different inputs (e.g. static analysis vs. runtime cost). Split instead.
- Capabilities with orthogonal release cadences or ownership. A combined extension couples their release engineering.
- Operators who need to run one capability but not the other. Colocation forces the merged feature surface on everyone.
Trade-offs¶
- Pro: zero extra hook-chain cost. The existing hook invocation absorbs the new logic.
- Pro: zero extra measurement cost. The existing extension already computes the numbers.
- Pro: coherent operator model. One extension to install, one GUC namespace, one shared-memory segment.
- Con: scope creep. The existing extension becomes less focused; each new merged capability raises the complexity bar.
- Con: coupled failure modes. A bug in the new capability can destabilise the existing capability's users.
- Con: coupled upgrade. Users who want only the old capability must take the new one too.