Skip to content

test(bench): ingest write-path criterion benches - #248

Merged
jensholdgaard merged 4 commits into
mainfrom
bench/ingest-write-path
Jun 18, 2026
Merged

test(bench): ingest write-path criterion benches#248
jensholdgaard merged 4 commits into
mainfrom
bench/ingest-write-path

Conversation

@jensholdgaard

@jensholdgaard jensholdgaard commented Jun 18, 2026

Copy link
Copy Markdown
Owner

What

Adds ourios-bench/benches/ingest_write_path.rs — criterion benches for CLAUDE.md §6.2's named ingest hot paths, alongside the existing b1/b2/recovery/compaction benches. This is the performance-test harness the perf-metrics work (#247) was paving the way for.

  • wal_appendOTLP → WAL: append one batch frame + fsync (the WAL-before-ack unit; one batch → one frame → one sync). Mirrors ourios.wal.append.duration. Throughput in bytes.
  • sink_write/{1000,10000}WAL → Parquet: feed N mined records to a ParquetRecordSink and flush to one Parquet object (encode + put). Mirrors ourios.sink.flush.*. Throughput in records.

Both rebuild their fixture in the untimed iter_batched setup, so only the durable append / emit + flush is measured.

Indicative local numbers (dev machine, real fsync — NOT a baseline)

  • wal_append4.4 ms/batch — fsync-bound; production amortizes one fsync across concurrent batches via group-commit.
  • sink_write/1000 ≈ 222 K rec/s; sink_write/100000.9 M rec/s — encode+put scales well as fixed overhead amortizes.

Per the bench-on-ci-runner-first discipline, these are supportive wall-clock evidence (like recovery/b1/b2), to be run indicatively on the CI runner; the authoritative baseline-hardware run is separate and opt-in.

Notes

  • Adds ourios-ingester as a ourios-bench dev-dep (for ParquetRecordSink); the WAL half uses ourios-wal directly.
  • No invariant (§3) touched — dev-only bench. A docs/benchmarks.md row can follow if you want it tracked there alongside the thesis gates.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added ingest_write_path performance benchmarks for the ingest write hot paths, including:
      • wal_append: measures steady-state WAL append + durable sync throughput (bytes).
      • sink_write/{N}: measures Parquet record sink emit + flush_all() performance (records), with warmed-up setup and timing focused on the critical work.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9241c03a-da18-401a-b259-83ef53b32e9a

📥 Commits

Reviewing files that changed from the base of the PR and between ffe01ca and 6d95d1c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • crates/ourios-bench/Cargo.toml
  • crates/ourios-bench/benches/ingest_write_path.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/ourios-bench/Cargo.toml

📝 Walkthrough

Walkthrough

Adds a new ingest_write_path Criterion benchmark target to crates/ourios-bench, backed by ourios-ingester as a dev-dependency. The benchmark file introduces two microbenchmarks: wal_append (WAL frame append + sync) and sink_write (ParquetRecordSink emit + flush), each with isolated per-iteration fixture setup.

Changes

Ingest Write-Path Benchmarks

Layer / File(s) Summary
Cargo target and dev-dependency wiring
crates/ourios-bench/Cargo.toml
Adds ourios-ingester as a path dev-dependency and registers the ingest_write_path bench target with harness = false.
Benchmark helpers: docs, imports, constants, and fixtures
crates/ourios-bench/benches/ingest_write_path.rs
Module-level doc comments describe the OTLP→WAL and WAL→Parquet hot paths; imports bring in Criterion and project types; wal_config() and constants configure WAL sizing and fsync; rec(i) generates non-degenerate MinedRecord fixtures with varying numeric param values.
wal_append and sink_write implementations
crates/ourios-bench/benches/ingest_write_path.rs
wal_append opens a fresh WAL per batch and times one frame append plus sync(); sink_write parametrizes over SINK_RECORDS sizes, emits records into a ParquetRecordSink, and calls flush_all(), reporting element throughput. Both use black_box to prevent dead-code elimination. criterion_group! and criterion_main! wire registration.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🐇 Hop, hop through the write-path we go,
WAL frames appended in one timely row,
Parquet records flushed, encode and put,
Criterion counts every tick underfoot.
No dead code survives the black_box test —
This bunny benchmarks faster than the rest! 🐾

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding criterion benchmarks for the ingest write-path, which is the primary objective of this PR.
Description check ✅ Passed The description comprehensively covers the PR's purpose, implementation details, performance metrics, and design decisions, though it does not explicitly address all template checklist items.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bench/ingest-write-path

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/ourios-bench/benches/ingest_write_path.rs`:
- Around line 35-139: The non-trivial benchmark helper functions wal_config and
rec lack unit tests to validate their correctness and assumptions. Add a
#[cfg(test)] module in this file with focused unit tests that verify the
wal_config function returns expected configuration values, the rec function
correctly generates MinedRecord instances with the varying parameter i properly
reflected in the output to ensure non-degenerate data for compression testing,
and validate any critical benchmark setup invariants such as proper TempDir
lifecycle management during benchmark execution. Place these tests adjacent to
the code they test to comply with coding guidelines.
- Around line 108-127: The issue is that r.clone() is being called inside the
measured closure for the ParquetRecordSink benchmark, so the cloning cost is
included in the timed sink.emit() operations which distorts the benchmark
signal. Move the cloning of records outside the timed path by cloning all
records in the setup closure (the first parameter to iter_batched) so that the
benchmark only measures the actual emit and flush operations without the clone
overhead. The measured closure should iterate over pre-cloned records instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 44f543b1-232a-4b0b-beb2-0b2d7dc2efd0

📥 Commits

Reviewing files that changed from the base of the PR and between 0d2074f and ffe01ca.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • crates/ourios-bench/Cargo.toml
  • crates/ourios-bench/benches/ingest_write_path.rs

Comment thread crates/ourios-bench/benches/ingest_write_path.rs
Comment thread crates/ourios-bench/benches/ingest_write_path.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new Criterion benchmark suite to ourios-bench to measure ingest write-path hot spots (OTLP→WAL append+fsync, and WAL→Parquet sink emit+flush), aligning with the performance harness needs described in CLAUDE.md §6.2.

Changes:

  • Add ingest_write_path Criterion benches covering wal_append and sink_write/{1000,10000}.
  • Add ourios-ingester as a dev-dependency for access to ParquetRecordSink.
  • Update Cargo.lock for the new dependency edge.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
crates/ourios-bench/Cargo.toml Registers the new ingest_write_path bench and adds ourios-ingester as a dev-dep.
crates/ourios-bench/benches/ingest_write_path.rs Implements the new WAL append+sync and Parquet sink write-path Criterion benchmarks.
Cargo.lock Adds ourios-ingester to the resolved dependency graph.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/ourios-bench/benches/ingest_write_path.rs Outdated
Adds `ourios-bench/benches/ingest_write_path.rs` covering CLAUDE.md §6.2's
named ingest hot paths, alongside the existing b1/b2/recovery/compaction
benches:

- `wal_append` — OTLP → WAL: append one batch frame + fsync (the
  WAL-before-ack unit), mirroring `ourios.wal.append.duration`.
- `sink_write/{1000,10000}` — WAL → Parquet: feed N mined records to a
  `ParquetRecordSink` and flush to one Parquet object, mirroring
  `ourios.sink.flush.*`. Throughput in records.

Both rebuild their fixture in the untimed `iter_batched` setup so only the
durable append / emit + flush is measured. Supportive **wall-clock**
evidence (like recovery/b1/b2) — to be run indicatively on the CI runner
first; the authoritative baseline-hardware numbers are a separate, opt-in
run (the `bench-on-ci-runner-first` discipline). Adds `ourios-ingester` as
a dev-dep for the sink half.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jensholdgaard
jensholdgaard force-pushed the bench/ingest-write-path branch from ffe01ca to 461651f Compare June 18, 2026 15:11
@jensholdgaard jensholdgaard changed the title bench(ingester): ingest write-path criterion benches test(bench): ingest write-path criterion benches Jun 18, 2026
@jensholdgaard
jensholdgaard requested a review from Copilot June 18, 2026 15:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comment thread crates/ourios-bench/benches/ingest_write_path.rs Outdated
Comment thread crates/ourios-bench/benches/ingest_write_path.rs
Address review on #248:
- Clone the record batch in the untimed `iter_batched` setup; the timed
  `sink_write` routine now emits owned records, so per-record clone cost
  no longer pollutes the WAL→Parquet signal (sink throughput rises to
  ~1.09 M rec/s at 10k, previously understated).
- `wal_append` warms up with one append + sync in setup so the timed sync
  measures steady state — the first sync on a fresh WAL also fsyncs the
  segment directory (entry durability), which steady-state syncs don't.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

Comment thread crates/ourios-bench/benches/ingest_write_path.rs Outdated
Comment thread crates/ourios-bench/benches/ingest_write_path.rs
Comment thread crates/ourios-bench/benches/ingest_write_path.rs Outdated
Round 2 review on #248: `iter_batched` ran fixture teardown (dropping
`TempDir`/`Wal`/sink → file close, Parquet unlink, dir delete) inside the
timed routine. Switch both benches to `iter_custom` with an explicit
`Instant` around just the append+fsync / emit+flush, so build and teardown
are excluded and only one fixture is alive at a time (deferring drops via
iter_batched outputs would instead accumulate open WALs/temp dirs across a
sample batch). Teardown was a large fraction — `sink_write/1000` ~halves
and sink throughput rises to ~1.56 M rec/s at 10k. Module doc updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

Comment thread crates/ourios-bench/benches/ingest_write_path.rs
…(review)

Round 3 review on #248: `ParquetRecordSink::flush_all` swallows encode/
store errors and retains the buffer, so a silent flush failure would still
report a (bogus) `sink_write` timing for the error path. Add an untimed
`assert_eq!(sink.buffered_records(), 0)` right after the timer — a failed
flush now panics the bench instead of benchmarking the retry path.
(`wal_append` is already covered: its append/sync `.expect()`s panic on
error.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated no new comments.

@jensholdgaard
jensholdgaard merged commit 244eece into main Jun 18, 2026
15 checks passed
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