Skip to content

[runtime] add Blob::write_at_sync#3840

Merged
patrick-ogrady merged 7 commits into
mainfrom
andre/runtime-write-at-sync
May 20, 2026
Merged

[runtime] add Blob::write_at_sync#3840
patrick-ogrady merged 7 commits into
mainfrom
andre/runtime-write-at-sync

Conversation

@andresilva
Copy link
Copy Markdown
Member

@andresilva andresilva commented May 20, 2026

This PR adds Blob::write_at_sync, a storage API for writing a byte range and making that write durable as part of the same operation. On Linux-backed runtimes this uses per-I/O sync flags where available, while fallback implementations preserve the same logical contract with write_at followed by sync. Empty writes are accepted as no-ops and do not sync prior writes.

The storage benchmark harness now has a write_sync workload with a --sync-method switch for comparing write_at + sync against write_at_sync.

Replaces #3784.

Benchmarks

Benchmarks ran on an AWS EC2 i8g.2xlarge node with local NVMe instance storage, Ubuntu 26.04, and Linux kernel 7.0.0. Each case ran the write_sync workload with contiguous writes, 30 seconds, a 256M fixed file, seed 0, and 8 runtime worker threads. Deltas compare write_at_sync against write_at + sync, positive throughput delta means write_at_sync is faster, and positive p95 delta means write_at_sync has lower p95 latency.

The concurrent-writer results need one caveat: write_at + sync is not a strict per-writer durable-write baseline when multiple writers share the same blob. Each sync can also flush dirty writes issued by other writers, so some writers may get credit for durability work already forced by a different writer. write_at_sync is range-scoped to the submitted write, so the 8-writer comparison is useful as a shared-blob workload measurement, but it is not a perfectly isolated per-operation comparison between the two durability methods.

Summary

Filesystem Backend Writers 4K throughput 64K throughput 1M throughput Notes
XFS Tokio 1 +30.7% +14.0% -0.0% write_at_sync helps small writes.
XFS Tokio 8 +98.7% -3.5% -0.0% Big 4K gain, neutral/regressive above that.
XFS io_uring 1 +44.9% +24.3% -0.0% Best single-writer gains.
XFS io_uring 8 -43.0% -3.4% -0.1% Concurrent 4K regresses sharply.
ext4 Tokio 1 +30.2% +16.2% -0.0% Similar to XFS single-writer Tokio.
ext4 Tokio 8 +131.3% -3.3% +0.0% Largest 4K gain.
ext4 io_uring 1 +36.7% +20.1% -0.0% Clear single-writer gain for 4K/64K.
ext4 io_uring 8 -11.1% -3.5% -0.6% No throughput win under concurrency.

XFS

Tokio

Single Writer

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 104.3 136.3 +30.7% 118.1 52.9 +55.2%
64K 1093.7 1247.1 +14.0% 81.3 76.1 +6.4%
1M 1578.9 1578.5 -0.0% 719.4 727.7 -1.2%

Concurrent Writers (8)

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 321.4 638.6 +98.7% 163.0 97.7 +40.1%
64K 1546.0 1491.7 -3.5% 601.0 640.9 -6.6%
1M 1579.3 1579.3 -0.0% 5192.9 5158.7 +0.7%

io_uring

Single Writer

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 107.4 155.6 +44.9% 114.6 48.7 +57.4%
64K 1086.9 1351.4 +24.3% 83.1 74.3 +10.6%
1M 1578.9 1578.6 -0.0% 726.2 727.4 -0.2%

Concurrent Writers (8)

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 305.6 174.1 -43.0% 178.5 286.1 -60.3%
64K 1543.4 1491.1 -3.4% 457.1 630.7 -38.0%
1M 1579.4 1578.6 -0.1% 5178.3 5141.0 +0.7%

ext4

Tokio

Single Writer

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 107.2 139.5 +30.2% 77.7 69.4 +10.7%
64K 1064.1 1236.2 +16.2% 93.1 83.8 +9.9%
1M 1568.6 1568.3 -0.0% 679.8 677.3 +0.4%

Concurrent Writers (8)

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 280.2 648.2 +131.3% 173.1 96.8 +44.1%
64K 1531.6 1481.6 -3.3% 611.8 629.3 -2.9%
1M 1577.6 1577.7 +0.0% 5150.0 5109.8 +0.8%

io_uring

Single Writer

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 95.7 130.9 +36.7% 81.0 70.9 +12.5%
64K 1028.5 1235.1 +20.1% 92.7 82.6 +10.9%
1M 1568.7 1568.2 -0.0% 675.0 675.9 -0.1%

Concurrent Writers (8)

