1 of 19

Beyond Execution Hooks

Designing Low-Overhead Telemetry and Diagnostic Architectures

Speaker : Kanishk Verma

2 of 19

Agenda

00:00 - 03:00

The Hook Paradigm: Power and Ubiquity

06:00 - 12:00

The Anti-Pattern: Inline Processing & Network I/O (With simple use case)

12:00 - 17:00

Simple on demand signal and poll architecture.

17:00 - 23:00

Custom Signals and Interrupts

23:00 - 27:00

Case study: pg_query_state

27:00 - 30:00

Summary & Takeaways

3 of 19

What is a hook?

The Definition

In Postgres, a "hook" is fundamentally a global function pointer found in the core server code (e.g., src/backend/executor/execMain.c).

Execution Logic

Postgres checks if the pointer is set. If null, it runs the standard function. If set, it redirects to the custom function registered by the extension.

Lifecycle Stages

Parsing

Planning

Exec Start

Exec Run

Exec End

warning

Crucial Detail: Synchronous Execution

Execution runs inline within the backend process handling the client connection. If your hook takes time, the client blocks.

4 of 19

The Hook Paradigm: Power and Ubiquity

  • Standard Hooks: (e.g., ExecutorEnd_hook, ProcessUtility_hook) allowing extensions to hijack execution.

The Success Pattern:

  • Purely CPU-bound operations.
  • Ultra-low memory footprints.
  • Pre-allocated shared memory structures.

5 of 19

Hook Chaining Internals & "Broken Chains"

Registration & Setup

// Global pointer to previous hook

static ExecutorRun_hook_type prev_ExecutorRun = NULL;

void _PG_init(void) {

/* Save the next step in the chain */

prev_ExecutorRun = ExecutorRun_hook;

/* Insert our custom hook at the head */

ExecutorRun_hook = my_custom_ExecutorRun;

}

Execution Logic

static void my_custom_ExecutorRun(...) {

// 1. Pre-execution logic (CPU bound only!)

...

// 2. Call next link in chain

if (prev_ExecutorRun)

prev_ExecutorRun(...);

else

standard_ExecutorRun(...);

// 3. Post-execution logic

...

}

6 of 19

The Anti-Pattern: Inline Processing & Network I/O

dangerous

Real-World Use Case: Telemetry to Remote Store

How to send the telemetry data such as the query execution time or the query statistics to the remote store such as Spanner or BigQuery or Another DataStore.

7 of 19

Operationalizing Telemetry: Design Solution

settings_input_component

Solution 1: Integrated Inline Telemetry

Implementation of a network call for telemetry directly within the inline hook to persist metrics to highly available datastores.

  • Target Datastore: Spanner or BigQuery or Another DataStore.
  • Hook Placement: Inline within execution lifecycle

warning

Note: Inline processing introduces network I/O latency hazards.

Direct network calls in hooks can cause 100x query latency spikes.

8 of 19

9 of 19

Mathematical Proof of Connection Exhaustion

Scenario A: Baseline

Latency: 0.1 ms

10,000 QPS

Max throughput per connection

Scenario B: 10ms Inline Block

Latency: 10.1 ms

~99 QPS

Max throughput per connection

With a max_connections pool of 100, the total system capacity suffers a catastrophic drop:

1,000,000 QPS -> 9,900 QPS

warning

Result: Denial of Service (DoS)

Connection pool exhaustion occurs. Clients timeout, backends saturate, and the database becomes unavailable.

10 of 19

Solution 2: Asymmetric Offloading

Instead of sending metrics over the network inline, the backend process writes metrics into a shared memory segment.

Specific Implementation

Ring Buffer

Ensures high-performance write operations without the overhead of traditional locking mechanisms.

11 of 19

12 of 19

What happens when the system is under extreme load and the Background-worker is too slow?

1. Data Store Slow

The remote log data store slows down, causing the Background Worker (BGW) to block on network write calls.

2. High Qps

Client queries execute quickly, writing metrics to shared memory. The write pointer catches up to the BGW read pointer.

priority_high

The Critical Decision

The system must choose between two suboptimal outcomes:

  • Block query execution (Direct impact on user latency)
  • Lose telemetry records (Data loss for monitoring/billing)

Solution : Lossy Drop (Load-Shedding)

  • Effect : Incomplete metrics, but database stays online

13 of 19

Solution 2.1: On-Demand Diagnostics

Beyond Telemetry Logging: Solving for Interactive Diagnostics

The Challenge

A query is stuck (e.g., running for 10 minutes), and you need to identify the specific join node causing the delay.

Why existing methods fail:

  • Background logging pools are too heavy.
  • Logging every node transition creates gigabytes of memory overhead.
  • You only need diagnostics for this specific query, right now.

The Requirement

Inspect execution state on-demand

Zero Overhead Goal:

Eliminate performance penalties when diagnostics are not actively being performed.

"We need a way to inspect the execution state of an active backend on-demand, without paying any overhead when we aren't looking."

14 of 19

Custom Signals and Interrupts Architecture

15 of 19

Let’s understand the real world example of pg_query_state But what is it?

The pg_query_state module provides facility to know the current state of query execution on working backend.

To enable this extension, you have to patch the stable version of PostgreSQL, recompile it, and deploy new binaries. All patch files are located in the patches/ directory.

Key Use Cases

  • Detect long-running queries (along with other monitoring tools)
  • Overwatch query execution in real-time

Note: Extension requires patching stable PostgreSQL versions based on the specific version number suffix.

16 of 19

17 of 19

Production case study :

pg_query_state

18 of 19

Summary & Takeaways

  • Do Not Block the Executor: Hooks must stay lightweight and CPU-bound.
  • Correct datastructures and locks : Ring buffer in asymmetric offloading.
  • Isolate I/O in BG Workers: Keep disk and network out of the query execution path.
  • Prioritize the Database: Always drop telemetry before stalling query backends.

19 of 19

References and further Readings

  1. https://github.com/postgres/postgres/blob/master/contrib/auto_explain/auto_explain.c
  2. https://www.postgresql.org/docs/current/pgstatstatements.html
  3. https://github.com/postgrespro/pg_query_state/blob/master/pg_query_state.c
  4. https://medium.com/@kanishk_verma/optimizing-active-query-plan-tracking-from-53-degradation-to-1-overhead-c7ec32e93583