Skip to content

docs(bench): design plan for SQLRite vs SQLite benchmark suite (SQLR-4)#101

Merged
joaoh82 merged 1 commit into
mainfrom
bench-plan-sqlr-4
May 6, 2026
Merged

docs(bench): design plan for SQLRite vs SQLite benchmark suite (SQLR-4)#101
joaoh82 merged 1 commit into
mainfrom
bench-plan-sqlr-4

Conversation

@joaoh82

@joaoh82 joaoh82 commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Drafts docs/benchmarks-plan.md — design proposal for the long-standing "Benchmarks against SQLite" item from the Possible extras list. Mirrors the shape of phase-7-plan.md / phase-8-plan.md: goals, scope philosophy, viability call per comparator, workloads table, methodology, repo layout, sub-phases, open questions, risks.
  • Wires it into docs/_index.md "Future work" and replaces the bare line in roadmap.md "Possible extras" with a richer entry that points at the plan + records the viability outcomes.
  • Docs-only — no engine code.

Comparison-target viability (the call)

  • SQLite — mandatory baseline via rusqlite; tuned to journal_mode=WAL + synchronous=NORMAL for apples-to-apples vs SQLRite's mandatory WAL.
  • DuckDB — analytical-slice only (Group B workloads), opt-in via --features duckdb. Different storage model (columnar OLAP); included to ground the "we're not DuckDB" positioning with measurement.
  • 🟡 libSQL (Turso embedded) — defer. Embedded SQL path tracks SQLite within a few percent; revisit when we want a non-extension competitor for the vector workload (W10).
  • Cloudflare D1 — out-of-scope. Network-resident; benchmarks would measure HTTP, not the engine.
  • rqlite — out-of-scope. Distributed (Raft over HTTP); same network-dominates-everything problem.

Workload shape

10 curated workloads in three groups:

  • Group A — OLTP baseline (W1 read-by-PK, W2 range scan, W3 bulk insert, W4 single-row insert, W5 mixed OLTP, W6 secondary-index lookup)
  • Group B — SQL-feature scaling (W7 aggregate, W8 GROUP BY, W9 INNER JOIN — exercises SQLR-3 + SQLR-5 surface)
  • Group C — Differentiators (W10 vector top-10, W11 BM25 top-10, W12 hybrid retrieval — proves the Phase 7d / 8 / 8d work has measured value)

Sub-phases

Six independently-shippable PRs, ~1.5 kLOC total:

  • 9.1 Harness scaffolding + Driver trait + W1 end-to-end
  • 9.2 Group A workloads (W2–W6)
  • 9.3 Group B workloads (W7–W9)
  • 9.4 Group C differentiators (W10–W12)
  • 9.5 DuckDB driver (optional, feature-gated)
  • 9.6 Reporting (compare.py, first official run, docs/benchmarks.md canonical reference)

Open questions

8 design questions in the doc (Q1 host pinning · Q2 SLO gates · Q3 SQLite tuning profile · Q4 DuckDB gating · Q5 libSQL timing · Q6 D1/rqlite confirmation · Q7 publishing surface · Q8 workload versioning). Leans included for each. Implementation kicks off after Q-resolution.

Test plan

  • All referenced relative-link targets in the new doc exist on disk
  • No engine code touched → existing cargo build / cargo test impact is nil
  • Plan reviewed; Q1–Q8 answered before sub-phase 9.1 starts (separate Marvin task)

🤖 Generated with Claude Code