IO size write_at + sync MiB/s write_at_sync MiB/s Throughput delta write_at + sync p95 us write_at_sync p95 us p95 delta
4K 218.5 194.3 -11.1% 199.8 220.4 -10.3%
64K 1533.2 1480.2 -3.5% 591.1 373.1 +36.9%
1M 1577.6 1568.3 -0.6% 5104.8 5137.4 -0.6%

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 20, 2026

Deploying monorepo with  Cloudflare Pages  Cloudflare Pages

Latest commit: 34d147e
Status: ✅  Deploy successful!
Preview URL: https://1dd7b18e.monorepo-eu0.pages.dev
Branch Preview URL: https://andre-runtime-write-at-sync.monorepo-eu0.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 20, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
commonware-mcp 34d147e May 20 2026, 10:37 PM

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Benchmark results

Tip

PASSED: No benchmark exceeded the regression threshold.

Benchmark comparison table
Benchmark Baseline (main) Current Delta Threshold Status
qmdb::merkleize/variant=any::unordered::fixed::mmr keys=10000 ch=false sync=false 1.555 ms 1.686 ms +8.46% 10.00% ✅ PASS
qmdb::merkleize/variant=current::ordered::fixed::mmb chunk=256 keys=10000 ch=true sync=false 3.044 ms 3.164 ms +3.93% 10.00% ✅ PASS

Baseline commit(s): 25bd84194fab

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c1d7a99. Configure here.

Comment thread runtime/src/storage/faulty.rs
@andresilva andresilva moved this to Ready for Review in Tracker May 20, 2026
@andresilva andresilva requested a review from patrick-ogrady May 20, 2026 16:36
Comment thread runtime/src/lib.rs
///
/// This is not a durability barrier for previous operations. When it completes,
/// only the bytes submitted to this call are guaranteed durable. Earlier unsynced
/// [`Blob::write_at`] or [`Blob::resize`] calls require [`Blob::sync`] to become
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.

Is this true? does sync on the blob here also sync other pending writes?

Copy link
Copy Markdown
Member Author

@andresilva andresilva May 20, 2026

Choose a reason for hiding this comment

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

Yes, this is the only thing that this API guarantees. On Linux where we actually implement this with RWF_SYNC the kernel only guarantees the range written by that specific syscall is durable. On non-Linux where we fallback to write+sync then we'll sync all pending writes, but that's incidental and users shouldn't lean on it. For example, even on non-Linux, if you issue a write_at_sync([]) we early return since there's nothing to write, which avoids syncing previous writes.

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.

Good to know...I would've definitely messed this up.

Comment thread runtime/src/storage/tokio/fallback.rs
@patrick-ogrady patrick-ogrady merged commit 64d3dc2 into main May 20, 2026
176 checks passed
@patrick-ogrady patrick-ogrady deleted the andre/runtime-write-at-sync branch May 20, 2026 22:44
@github-project-automation github-project-automation Bot moved this from Ready for Review to Done in Tracker May 20, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 85.80858% with 43 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.71%. Comparing base (14a016a) to head (34d147e).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
runtime/src/utils/buffer/paged/cache.rs 0.00% 24 Missing ⚠️
runtime/src/utils/buffer/mod.rs 0.00% 12 Missing ⚠️
runtime/src/storage/faulty.rs 87.71% 6 Missing and 1 partial ⚠️
@@            Coverage Diff             @@
##             main    #3840      +/-   ##
==========================================
- Coverage   95.73%   95.71%   -0.02%     
==========================================
  Files         473      473              
  Lines      192489   192842     +353     
  Branches     4666     4674       +8     
==========================================
+ Hits       184280   184588     +308     
- Misses       6636     6681      +45     
  Partials     1573     1573              
Files with missing lines Coverage Δ
runtime/src/iouring/mod.rs 99.01% <100.00%> (+0.01%) ⬆️
runtime/src/iouring/request.rs 99.90% <100.00%> (+<0.01%) ⬆️
runtime/src/lib.rs 97.78% <ø> (+0.04%) ⬆️
runtime/src/storage/audited.rs 94.16% <100.00%> (+1.14%) ⬆️
runtime/src/storage/iouring.rs 98.99% <100.00%> (+0.02%) ⬆️
runtime/src/storage/memory.rs 99.56% <100.00%> (+0.02%) ⬆️
runtime/src/storage/metered.rs 100.00% <100.00%> (ø)
runtime/src/storage/mod.rs 97.85% <100.00%> (+0.10%) ⬆️
runtime/src/storage/tokio/unix.rs 93.70% <100.00%> (+1.70%) ⬆️
runtime/src/storage/faulty.rs 94.50% <87.71%> (-0.93%) ⬇️
... and 2 more

... and 15 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 14a016a...34d147e. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants