Skip to content

perf: reduce clock reads per request from 9 to 3 - #2016

Merged
jkaczman merged 1 commit into
mainfrom
jk-request-clock-reads
Nov 13, 2026
Merged

jkaczman merged 1 commit into
mainfrom
jk-request-clock-reads

Conversation

@jkaczman

Copy link
Copy Markdown
Contributor

Previously, we read the clock 9 times per request (there were a couple other ones that I missed in #1890 from not looking at the flamegraph).

Now we read it 3 times (+ tokio's): once at the start of the request, once for the checkout timeout in Pool::get, and once in Server::read on ReadyForQuery

Stats, new request and all of our timers reuse prior ones now.

Removes ~650 instructions and ~2.4% of user cycles per transaction in pooler bench

@jkaczman
jkaczman added this pull request to stack #2012 November 11, 2026 18:02
Comment thread pgdog/src/backend/server.rs Outdated
self.statement_executed
}

pub(crate) fn take_last_ready_for_query(&mut self) -> Option<Instant> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd rename it to something more self-documenting, maybe take_last_query_exec_time?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, maybe we could make it pub(in crate::backend) to make sure someone doesn't accidentally use it incorrectly? Not sure what kind of side effect it would have; previously, all server timings were self-contained, so an outside caller couldn't break them.

@levkk

levkk commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

A case can be made here to fork Tokio to add a once-per-runtime-tick Instant cache. Might help with code legibility. Not a blocker obviously (forking Tokio is a full time job), but something to consider in the future maybe.

@jkaczman
jkaczman removed this pull request from stack #2012 November 13, 2026 18:11
@jkaczman
jkaczman added this pull request to stack #2032 November 13, 2026 18:13
@jkaczman
jkaczman force-pushed the jk-request-clock-reads branch from 16690d0 to aaa70f6 Compare November 13, 2026 18:20
@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.89922% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pgdog/src/frontend/client/mod.rs 82.35% 3 Missing ⚠️
pgdog/src/frontend/client/query_engine/query.rs 91.66% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@jkaczman
jkaczman force-pushed the jk-request-clock-reads branch 4 times, most recently from cd2d929 to 7b25c8f Compare November 13, 2026 18:46
Base automatically changed from jk-shrink-moves to main November 13, 2026 18:54
@jkaczman
jkaczman force-pushed the jk-request-clock-reads branch from 7b25c8f to 51ea109 Compare November 13, 2026 18:59
@jkaczman
jkaczman merged commit 9ba9caf into main Nov 13, 2026
45 of 47 checks passed
@jkaczman
jkaczman deleted the jk-request-clock-reads branch November 13, 2026 19:07
@github-actions

Copy link
Copy Markdown
Contributor

Metal bench (x86) failed. 46 of 517 measures outside bounds.

suite throughput cpu/txn user cycles/txn user instr/txn kernel cycles/txn kernel instr/txn ctx/txn
pooler 25.98 (-0.4% ± 0.2%) 19,196 (-0.9% ± 0.1%) 32,924 (-2.0% ± 0.1%) 33,320 (-0.4% ± 0.4%) 36,454 (+0.1% ± 0.4%)
lb 26.42 (-0.4% ± 0.07%) 19,768 (-0.8% ± 0.2%) 33,895 (-1.9% ± 0.07%) 33,532 (-0.2% ± 0.6%) 37,258 (+0.2% ± 0.3%)
sharding-w2 42.05 (-0.1% ± 1.9%) 47,414 (-0.1% ± 1.9%) 98,511 (-0.4% ± 0.01%) 38,202 (-0.2% ± 2.9%) 40,174 (-0.0% ± 0.3%) 1.529 (-0.0% ± 0.8%)
sharding-w8 207,264 (-0.2% ± 0.5%) 32.97 (+0.3% ± 0.4%) 46,405 (+0.4% ± 1.0%) 52,830 (-0.7% ± 0.02%) 31,013 (+0.1% ± 0.2%) 32,464 (+0.0% ± 0.2%) 0.1699 (-0.6% ± 0.6%)
Counters per txn
suite frontend stall l1i refill backend stall
pooler 4,038 (+2.7% ± 0.5%) 1,205 (-2.4% ± 0.8%) 36,637 (-2.6% ± 0.7%)
lb 4,249 (+4.5% ± 0.5%) 1,255 (-0.5% ± 0.7%) 37,227 (-3.6% ± 0.3%)
sharding-w2 7,270 (+12.6% ± 0.9%) 1,564 (+1.6% ± 1.2%) 110,617 (-4.6% ± 4.3%)
sharding-w8 4,958 (+28.9% ± 1.6%) 912 (-3.1% ± 0.8%) 170,334 (-3.0% ± 1.9%)
benchmark measure result baseline change bound
extended_cached::aggregate instructions 17,562 17,308 +1.47% ± 0.00% +1%
extended_cached::begin instructions 6,178 5,924 +4.29% ± 0.00% +1%
extended_cached::cte instructions 23,847 23,593 +1.08% ± 0.00% +1%
extended_cached::delete_all_shards instructions 8,959 8,705 +2.92% ± 0.00% +1%
extended_cached::delete_by_key instructions 12,232 11,978 +2.12% ± 0.00% +1%
extended_cached::distinct instructions 13,604 13,350 +1.90% ± 0.00% +1%
extended_cached::group_by instructions 17,149 16,895 +1.50% ± 0.00% +1%
extended_cached::having instructions 19,011 18,757 +1.35% ± 0.00% +1%
extended_cached::having_distinct_limit instructions 23,148 22,894 +1.11% ± 0.00% +1%
extended_cached::insert instructions 12,427 12,173 +2.09% ± 0.00% +1%
extended_cached::insert_returning instructions 13,386 13,132 +1.93% ± 0.00% +1%
extended_cached::lookup instructions 18,138 17,884 +1.42% ± 0.00% +1%
extended_cached::min_max_sum instructions 20,528 20,280 +1.22% ± 0.00% +1%
extended_cached::order_limit_offset instructions 16,455 16,201 +1.57% ± 0.00% +1%
extended_cached::select_all_shards instructions 13,099 12,845 +1.98% ± 0.00% +1%
extended_cached::select_by_key instructions 16,432 16,178 +1.57% ± 0.00% +1%
extended_cached::select_in_list instructions 21,455 21,201 +1.20% ± 0.00% +1%
extended_cached::select_omni instructions 10,606 10,352 +2.45% ± 0.00% +1%
extended_cached::set instructions 6,849 6,595 +3.85% ± 0.00% +1%
extended_cached::subquery instructions 18,630 18,376 +1.38% ± 0.00% +1%
extended_cached::update_all_shards instructions 10,350 10,096 +2.52% ± 0.00% +1%
extended_cached::update_by_key instructions 13,543 13,287 +1.93% ± 0.00% +1%
extended_cold::aggregate instructions 57,431 56,737 +1.22% ± 0.00% +1%
extended_cold::begin instructions 10,373 10,119 +2.51% ± 0.00% +1%
extended_cold::delete_all_shards instructions 16,020 15,766 +1.61% ± 0.00% +1%
extended_cold::delete_by_key instructions 22,836 22,584 +1.12% ± 0.00% +1%
extended_cold::select_all_shards instructions 23,799 23,545 +1.08% ± 0.00% +1%
extended_cold::select_by_key instructions 30,968 30,268 +2.31% ± 0.00% +1%
extended_cold::select_omni instructions 21,031 20,777 +1.22% ± 0.00% +1%
extended_cold::update_all_shards instructions 21,011 20,757 +1.22% ± 0.00% +1%
extended_evicting::begin instructions 11,154 10,900 +2.33% ± 0.00% +1%
extended_evicting::cte instructions 49,103 48,571 +1.10% ± 0.00% +1%
extended_evicting::delete_all_shards instructions 16,840 16,586 +1.53% ± 0.00% +1%
extended_evicting::delete_by_key instructions 23,724 23,470 +1.08% ± 0.00% +1%
extended_evicting::select_all_shards instructions 24,659 24,405 +1.04% ± 0.00% +1%
extended_evicting::select_omni instructions 21,891 21,637 +1.17% ± 0.00% +1%
extended_evicting::set instructions 15,295 14,764 +3.60% ± 0.00% +1%
extended_evicting::update_all_shards instructions 21,871 21,617 +1.18% ± 0.00% +1%
simple_cold::begin instructions 9,510 9,256 +2.74% ± 0.00% +1%
simple_cold::delete_all_shards instructions 15,213 14,959 +1.70% ± 0.00% +1%

Microbench: 458 of 504 measures within bounds. See verdict.json for the rest.

  • extended_cached: 24 of 24 benches slower, median +1.6% ± 0.0%
Microbench latency: 3 benches changed more than 3%
benchmark latency baseline change instructions change
extended_cached::having_distinct_limit 3,484 ns 3,311 ns +5.24% ± 0.38% +1.11% ± 0.00%
extended_cached::select_in_list 3,272 ns 3,162 ns +3.47% ± 0.45% +1.20% ± 0.00%
extended_cached::order_limit_offset 2,705 ns 2,621 ns +3.22% ± 0.47% +1.57% ± 0.00%
Hot code per txn
path base head change
pooler 114.7 KB 114.9 KB +0.2 KB
sharding-w2 168.3 KB 168.1 KB -0.2 KB

pooler:

crate base head change
pgdog::frontend::client::query_engine 21.5 KB 21.8 KB +0.3 KB
pgdog::backend::pool 18.4 KB 18.6 KB +0.2 KB
tokio 18.4 KB 18.4 KB +0.0 KB
pgdog::frontend (other) 8.9 KB 9.2 KB +0.4 KB
aws-lc (TLS crypto) 9.1 KB 8.6 KB -0.4 KB
rustls (TLS) 7.6 KB 8.0 KB +0.4 KB
pgdog::backend::server 7.3 KB 7.4 KB +0.1 KB
other 6.1 KB 5.8 KB -0.4 KB
everything else 17.3 KB 17.1 KB -0.2 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 7.2 KB +0.2 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 6.3 KB +0.1 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 4.9 KB -0.1 KB
tokio::runtime::task::raw::poll 3.8 KB +0.1 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 3.3 KB +0.2 KB

sharding-w2:

crate base head change
pgdog::frontend::router 28.7 KB 28.5 KB -0.2 KB
pgdog::frontend::client::query_engine 22.8 KB 22.8 KB +0.0 KB
pgdog::backend::pool 19.1 KB 19.1 KB +0.0 KB
tokio 18.7 KB 18.4 KB -0.3 KB
pgdog::frontend (other) 10.6 KB 10.8 KB +0.2 KB
other 10.7 KB 10.4 KB -0.2 KB
aws-lc (TLS crypto) 10.4 KB 10.3 KB -0.1 KB
pgdog::backend::server 7.9 KB 8.1 KB +0.2 KB
everything else 39.5 KB 39.7 KB +0.2 KB
function head change
pgdog::frontend::client::Client::run::{{closure}} 8.4 KB +0.1 KB
pgdog::frontend::client::query_engine::query::<impl pgdog::frontend::client::query_engine: 6.2 KB +0.1 KB
pgdog::frontend::client::query_engine::QueryEngine::handle::{{closure}} 4.4 KB -0.3 KB
pgdog::frontend::router::parser::query::select::<impl pgdog::frontend::router::parser::que 4.2 KB +0.1 KB
tokio::runtime::task::raw::poll 3.9 KB -0.1 KB
lb flamegraph vs 2c54eb8

lb

Open interactive for hover, zoom and search.

lb removed

Open interactive.

microbench flamegraph vs 2c54eb8

microbench

Open interactive for hover, zoom and search.

microbench removed

Open interactive.

pooler flamegraph vs 2c54eb8

pooler

Open interactive for hover, zoom and search.

pooler removed

Open interactive.

sharding-w2 flamegraph vs 2c54eb8

sharding-w2

Open interactive for hover, zoom and search.

sharding-w2 removed

Open interactive.

sharding-w8 flamegraph vs 2c54eb8

sharding-w8

Open interactive for hover, zoom and search.

sharding-w8 removed

Open interactive.

Logs

lb, microbench, pooler, sharding-w2, sharding-w8, verdict.json

Compared 35ed39a with 2c54eb8 on c7i.metal-48xl (on-demand).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants