Skip to content

ci(bench): measure the incremental benchmark as a production bundle - #2379

Merged
KyleAMathews merged 2 commits into
mainfrom
bench/production-build
Nov 9, 2026
Merged

KyleAMathews merged 2 commits into
mainfrom
bench/production-build

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

🎯 Changes

The incremental update benchmark now measures TanStack DB as a production app runs it. Before this change, the benchmark imported db's source through tsx. It therefore measured development-mode code that every production build removes: process.env.NODE_ENV checks, development-only branches, and private members without their mangled names.

  • A new runner, scripts/bench/production.mjs, bundles a benchmark with esbuild against the built dist of db and db-ivm. The bundle is minified, and process.env.NODE_ENV is set to production. These are the settings that the size scenarios in scripts/size-compare.mjs use.
  • The runner refuses a dist that is older than its package's sources. It also fails if the bundle includes any module from a package's src, so a benchmark cannot measure a development copy of a package beside its dist.
  • The bundle has an inline source map. A failed assertion in the benchmark names its line in incremental-update.ts.
  • The benchmark keeps its import of db's source entry for its types. The runner redirects that import to the built entry, so the root tsc run does not change.
  • CI builds db-ivm and db on both sides, then runs the bundle. This adds about 7 seconds to each side. The base side takes the runner and its freshness check from the PR head, so both sides run the same benchmark code.
  • The README states what the benchmark measures. It also states that the 2026-11-05 runner-variation data came from source-mode runs.

The maintainer asked for this change on 2026-11-09. The trigger was #2378: it flagged 5 writes in 100-row configurations. Those writes ran development-only state probes that a production bundle removes.

Verification

  • The bundle's inputs are 118 files from packages/db/dist and 28 files from packages/db-ivm/dist. It has no inputs from src, and the output contains no NODE_ENV reads.
  • A short run of the bundled benchmark completes with all cases.
  • With a second import of db's source added to the benchmark, the runner fails and names the source files. Before this check, that run completed with two copies of db in the bundle.
  • With an error thrown at the top of the benchmark, the stack trace names scripts/bench/incremental-update.ts:1:7.
  • node --test scripts/bench/inputs-changed.test.mjs scripts/bench/compare-incremental-update.test.mjs: 22 of 22 pass.
  • One source-mode run and one production run on the same machine: the production writes had a geometric mean of 0.90× and cold hydration 0.97×. This is one run of each, so it shows only the direction.

Limits

  • Node servers that load db from node_modules without a bundler run code that this benchmark does not measure.
  • The CI gate thresholds were calibrated on source-mode runs. Production-bundle runs on CI have no separate calibration yet.

✅ Checklist

  • I have tested this code locally with pnpm test. I ran the benchmark's own tests and the bundled benchmark.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

This pull request and its description were written by Isaac.

Summary by CodeRabbit

  • Chores
    • Benchmark workflows now build both packages and run measurements using production bundles. Base and candidate runs use the same benchmark scripts and freshness checks.
    • Runs require fresh package builds and support passing arguments to the benchmark.
  • Documentation
    • Updated benchmark instructions to cover the production runner and clarify how development-mode timings differ from production measurements.

The benchmark imported db's source through tsx, so it measured
development-mode code: unmangled private members, NODE_ENV checks and
development-only branches that every production app strips. A new
runner, scripts/bench/production.mjs, bundles the benchmark against the
built db and db-ivm dist with esbuild, minified, with
process.env.NODE_ENV set to production, as the size scenarios do. It
refuses a dist older than its package's sources. CI builds both
packages on each side and runs the bundle.

Co-authored-by: Isaac <no-reply@databricks.com>
@changeset-bot

changeset-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: df5a78a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The benchmark runner now checks built package freshness, bundles the benchmark in production mode, and executes it. The workflow uses the runner for candidate and base benchmarks. The README documents the runner and clarifies the mode used for previously cited CI timings.

Changes: Production benchmark execution

Layer / File(s) Summary
Bundle and run benchmark
scripts/bench/production.mjs
The runner checks package distribution freshness, bundles the benchmark as minified Node ESM with production mode and built-package aliases, rejects bundles containing package source modules, and imports the bundle with forwarded arguments.
Workflow and documentation integration
.github/workflows/benchmark.yml, scripts/bench/README.md
The candidate and base runs build both packages and use the runner. The README describes the production bundle and states that cited CI timings measured development-mode source.

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Other

Sequence Diagram(s)

sequenceDiagram
  participant BenchmarkWorkflow
  participant ProductionRunner
  participant Esbuild
  participant BuiltPackages
  participant BenchmarkBundle
  BenchmarkWorkflow->>ProductionRunner: pass benchmark path and arguments
  ProductionRunner->>BuiltPackages: check distribution freshness
  ProductionRunner->>Esbuild: bundle with production settings and package aliases
  Esbuild->>BuiltPackages: resolve db and db-ivm imports
  Esbuild->>BenchmarkBundle: write minified Node ESM bundle
  ProductionRunner->>BenchmarkBundle: import bundle with forwarded arguments
Loading

Possibly related PRs

  • TanStack/db#2356: Changes the same benchmark and CI workflow with a nested workload, repeated reports, and regression gating.
  • TanStack/db#2171: Changes the transaction settlement contract and updates the incremental benchmark to observe settlement.

Suggested reviewers: kevin-dp

Merge Risk: Minimal · up to df5a7

The benchmark now uses built production bundles. No concrete merge-blocking risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description follows the repository template. It has the Changes, Oracle Coverage, Checklist, and Release Impact sections. The Changes section states what changed and why: the benchmark now measure… Complete the "Oracle Coverage" section. For a non-bug change without a practical oracle, name the relevant coverage-map entry and explain why the owner cannot be extended, no independent oracle can be built, and no receiving witness can be …
Passed Passed checks: 4 passed

Check name Status Explanation
Title check Passed The title "ci(bench): measure the incremental benchmark as a production bundle" matches the main change. The PR adds scripts/bench/production.mjs, which bundles the benchmark against built dist output…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "ci(bench): measure the incremental benchmark as a production bundle" matches the main change. The PR adds scripts/bench/production.mjs, which bundles the benchmark against built dist output with minification and NODE_ENV=production, and the CI workflow now runs that bundle. The title is short, specific, and uses a conventional commit prefix.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 1 files. (1 skipped: 1 unsupported.)

Full details: Description check

Explanation

The description follows the repository template. It has the Changes, Oracle Coverage, Checklist, and Release Impact sections. The Changes section states what changed and why: the benchmark now measures a production bundle, not development-mode source imported through tsx. It lists the new runner, the freshness and source-inclusion guards, the CI changes with their cost, and the README update. The author also gives verification evidence and limits. The Oracle Coverage section is not filled in. It does not name a coverage-map owner or summarize oracle evidence, and it does not explain why no practical oracle exists. This section applies to behavior changes, so the gap is significant. The template asks for different content depending on whether the change is a bug fix or a non-bug change. The description also leaves the changeset checkbox unchecked and checks the docs/CI/dev-only box, which is consistent with the stated release impact.

Resolution

Complete the "Oracle Coverage" section. For a non-bug change without a practical oracle, name the relevant coverage-map entry and explain why the owner cannot be extended, no independent oracle can be built, and no receiving witness can be added. Also confirm that the maintainer-requested benchmark change has no observable behavior change that needs oracle evidence. If it has none, state that explicitly so the reviewer can verify it.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f869f7ba-f4ab-4226-93eb-198554587e02
Commits

Reviewing files that changed from the base of the PR and between 7e1f6d4 and df5a78a.

Files selected for processing: 2

  • .github/workflows/benchmark.yml
  • scripts/bench/production.mjs

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 199 kB

ℹ️ View Unchanged
Filename Size
packages/db/dist/esm/_virtual/_rolldown/runtime.js 190 B
packages/db/dist/esm/client.js 4.98 kB
packages/db/dist/esm/collection-options-brand.js 215 B
packages/db/dist/esm/collection-options.js 248 B
packages/db/dist/esm/collection/change-events.js 1.64 kB
packages/db/dist/esm/collection/changes.js 2.15 kB
packages/db/dist/esm/collection/cleanup-queue.js 698 B
packages/db/dist/esm/collection/config-errors.js 561 B
packages/db/dist/esm/collection/events.js 441 B
packages/db/dist/esm/collection/health-tree.js 679 B
packages/db/dist/esm/collection/index.js 2.6 kB
packages/db/dist/esm/collection/indexes.js 1.9 kB
packages/db/dist/esm/collection/lifecycle.js 3.59 kB
packages/db/dist/esm/collection/mutations.js 2.29 kB
packages/db/dist/esm/collection/state.js 5.28 kB
packages/db/dist/esm/collection/subscription.js 6.26 kB
packages/db/dist/esm/collection/sync.js 4.94 kB
packages/db/dist/esm/collection/validate-config.js 1.11 kB
packages/db/dist/esm/collection/validate-indexing.js 371 B
packages/db/dist/esm/deferred.js 205 B
packages/db/dist/esm/error-message.js 627 B
packages/db/dist/esm/errors.js 7.14 kB
packages/db/dist/esm/event-emitter.js 698 B
packages/db/dist/esm/index.js 4.68 kB
packages/db/dist/esm/indexed-db-wrapper.js 1.71 kB
packages/db/dist/esm/indexed-db.js 3.55 kB
packages/db/dist/esm/indexes/auto-index.js 890 B
packages/db/dist/esm/indexes/base-index.js 1.69 kB
packages/db/dist/esm/indexes/basic-index.js 1.64 kB
packages/db/dist/esm/indexes/btree-index.js 1.57 kB
packages/db/dist/esm/indexes/index-registry.js 909 B
packages/db/dist/esm/indexes/reverse-index.js 635 B
packages/db/dist/esm/live-query-adapter.js 950 B
packages/db/dist/esm/live-query-observer-client.js 2.14 kB
packages/db/dist/esm/live-query-observer.js 2.84 kB
packages/db/dist/esm/live-query-options.js 2.4 kB
packages/db/dist/esm/live-query-primitives.js 401 B
packages/db/dist/esm/live-query-window-binding.js 1.5 kB
packages/db/dist/esm/live-query-window-controller.js 3.88 kB
packages/db/dist/esm/local-only.js 814 B
packages/db/dist/esm/local-storage.js 3.95 kB
packages/db/dist/esm/optimistic-action.js 320 B
packages/db/dist/esm/paced-mutations.js 1.07 kB
packages/db/dist/esm/proxy.js 3.07 kB
packages/db/dist/esm/query/builder/clone-query.js 845 B
packages/db/dist/esm/query/builder/functions.js 1.52 kB
packages/db/dist/esm/query/builder/group-keys.js 162 B
packages/db/dist/esm/query/builder/include-functions.js 222 B
packages/db/dist/esm/query/builder/index.js 4.83 kB
packages/db/dist/esm/query/builder/query-ir.js 318 B
packages/db/dist/esm/query/builder/ref-proxy-identity.js 284 B
packages/db/dist/esm/query/builder/ref-proxy.js 1.57 kB
packages/db/dist/esm/query/builder/wrapper-identity.js 212 B
packages/db/dist/esm/query/compiler/evaluators.js 2.33 kB
packages/db/dist/esm/query/compiler/expressions.js 582 B
packages/db/dist/esm/query/compiler/find-aggregate.js 313 B
packages/db/dist/esm/query/compiler/group-by.js 3.75 kB
packages/db/dist/esm/query/compiler/grouping.js 163 B
packages/db/dist/esm/query/compiler/index.js 8.85 kB
packages/db/dist/esm/query/compiler/joins.js 3 kB
packages/db/dist/esm/query/compiler/lazy-targets.js 1.05 kB
packages/db/dist/esm/query/compiler/order-by.js 2.55 kB
packages/db/dist/esm/query/compiler/parent-routes.js 313 B
packages/db/dist/esm/query/compiler/query-equivalence.js 554 B
packages/db/dist/esm/query/compiler/route-metadata.js 1.26 kB
packages/db/dist/esm/query/compiler/select.js 1.57 kB
packages/db/dist/esm/query/effect.js 4.42 kB
packages/db/dist/esm/query/equality-conjunct.js 483 B
packages/db/dist/esm/query/equality-value-identity.js 729 B
packages/db/dist/esm/query/expression-helpers.js 1.52 kB
packages/db/dist/esm/query/ir-stable-identity.js 3.71 kB
packages/db/dist/esm/query/ir.js 2.21 kB
packages/db/dist/esm/query/join-conditions.js 254 B
packages/db/dist/esm/query/live-query-collection.js 383 B
packages/db/dist/esm/query/live/bucket-facade-adapter.js 2.73 kB
packages/db/dist/esm/query/live/collection-config-builder.js 6.72 kB
packages/db/dist/esm/query/live/collection-registry.js 259 B
packages/db/dist/esm/query/live/collection-subscriber.js 2.25 kB
packages/db/dist/esm/query/live/graph-scheduler.js 300 B
packages/db/dist/esm/query/live/includes-runtime.js 213 B
packages/db/dist/esm/query/live/internal.js 142 B
packages/db/dist/esm/query/live/materialized-pipeline.js 2.17 kB
packages/db/dist/esm/query/live/ordered-source-loader.js 4.71 kB
packages/db/dist/esm/query/live/public-key-reduction.js 931 B
packages/db/dist/esm/query/live/subset-demand-controller.js 2.01 kB
packages/db/dist/esm/query/live/utils.js 1.35 kB
packages/db/dist/esm/query/optimizer.js 2.7 kB
packages/db/dist/esm/query/pooled-live-query.js 4.2 kB
packages/db/dist/esm/query/pooled-source.js 210 B
packages/db/dist/esm/query/query-once.js 317 B
packages/db/dist/esm/query/runtime-reference-identity.js 621 B
packages/db/dist/esm/query/subset-dedupe.js 489 B
packages/db/dist/esm/query/validate-limit.js 250 B
packages/db/dist/esm/scheduler.js 942 B
packages/db/dist/esm/SortedMap.js 861 B
packages/db/dist/esm/strategies/commit-completion.js 152 B
packages/db/dist/esm/strategies/debounceStrategy.js 625 B
packages/db/dist/esm/strategies/queueStrategy.js 470 B
packages/db/dist/esm/strategies/serial-pacer.js 457 B
packages/db/dist/esm/strategies/throttleStrategy.js 695 B
packages/db/dist/esm/sync-persistence.js 648 B
packages/db/dist/esm/sync-receipt.js 210 B
packages/db/dist/esm/transaction-commit-work.js 345 B
packages/db/dist/esm/transactions.js 2.58 kB
packages/db/dist/esm/utils.js 1.7 kB
packages/db/dist/esm/utils/array-utils.js 265 B
packages/db/dist/esm/utils/browser-polyfills.js 268 B
packages/db/dist/esm/utils/btree.js 1.66 kB
packages/db/dist/esm/utils/callbacks.js 209 B
packages/db/dist/esm/utils/comparison.js 1.88 kB
packages/db/dist/esm/utils/cursor.js 752 B
packages/db/dist/esm/utils/error.js 267 B
packages/db/dist/esm/utils/get-or-create.js 154 B
packages/db/dist/esm/utils/index-optimization.js 2.08 kB
packages/db/dist/esm/utils/source-record.js 141 B
packages/db/dist/esm/utils/type-guards.js 221 B
packages/db/dist/esm/utils/uuid.js 534 B
packages/db/dist/esm/virtual-props.js 383 B
packages/react-db/dist/esm/DbProvider.js 319 B
packages/react-db/dist/esm/development.js 200 B
packages/react-db/dist/esm/HydrationBoundary.js 273 B
packages/react-db/dist/esm/index.js 314 B
packages/react-db/dist/esm/source-id-bindings.js 335 B
packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.3 kB
packages/react-db/dist/esm/useLiveQuery.js 2.54 kB
packages/react-db/dist/esm/useLiveQueryEffect.js 510 B
packages/react-db/dist/esm/useLiveSuspenseQuery.js 1.87 kB
packages/react-db/dist/esm/usePacedMutations.js 374 B

compressed-size-action::db-and-react-package-size

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Incremental update benchmark

Comparing 8ebff4e74 (this PR) against c6a85dc0c (base). Write times are per-write medians over 100 iterations (20 warmup writes). Timings use the median of 3 fresh fixture repetition(s).

Overall median write time vs base: 1.08× · cold hydrate time: 1.06× (geometric mean of per-case ratios; lower is faster).

Writes: 1 regression(s), 0 improvement(s) (threshold: ±20% and >0.05ms).

Cold hydrate: 0 regression(s), 1 improvement(s) (threshold: ±50% and >5ms).

CI regression gate: PASS. Query geometric means: >+30% writes or >+50% cold. A case also fails when every repetition exceeds the entire base range by >+50% and the metric's absolute floor.

Per-case flags are noisy on shared runners. Read the geometric means first.

Writes

Query Δ median write time (geomean) Best case Worst case Flags
list: newest 50 open +2.4% -38.5% +57.6% —
list + author +10.3% -0.1% +55.0% —
list + comment count +10.3% -3.4% +30.6% —
list + 3 recent comments +5.9% -2.8% +26.1% —
issue detail + comments +6.0% -11.3% +67.1% —
open issues + documents +21.2% -2.8% +113.4% 1 🔴

Cold hydrate

Query Δ cold hydrate time (geomean) Best case Worst case Flags
list: newest 50 open +6.0% -30.8% +56.6% —
list + author -5.0% -78.9% +69.2% 1 🟢
list + comment count +14.6% -22.5% +168.4% —
list + 3 recent comments -0.8% -35.5% +16.6% —
issue detail + comments +13.7% -5.5% +39.2% —
open issues + documents +11.6% -4.7% +40.6% —

Each row aggregates that query's scale/index/write-mode configurations; per-configuration tables below.

100 rows/collection | source indexes: none | synced writes — geomean 1.35×, cold 1.24×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.048ms 0.076ms +57.6% 0.147ms 0.165ms +12.5% 2.839ms 3.500ms +23.3%
list: newest 50 open 0.102ms 0.104ms +1.6% 0.245ms 0.275ms +12.2% 0.643ms 1.008ms +56.6%
list + author 0.068ms 0.105ms +55.0% 0.129ms 0.146ms +13.7% 2.976ms 4.240ms +42.5%
list + comment count 0.104ms 0.122ms +16.9% 0.221ms 0.266ms +20.6% 3.527ms 2.732ms -22.5%
list + 3 recent comments 0.064ms 0.075ms +17.1% 0.141ms 0.157ms +10.8% 3.318ms 3.870ms +16.6%
issue detail + comments 0.041ms 0.046ms +13.7% 0.105ms 0.095ms -9.8% 0.411ms 0.526ms +28.1%
open issues + documents 0.031ms 0.065ms +113.4% 0.056ms 0.106ms +88.7% 1.413ms 1.986ms +40.6%
100 rows/collection | source indexes: none | optimistic writes — geomean 1.24×, cold 1.03×, 1 change(s)
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.053ms 0.053ms +0.7% 0.099ms 0.110ms +11.0% 1.028ms 0.876ms -14.8%
list: newest 50 open 0.017ms 0.019ms +7.5% 0.031ms 0.056ms +79.9% 0.544ms 0.572ms +5.3%
list + author 0.036ms 0.039ms +8.8% 0.065ms 0.091ms +39.8% 1.466ms 2.481ms +69.2%
list + comment count 0.063ms 0.073ms +15.5% 0.147ms 0.138ms -5.8% 1.755ms 1.964ms +11.9%
list + 3 recent comments 0.035ms 0.037ms +5.6% 0.071ms 0.085ms +19.9% 4.041ms 2.607ms -35.5%
issue detail + comments 0.030ms 0.051ms +67.1% 0.063ms 0.068ms +8.8% 0.308ms 0.358ms +16.3%
open issues + documents 0.220ms 0.416ms +89.7% 0.409ms 0.596ms +45.8% 🔴 1.101ms 1.049ms -4.7%
100 rows/collection | source indexes: manual | synced writes — geomean 0.97×, cold 1.11×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.050ms 0.031ms -38.5% 0.083ms 0.058ms -29.2% 0.960ms 1.152ms +20.0%
list: newest 50 open 0.089ms 0.097ms +9.1% 0.210ms 0.198ms -5.8% 0.533ms 0.571ms +7.1%
list + author 0.034ms 0.036ms +5.1% 0.066ms 0.077ms +15.8% 1.339ms 1.200ms -10.3%
list + comment count 0.068ms 0.072ms +7.1% 0.137ms 0.141ms +3.2% 1.320ms 1.550ms +17.4%
list + 3 recent comments 0.045ms 0.046ms +2.7% 0.057ms 0.060ms +6.1% 1.972ms 2.127ms +7.9%
issue detail + comments 0.037ms 0.033ms -11.3% 0.067ms 0.044ms -35.0% 0.276ms 0.359ms +29.7%
open issues + documents 0.047ms 0.055ms +18.9% 0.059ms 0.100ms +67.7% 1.379ms 1.543ms +11.9%
100 rows/collection | source indexes: manual | optimistic writes — geomean 1.15×, cold 1.22×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.027ms 0.032ms +17.2% 0.054ms 0.077ms +41.1% 0.433ms 0.670ms +54.7%
list: newest 50 open 0.031ms 0.025ms -20.6% 0.040ms 0.049ms +22.7% 0.601ms 0.530ms -11.7%
list + author 0.035ms 0.047ms +34.8% 0.054ms 0.063ms +18.2% 0.968ms 1.270ms +31.2%
list + comment count 0.062ms 0.081ms +30.6% 0.091ms 0.104ms +15.1% 1.463ms 1.903ms +30.0%
list + 3 recent comments 0.037ms 0.047ms +26.1% 0.078ms 0.094ms +20.0% 2.068ms 2.252ms +8.9%
issue detail + comments 0.029ms 0.034ms +14.8% 0.040ms 0.071ms +79.9% 0.213ms 0.276ms +29.6%
open issues + documents 0.202ms 0.231ms +13.9% 0.220ms 0.261ms +18.8% 0.841ms 1.022ms +21.5%
1,000 rows/collection | source indexes: none | synced writes — geomean 1.04×, cold 1.07×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.021ms 0.022ms +7.1% 0.022ms 0.040ms +81.4% 3.275ms 3.808ms +16.3%
list: newest 50 open 0.434ms 0.453ms +4.4% 0.512ms 0.528ms +3.1% 3.350ms 4.002ms +19.5%
list + author 0.030ms 0.032ms +4.5% 0.040ms 0.040ms +1.6% 9.784ms 10.661ms +9.0%
list + comment count 0.064ms 0.068ms +6.2% 0.079ms 0.135ms +71.5% 4.193ms 4.775ms +13.9%
list + 3 recent comments 0.041ms 0.043ms +3.5% 0.052ms 0.052ms +0.5% 6.039ms 4.792ms -20.6%
issue detail + comments 0.033ms 0.033ms -0.4% 0.056ms 0.065ms +17.6% 0.461ms 0.514ms +11.6%
open issues + documents 0.028ms 0.029ms +2.8% 0.033ms 0.036ms +11.4% 6.930ms 7.287ms +5.1%
1,000 rows/collection | source indexes: none | optimistic writes — geomean 1.07×, cold 1.13×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.025ms 0.026ms +7.6% 0.032ms 0.037ms +15.4% 2.800ms 3.047ms +8.8%
list: newest 50 open 0.024ms 0.021ms -11.0% 0.030ms 0.026ms -16.0% 2.739ms 2.984ms +9.0%
list + author 0.033ms 0.038ms +13.7% 0.041ms 0.052ms +28.4% 9.445ms 10.270ms +8.7%
list + comment count 0.055ms 0.065ms +18.6% 0.084ms 0.128ms +52.0% 5.064ms 4.946ms -2.3%
list + 3 recent comments 0.031ms 0.035ms +12.4% 0.042ms 0.065ms +53.7% 4.216ms 4.851ms +15.1%
issue detail + comments 0.027ms 0.028ms +5.5% 0.038ms 0.055ms +45.4% 0.422ms 0.587ms +39.2%
open issues + documents 0.220ms 0.233ms +5.9% 0.322ms 0.272ms -15.5% 6.272ms 7.356ms +17.3%
1,000 rows/collection | source indexes: manual | synced writes — geomean 1.03×, cold 1.24×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.022ms 0.023ms +3.8% 0.026ms 0.032ms +23.2% 0.469ms 0.537ms +14.5%
list: newest 50 open 0.098ms 0.107ms +9.2% 0.134ms 0.200ms +49.6% 0.448ms 0.493ms +10.1%
list + author 0.030ms 0.031ms +2.6% 0.034ms 0.035ms +2.5% 0.942ms 1.014ms +7.6%
list + comment count 0.068ms 0.070ms +1.9% 0.082ms 0.093ms +13.9% 1.552ms 4.167ms +168.4%
list + 3 recent comments 0.045ms 0.046ms +3.9% 0.060ms 0.056ms -5.3% 1.698ms 1.854ms +9.2%
issue detail + comments 0.032ms 0.032ms -0.7% 0.037ms 0.038ms +3.6% 0.244ms 0.264ms +8.2%
open issues + documents 0.028ms 0.029ms +3.7% 0.032ms 0.036ms +15.3% 7.339ms 7.735ms +5.4%
1,000 rows/collection | source indexes: manual | optimistic writes — geomean 1.06×, cold 1.08×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.024ms 0.026ms +5.0% 0.029ms 0.032ms +9.1% 0.489ms 0.506ms +3.6%
list: newest 50 open 0.019ms 0.020ms +9.5% 0.027ms 0.030ms +13.9% 0.525ms 0.552ms +5.1%
list + author 0.034ms 0.035ms +3.4% 0.047ms 0.053ms +14.0% 0.966ms 1.067ms +10.5%
list + comment count 0.061ms 0.065ms +6.7% 0.084ms 0.088ms +4.5% 1.483ms 1.635ms +10.3%
list + 3 recent comments 0.035ms 0.039ms +9.7% 0.047ms 0.050ms +7.4% 1.877ms 2.004ms +6.8%
issue detail + comments 0.029ms 0.031ms +5.5% 0.059ms 0.048ms -19.2% 0.230ms 0.280ms +21.5%
open issues + documents 0.223ms 0.230ms +3.4% 0.241ms 0.258ms +7.3% 6.333ms 6.211ms -1.9%
10,000 rows/collection | source indexes: none | synced writes — geomean 0.99×, cold 1.03×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.022ms 0.022ms -0.6% 0.042ms 0.025ms -40.3% 38.629ms 37.533ms -2.8%
list: newest 50 open 4.301ms 4.652ms +8.1% 4.945ms 5.241ms +6.0% 37.255ms 39.186ms +5.2%
list + author 0.033ms 0.033ms +0.8% 0.039ms 0.040ms +2.3% 116.263ms 122.026ms +5.0%
list + comment count 0.066ms 0.063ms -3.4% 0.085ms 0.079ms -7.4% 45.434ms 47.590ms +4.7%
list + 3 recent comments 0.043ms 0.042ms -2.8% 0.061ms 0.052ms -14.8% 38.031ms 43.164ms +13.5%
issue detail + comments 0.032ms 0.031ms -2.9% 0.045ms 0.037ms -16.8% 3.001ms 2.902ms -3.3%
open issues + documents 0.030ms 0.029ms -2.8% 0.038ms 0.045ms +19.2% 79.301ms 80.197ms +1.1%
10,000 rows/collection | source indexes: none | optimistic writes — geomean 1.03×, cold 0.98×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.027ms 0.028ms +2.3% 0.055ms 0.050ms -9.4% 38.569ms 38.317ms -0.7%
list: newest 50 open 0.017ms 0.020ms +15.3% 0.030ms 0.034ms +12.1% 41.072ms 38.225ms -6.9%
list + author 0.036ms 0.037ms +3.7% 0.047ms 0.055ms +16.5% 113.979ms 117.699ms +3.3%
list + comment count 0.070ms 0.072ms +3.4% 0.101ms 0.099ms -1.4% 42.584ms 41.068ms -3.6%
list + 3 recent comments 0.033ms 0.033ms -0.6% 0.042ms 0.050ms +18.4% 42.861ms 41.046ms -4.2%
issue detail + comments 0.030ms 0.029ms -2.3% 0.037ms 0.038ms +2.2% 3.053ms 2.885ms -5.5%
open issues + documents 0.223ms 0.224ms +0.7% 0.262ms 0.246ms -6.2% 75.909ms 77.922ms +2.7%
10,000 rows/collection | source indexes: manual | synced writes — geomean 1.05×, cold 0.80×, 1 change(s)
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.025ms 0.022ms -8.8% 0.027ms 0.027ms +0.5% 1.369ms 1.261ms -7.9%
list: newest 50 open 0.528ms 0.515ms -2.4% 0.869ms 0.835ms -4.0% 1.187ms 1.119ms -5.8%
list + author 0.033ms 0.034ms +3.2% 0.041ms 0.039ms -3.7% 9.151ms 1.934ms -78.9% 🟢
list + comment count 0.073ms 0.073ms +0.2% 0.089ms 0.151ms +68.2% 2.409ms 2.482ms +3.0%
list + 3 recent comments 0.049ms 0.048ms -1.6% 0.081ms 0.065ms -20.0% 2.735ms 2.506ms -8.4%
issue detail + comments 0.034ms 0.034ms -0.1% 0.042ms 0.040ms -5.3% 0.537ms 0.525ms -2.1%
open issues + documents 0.028ms 0.045ms +59.9% 0.035ms 0.059ms +70.5% 76.350ms 90.551ms +18.6%
10,000 rows/collection | source indexes: manual | optimistic writes — geomean 1.04×, cold 0.93×
Query Base median PR median Δ median Base p95 PR p95 Δ p95 Base cold PR cold Δ cold
list: newest 50 open 0.026ms 0.026ms +1.5% 0.047ms 0.038ms -20.2% 1.678ms 1.162ms -30.8%
list: newest 50 open 0.020ms 0.020ms +1.5% 0.038ms 0.023ms -38.9% 1.096ms 1.150ms +5.0%
list + author 0.035ms 0.035ms -0.1% 0.061ms 0.040ms -33.6% 2.830ms 1.667ms -41.1%
list + comment count 0.076ms 0.095ms +25.3% 0.111ms 0.174ms +56.8% 2.139ms 2.426ms +13.4%
list + 3 recent comments 0.037ms 0.036ms -1.5% 0.048ms 0.047ms -0.8% 2.389ms 2.313ms -3.2%
issue detail + comments 0.032ms 0.032ms -0.4% 0.037ms 0.057ms +55.0% 0.478ms 0.489ms +2.2%
open issues + documents 0.219ms 0.220ms +0.6% 0.274ms 0.268ms -2.2% 78.607ms 102.190ms +30.0%

