Skip to content

feat(zbugs): swap to whereScalar for zbugs filters#5529

Closed
tantaman wants to merge 5 commits intomainfrom
mlaw/debug
Closed

feat(zbugs): swap to whereScalar for zbugs filters#5529
tantaman wants to merge 5 commits intomainfrom
mlaw/debug

Conversation

@tantaman
Copy link
Contributor

@tantaman tantaman commented Feb 6, 2026

Make zbugs queries performant for terabugs by using whereScalar

This allows:

  1. eliminating some joins (on label, on project, on user)
  2. providing the planner with distribution information as we bind specific label ids.

Planner gets more accurate counts based on label ids resolved from label names.

- Attempt 1 (flip=01): outer flipped join scans 832 issueLabel[bug] rows
- Attempt 3 (flip=11): outer flipped join scans 960 issueLabel[software] rows 

Contains other fixes (to be split out):

  1. consumes the companion pipelines
  2. transforms scalar subqueries that cannot be inlined to exists before hitting the plan phase
  3. unqiue index on issueLabel(projectID, name)
  4. adds whereScalar

You can review the commits in order to see each fix.

@vercel
Copy link

vercel bot commented Feb 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
replicache-docs Ready Ready Preview, Comment Feb 9, 2026 3:32pm
zbugs Ready Ready Preview, Comment Feb 9, 2026 3:32pm

Request Review

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

🐰 Bencher Report