Drafts docs/benchmarks-plan.md — comparison-target viability call
(SQLite mandatory, DuckDB analytical-slice opt-in, libSQL deferred,
Cloudflare D1 + rqlite out-of-scope), 10 curated workloads across
OLTP / SQL-feature scaling / AI-era differentiators (HNSW, BM25,
hybrid retrieval), driver-trait shape, repo layout, 6 sub-phases,
and 8 open design questions. Wires into docs/_index.md "Future
work" and replaces the bare "Benchmarks against SQLite" line in
roadmap.md "Possible extras". No engine code yet — implementation
starts post-Q-resolution as its own ticket.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joaoh82 joaoh82 merged commit dab76f1 into main May 6, 2026
15 checks passed
joaoh82 added a commit that referenced this pull request May 6, 2026
…9.1) (#102)

First executable code for the SQLRite-vs-SQLite benchmark suite designed
in #101. Stands up a `benchmarks/` workspace member with a small
`Driver` trait, two engine implementations (SQLRite via `Connection`,
SQLite via `rusqlite`-bundled), one workload end-to-end (W1 read-by-PK),
a criterion entry point, and an aggregator that collapses
`target/criterion/**/estimates.json` into a single results envelope
under `benchmarks/results/`. Excluded from CI alongside `sqlrite-desktop`
+ the SDK cdylibs; runs locally with `make bench`.

Plan-doc:
  - Q1-Q8 resolved on 2026-05-06 and converted to a "Decisions
    (was: open questions)" section, mirroring the post-resolution
    shape of `docs/phase-7-plan.md`. Status moved to
    "approved 2026-05-06 -- 9.1 in flight".
  - Cleaned up the muddled "Not added to the default exclude list"
    sentence in the Repository layout section.

Harness:
  - `Driver` trait is small enough to express every planned workload:
    open / execute / execute_with_params / query_one / query_all.
    `&self` so drivers are cheap to clone into criterion closures.
  - SQLRite driver inlines `?` params via SQL formatting (SQLite-side
    quoting / arity checks unit-tested) -- the engine has no parameter
    binding yet; that lands as a post-9.6 follow-up.
  - SQLite driver runs the Q3-tuned profile at open time
    (WAL + synchronous=NORMAL + 64 MB cache + temp_store=MEMORY) and
    `prepare_cached` on every hot-path SELECT so we measure execution
    cost, not per-iter parse cost.
  - Per-run `TempDir` -- no page-cache / WAL bleed across iterations.
  - Correctness gate: every workload runs `correctness_check` against
    sample keys before timing, so a divergent-result "speedup" can't
    silently land.
  - Q8 versioning baked in: workloads carry a `WorkloadId { id, name,
    version }` and the JSON envelope tags every sample with `W{n}.v{v}`.

Output:
  - `BenchSample` per (workload, driver) pair: median + 95% CI
    + mean + std dev + sample count + ops/s.
  - `ResultsEnvelope` carries schema_version, run timestamp, host
    fingerprint (CPU brand, RAM, OS kind + release, arch) and commit
    info (sha, branch, dirty bit). `aggregate.rs` reads sysctl /
    /proc / git directly -- no chrono / sysinfo deps.
  - `benchmarks/results/.gitignore` keeps casual local runs out of
    git until 9.6 commits the first official pinned-host run.

Wiring:
  - `--exclude sqlrite-benchmarks` added to the four CI cargo commands
    (build, test, clippy, doc), with a comment explaining why.
  - `make bench` -> `benchmarks/scripts/run.sh` -> cargo bench +
    aggregator. `make bench-duckdb` deferred to 9.5.
  - CLAUDE.md "Workspace layout" + "Commands" sections updated.
  - `docs/_index.md` plan entry updated to reflect 9.1 shipping.

Verification:
  - `cargo fmt --all -- --check` clean.
  - `cargo clippy -p sqlrite-benchmarks --all-targets` clean (engine
    warnings unchanged from baseline).
  - Full CI-equivalent build + test + doc green
    (--exclude desktop / python / nodejs / benchmarks).
  - `cargo test -p sqlrite-benchmarks` -- 5 tests pass (4 inliner
    + 1 ymd-from-days round-trip).
  - End-to-end run with `--warm-up-time 1 --measurement-time 2
    --sample-size 10`: SQLRite ~12 us/op, SQLite ~2.5 us/op (~5x gap,
    driven by SQLRite re-parsing per call). Aggregator wrote a
    2-sample JSON envelope.

Refs: SQLR-4 (design), SQLR-16 (execution), #101.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.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