Runner: node v24.8.0, linux 7.0.0-1017-azure, AMD EPYC 9V45 96-Core Processor. Timings on shared CI runners are noisy; treat small deltas as indicative only.

@pkg-pr-new

pkg-pr-new Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@2379

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@2379

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@2379

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@2379

@tanstack/convex-db-collection

npm i https://pkg.pr.new/@tanstack/convex-db-collection@2379

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@2379

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@2379

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@2379

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@2379

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@2379

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@2379

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@2379

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@2379

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@2379

@tanstack/preact-db

npm i https://pkg.pr.new/@tanstack/preact-db@2379

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@2379

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@2379

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@2379

@tanstack/react-router-with-db

npm i https://pkg.pr.new/@tanstack/react-router-with-db@2379

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@2379

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@2379

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@2379

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@2379

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@2379

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@2379

commit: df5a78a

Review fixes for the production benchmark runner:

- The runner fails when esbuild's metafile lists any packages/*/src
  input. Before, a second import of db source bundled a development
  copy of db beside its dist without notice (a planted import of
  packages/db/src/collection/index.js ran to exit 0; it now fails and
  names the source files).
- The bundle carries an inline source map, and the runner enables
  source maps before it imports the bundle, so a failed assertion names
  its line in incremental-update.ts. The bundle directory uses the real
  temp path, because macOS's /var symlink offset the map's relative
  paths.