Branchmlaw/debug
TestbedLinux
Click to view all benchmark results
BenchmarkFile SizeBenchmark Result
kilobytes (KB)
(Result Δ%)
Upper Boundary
kilobytes (KB)
(Limit %)
zero-package.tgz📈 view plot
🚷 view threshold
1,856.22 KB
(+0.03%)Baseline: 1,855.58 KB
1,892.70 KB
(98.07%)
zero.js📈 view plot
🚷 view threshold
246.57 KB
(+0.16%)Baseline: 246.18 KB
251.10 KB
(98.20%)
zero.js.br📈 view plot
🚷 view threshold
67.42 KB
(+0.12%)Baseline: 67.34 KB
68.68 KB
(98.16%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

🐰 Bencher Report

Branchmlaw/debug
Testbedself-hosted
Click to view all benchmark results
BenchmarkThroughputBenchmark Result
operations / second (ops/s)
(Result Δ%)
Lower Boundary
operations / second (ops/s)
(Limit %)
1 exists: track.exists(album)📈 view plot
🚷 view threshold
13,507.57 ops/s
(-1.69%)Baseline: 13,739.65 ops/s
10,854.25 ops/s
(80.36%)
10 exists (AND)📈 view plot
🚷 view threshold
196,120.25 ops/s
(-2.29%)Baseline: 200,714.16 ops/s
156,049.80 ops/s
(79.57%)
10 exists (OR)📈 view plot
🚷 view threshold
3,751.74 ops/s
(-4.91%)Baseline: 3,945.27 ops/s
3,183.77 ops/s
(84.86%)
12 exists (AND)📈 view plot
🚷 view threshold
174,451.16 ops/s
(-1.73%)Baseline: 177,522.36 ops/s
136,261.18 ops/s
(78.11%)
12 exists (OR)📈 view plot
🚷 view threshold
3,113.99 ops/s
(-6.81%)Baseline: 3,341.41 ops/s
2,685.80 ops/s
(86.25%)
12 level nesting📈 view plot
🚷 view threshold
2,749.67 ops/s
(-5.14%)Baseline: 2,898.68 ops/s
2,278.73 ops/s
(82.87%)
2 exists (AND): track.exists(album).exists(genre)📈 view plot
🚷 view threshold
5,032.04 ops/s
(-2.53%)Baseline: 5,162.62 ops/s
4,144.47 ops/s
(82.36%)
3 exists (AND)📈 view plot
🚷 view threshold
1,979.65 ops/s
(-1.77%)Baseline: 2,015.39 ops/s
1,630.23 ops/s
(82.35%)
3 exists (OR)📈 view plot
🚷 view threshold
968.26 ops/s
(-3.72%)Baseline: 1,005.64 ops/s
806.30 ops/s
(83.27%)
5 exists (AND)📈 view plot
🚷 view threshold
307.72 ops/s
(-2.94%)Baseline: 317.04 ops/s
253.63 ops/s
(82.42%)
5 exists (OR)📈 view plot
🚷 view threshold
160.11 ops/s
(-3.97%)Baseline: 166.72 ops/s
131.19 ops/s
(81.93%)
Nested 2 levels: track > album > artist📈 view plot
🚷 view threshold
4,363.94 ops/s
(-2.54%)Baseline: 4,477.77 ops/s
3,521.91 ops/s
(80.70%)
Nested 4 levels: playlist > tracks > album > artist📈 view plot
🚷 view threshold
699.90 ops/s
(-4.76%)Baseline: 734.89 ops/s
585.78 ops/s
(83.70%)
Nested with filters: track > album > artist (filtered)📈 view plot
🚷 view threshold
3,617.67 ops/s
(-3.44%)Baseline: 3,746.70 ops/s
3,021.47 ops/s
(83.52%)
planned: playlist.exists(tracks)📈 view plot
🚷 view threshold
556.94 ops/s
(-8.95%)Baseline: 611.70 ops/s
504.34 ops/s
(90.56%)
planned: track.exists(album) OR exists(genre)📈 view plot
🚷 view threshold
165.25 ops/s
(+1.25%)Baseline: 163.21 ops/s
140.30 ops/s
(84.90%)
planned: track.exists(album) where title="Big Ones"📈 view plot
🚷 view threshold
7,528.39 ops/s
(+0.70%)Baseline: 7,475.88 ops/s
6,305.22 ops/s
(83.75%)
planned: track.exists(album).exists(genre)📈 view plot
🚷 view threshold
36.61 ops/s
(-6.17%)Baseline: 39.02 ops/s
32.47 ops/s
(88.68%)
planned: track.exists(album).exists(genre) with filters📈 view plot
🚷 view threshold
5,133.50 ops/s
(-2.42%)Baseline: 5,260.63 ops/s
4,343.35 ops/s
(84.61%)
planned: track.exists(playlists)📈 view plot
🚷 view threshold
3.74 ops/s
(-5.23%)Baseline: 3.94 ops/s
3.23 ops/s
(86.45%)
unplanned: playlist.exists(tracks)📈 view plot
🚷 view threshold
561.03 ops/s
(-6.05%)Baseline: 597.18 ops/s
489.77 ops/s
(87.30%)
unplanned: track.exists(album) OR exists(genre)📈 view plot
🚷 view threshold
42.56 ops/s
(-4.24%)Baseline: 44.44 ops/s
36.28 ops/s
(85.25%)
unplanned: track.exists(album) where title="Big Ones"📈 view plot
🚷 view threshold
52.07 ops/s
(-6.32%)Baseline: 55.59 ops/s
45.89 ops/s
(88.13%)
unplanned: track.exists(album).exists(genre)📈 view plot
🚷 view threshold
37.28 ops/s
(-3.76%)Baseline: 38.74 ops/s
32.10 ops/s
(86.10%)
unplanned: track.exists(album).exists(genre) with filters📈 view plot
🚷 view threshold
51.02 ops/s
(-6.23%)Baseline: 54.40 ops/s
45.01 ops/s
(88.23%)
unplanned: track.exists(playlists)📈 view plot
🚷 view threshold
3.77 ops/s
(-4.06%)Baseline: 3.93 ops/s
3.24 ops/s
(85.81%)
zpg: all playlists📈 view plot
🚷 view threshold
5.23 ops/s
(-5.64%)Baseline: 5.54 ops/s
4.81 ops/s
(91.97%)
zql: all playlists📈 view plot
🚷 view threshold
7.29 ops/s
(-3.44%)Baseline: 7.55 ops/s
5.82 ops/s
(79.88%)
zql: edit for limited query, inside the bound📈 view plot
🚷 view threshold
199,955.15 ops/s
(-4.93%)Baseline: 210,318.45 ops/s
172,419.95 ops/s
(86.23%)
zql: edit for limited query, outside the bound📈 view plot
🚷 view threshold
211,415.66 ops/s
(-1.63%)Baseline: 214,913.29 ops/s
169,804.12 ops/s
(80.32%)
zql: push into limited query, inside the bound📈 view plot
🚷 view threshold
103,081.44 ops/s
(-3.74%)Baseline: 107,085.55 ops/s
88,318.46 ops/s
(85.68%)
zql: push into limited query, outside the bound📈 view plot
🚷 view threshold
375,171.33 ops/s
(-5.33%)Baseline: 396,284.28 ops/s
296,887.81 ops/s
(79.13%)
zql: push into unlimited query📈 view plot
🚷 view threshold
312,012.08 ops/s
(-3.33%)Baseline: 322,772.63 ops/s
248,707.90 ops/s
(79.71%)
zqlite: all playlists📈 view plot
🚷 view threshold
1.69 ops/s
(-2.93%)Baseline: 1.74 ops/s
1.36 ops/s
(80.40%)
zqlite: edit for limited query, inside the bound📈 view plot
🚷 view threshold
75,165.84 ops/s
(-0.73%)Baseline: 75,722.40 ops/s
61,571.75 ops/s
(81.91%)
zqlite: edit for limited query, outside the bound📈 view plot
🚷 view threshold
74,863.61 ops/s
(-0.18%)Baseline: 75,001.84 ops/s
55,921.80 ops/s
(74.70%)
zqlite: push into limited query, inside the bound📈 view plot
🚷 view threshold
3,771.79 ops/s
(-5.60%)Baseline: 3,995.74 ops/s
3,544.77 ops/s
(93.98%)
zqlite: push into limited query, outside the bound📈 view plot
🚷 view threshold
84,412.25 ops/s
(-3.27%)Baseline: 87,268.83 ops/s
71,430.47 ops/s
(84.62%)
zqlite: push into unlimited query📈 view plot
🚷 view threshold
121,951.68 ops/s
(-0.27%)Baseline: 122,283.21 ops/s
95,193.39 ops/s
(78.06%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

🐰 Bencher Report

Branchmlaw/debug
Testbedself-hosted
Click to view all benchmark results
BenchmarkThroughputBenchmark Result
operations / second (ops/s) x 1e3
(Result Δ%)
Lower Boundary
operations / second (ops/s) x 1e3
(Limit %)
src/client/custom.bench.ts > big schema📈 view plot
🚷 view threshold
132.90 ops/s x 1e3
(-2.87%)Baseline: 136.82 ops/s x 1e3
113.62 ops/s x 1e3
(85.50%)
src/client/zero.bench.ts > basics > All 1000 rows x 10 columns (numbers)📈 view plot
🚷 view threshold
2.36 ops/s x 1e3
(-3.17%)Baseline: 2.43 ops/s x 1e3
2.03 ops/s x 1e3
(86.03%)
src/client/zero.bench.ts > pk compare > pk = N📈 view plot
🚷 view threshold
61.63 ops/s x 1e3
(-1.87%)Baseline: 62.80 ops/s x 1e3
50.49 ops/s x 1e3
(81.92%)
src/client/zero.bench.ts > with filter > Lower rows 500 x 10 columns (numbers)📈 view plot
🚷 view threshold
3.73 ops/s x 1e3
(-0.52%)Baseline: 3.75 ops/s x 1e3
3.19 ops/s x 1e3
(85.52%)
🐰 View full continuous benchmarking report in Bencher

tantaman and others added 5 commits February 9, 2026 10:31
…nner

Move scalar subquery rewriting from buildPipelineInternal (per-node) to
buildPipeline (top-level), making it recursive through the full AST
including related subqueries and correlated subquery conditions. Also
update resolve-scalar-subqueries to recurse into correlated subquery
conditions so nested scalar subqueries are properly resolved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add experimental whereScalar() to the Query interface and implementation.
This provides a convenience method for scalar subquery conditions using
relationship definitions, complementing the lower-level cmp+scalar API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace label_name_idx with a unique composite index on (projectID, name)
to support scalar subquery resolution for label lookups by project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace first() with a full stream consumption loop to avoid triggering
early return on Take's #initialFetch assertion. The subquery AST already
has limit: 1, so at most one row is produced.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add issueLabels and label relationships to the schema and update queries
to use whereScalar instead of whereExists for project filtering, creator/
assignee lookups, and label filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@grgbkr
Copy link
Contributor

grgbkr commented Feb 19, 2026

Landed here:
d231cdd
and here:
1734c7c

@grgbkr grgbkr closed this Feb 19, 2026
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

Comments