perf(relay): bounded-concurrency multi-filter query execution (S2)#1457
Merged
Conversation
…nded concurrency (S2)
NIP-01 multi-filter requests previously awaited db.query_events once per
filter, serially — a K-filter POST /query paid K sequential DB round trips
(the structural cost behind get_channels' N last-message filters and any
batched client query). Both loops now run three phases:
1. pure query construction + validation, in filter order
2. DB reads via futures buffered(FILTER_QUERY_CONCURRENCY=4) —
order-preserving bounded concurrency
3. post-processing, strictly in original filter order
Because buffered() yields in input order, phase 3 is byte-identical to the
old serial loop: NIP-01 OR/dedupe order (seen_ids insertion = filter order),
per-event access gates (event_in_accessible_channel, filters_match,
reader_authorized_for_event, author-only), conformance trace row order, and
first-error semantics are all unchanged. Special-pass filters (feed_types,
depth_limit, search) are handled in earlier loops and untouched; per-filter
LIMITs unchanged.
One deliberate edge shift, bridge only: before_id validation (400) for a
later filter now surfaces before any earlier filter's DB query executes —
deterministic client errors now always precede transient DB errors.
New tests: filter_query_pipeline_preserves_filter_order (proves ordered
yield when the first filter is slowest) and a concurrency-bound guard.
cargo test -p buzz-relay: 453 passed, 0 failed.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
… assert CI clippy runs --all-targets -D warnings, which lints test code and rejects assertions_on_constants. The compile-time const assert at the definition site is stronger anyway: violating the FILTER_QUERY_CONCURRENCY range now fails every build, not just a test run. Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
tlongwell-block
pushed a commit
that referenced
this pull request
Jul 2, 2026
* origin/main: perf(relay): bounded-concurrency multi-filter query execution (S2) (#1457)
tlongwell-block
pushed a commit
that referenced
this pull request
Jul 2, 2026
* origin/main: perf(relay): bounded-concurrency multi-filter query execution (S2) (#1457) Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
wpfleger96
added a commit
that referenced
this pull request
Jul 2, 2026
…into HEAD * origin/paul/nip-am-agent-turn-metrics: fix(profile): consolidate agent profile runtime metadata (#1451) fix(desktop): simplify workspace rail badges (#1462) perf(desktop): instant channel switching — non-blocking first paint, persisted snapshots (#1452) perf(relay): bounded-concurrency multi-filter query execution (S2) (#1457) fix(desktop): classify timeline prepends so history loads don't bump unread (#1416) fix(desktop): quiet gate for workspace switches instead of boot splash (#1449) fix(read-path): reach complete threads, dense-second timelines, and all people in the GUI (#1418) E1+E3: reduce relay ingest/fan-out DB round trips; ack p99 −7–16%, fd p99 −6–28%, p999 tails −29–53% vs PR #1453 tip (#1454) perf(relay): defer post-commit dispatch and avoid verify clone (#1453) fix(relay): include git hook tools in runtime image (#1326) feat(chart): per-pod emptyDir git scratch when persistence disabled (multi-replica HA) (#1450) fix(relay): remove media bearer-token auth (#1444) fix(desktop): stop search shortcut from hijacking the sidebar (#1447) Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Follow-up S2 reserved by #1452's follow-up list; sequenced after #1418 (merged,
7da936ff). Part of the buzz-gui-performance arc.NIP-01 multi-filter requests (
POST /querycatch-all pass inapi/bridge.rs, WS REQ historical delivery inhandlers/req.rs) executed onedb.query_eventsawait per filter, serially. A K-filter request paid K sequential DB round trips — the structural cost behindget_channels' N per-channel last-message filters and any client-side request batching (which otherwise only saves HTTP RTT + NIP-98/auth tax, not DB time).Design
Both loops split into three phases:
before_id400,pageoffsets all decided here).db.query_eventsviafutures_utilbuffered(FILTER_QUERY_CONCURRENCY = 4)— bounded, order-preserving concurrency.Because
buffered(notbuffer_unordered) yields in input order, phase 3 is byte-identical to the old serial loop:seen_idsinsertion order = filter order; an event failing filter A stays eligible for filter B.event_in_accessible_channel,filters_match,reader_authorized_for_event, author-only.One deliberate edge shift (bridge only):
before_idvalidation (400) for a later filter now surfaces before any earlier filter's DB query runs — deterministic client errors now always precede transient DB errors. No caller depends on the old interleaving (validation errors were already request-fatal).Why N=4: bounded well below the pool ceiling so one multi-filter request can't monopolise Postgres connections; a guard test pins the range so raising it forces a bench re-run.
Verification
cargo test -p buzz-relay: 453 passed, 0 failed (whole package, not scoped).filter_query_pipeline_preserves_filter_order: proves ordered yield when the first filter is the slowest (the case wherebuffer_unorderedwould break dedupe order).filter_query_concurrency_is_boundedguard.cargo fmt+ clippy clean; pre-commit/pre-push hook suites green.Not in this PR (deliberate)
The dedicated
DISTINCT ON (channel_id)last-message query forget_channelsstep 5 — separate follow-up diff so each change carries its own correctness argument. S2 helps every multi-filter query; DISTINCT ON kills the worst single call site.