- Both freshness checks run before the bundle directory is created.
- The base step also takes the freshness helper from the PR head, so
  both sides run the same runner code.

Co-authored-by: Isaac <no-reply@databricks.com>
@KyleAMathews
KyleAMathews merged commit 3f48c2f into main Nov 9, 2026
26 checks passed
@KyleAMathews
KyleAMathews deleted the bench/production-build branch November 9, 2026 16:02
KyleAMathews pushed a commit that referenced this pull request Nov 9, 2026
…ade #2374)

Conflicts resolved as the standing rule says: main's tooling, with this
branch's oracle changes reapplied.

- package.json, packages/db/package.json: main's dependency versions,
  plus the @tanstack/oracles and @tanstack/eslint-plugin-oracles
  previews. fast-check stays at ^4.10.2 here and in
  db-adapter-conformance.
- packages/db-ivm/vite.config.ts: main's publishableModuleOutput build
  output, plus the stripOracleProbes() plugin.
- electric-sdk-delivery-oracle: main's resume-checkpoint check and
  model, plus this branch's owns entry.
- solid-db row-materialization-oracle: main's keyed visibility
  histories, plus this branch's case route.
- pnpm-lock.yaml: resolved from the public registry by a temporary CI
  job (run 42653737079, which also checked a frozen install), because
  the local registry proxy does not yet carry #2374's versions.

Co-authored-by: Isaac <no-reply@databricks.com>
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.

1 participant