docs(bench): profile daytona/modal filesystem trade-offs#100
Draft
signalrush wants to merge 1 commit into
Draft
Conversation
Add benchmark scripts and writeups for the three remote-FS surfaces an
agent-sdk session can land on: daytona sandbox FS, modal sandbox FS, and
modal volumes (both client-side via batch_upload and mounted into a
sandbox).
- bench_fs.py single-backend latency / throughput across
small (200x64KiB conc=64), 200MiB, 1GiB workloads;
reports aggregate + p50/p95/p99 latency.
- bench_contention.py N parallel workers each on a disjoint subpath
of the same backend; surfaces per-prefix vs
per-volume contention.
- bench_mount.py in-sandbox dd / many-files / pip-install on
/tmp vs a mounted modal volume subpath.
Three result files capture the findings, including the non-obvious
ones: modal volume batch_upload contends per-prefix not per-volume,
and a mounted volume is at parity for bulk I/O but ~3-5x slower for
metadata-heavy workloads like pip install.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds benchmark scripts and three writeups characterising the remote-FS
surfaces an agent-sdk session can land on:
Sandbox.fs.{upload,download,delete}_fileSandbox.filesystem.{copy_from_local,copy_to_local,remove}Volume.{batch_upload, read_file, remove_file}/vol/<sub>accessed via in-sandboxexecDoc-only PR;
benchmark/fs/is a sibling of the existingbenchmark/load/andbenchmark/micro/and is not imported by the server.What's in the PR
benchmark/fs/bench_fs.py— single-backend bench. Workloads:small(N×S, concurrent),200m,1g,2g(opt-in). Reports aggregate throughput + per-op p50/p95/p99 latency.benchmark/fs/bench_contention.py— N parallel workers each on a disjoint subpath of the same backend; surfaces per-prefix vs per-volume contention.benchmark/fs/bench_mount.py— in-sandboxdd/cp -P16/pip install pandasagainst/tmp(ephemeral) and/vol/<sub>(mounted Modal volume) inside one Modal sandbox.benchmark/fs/README.md,RESULTS.md,RESULTS_CONTENTION.md,RESULTS_MOUNT.md— usage + numbers + analysis for each.All scripts share a
Backendabstraction,asyncio.to_threadover the blocking SDK calls, and a bumped default executor (128 workers) so concurrency knobs aren't capped by the asyncio default thread pool. Each provider sandbox is provisioned with 4 vCPU / 4 GiB RAM.Headline findings
bench_fs.py— small (200×64 KiB, conc=64), 200 MiB, 1 GiBbatch_uploadcommits queue when many target the same prefixbench_contention.py— same total ops, spread across 1/5/10 disjoint subpathsModal volume parallelises near-ideally when prefixes are disjoint:
Per-op p50 stays flat for
modal_vol(0.37 s across 1/5/10 workers) but grows linearly formodal_sb(0.69 → 0.94 → 1.58 s) — the sandbox FS RPC channel queues per task. Daytona is mostly flat to 5 workers, then degrades.So the earlier "
modal_volwrites serialise" headline is wrong in the general case: the contention is per-prefix, not per-volume. Hammering one path serialises, fanning out across subpaths scales.bench_mount.py— agent doing work inside the sandbox/tmp/vol/<sub>Bulk I/O through the mount is essentially free; metadata-heavy workloads (pip install, rm -rf of deep trees) pay 3–5× because each
mkdir/rename/fsync/unlinkround-trips to the volume control plane while data writes stay in the local cache.Practical guidance the report lands on
git clone: install to/tmpthen bulk-copy onto/vol.Caveats called out in the docs
modal_vol/1/write) move ±15 % run-to-run.modal_vol/1g/write 0.52 soutlier is a content-addressed-storage dedup artefact (the 1 GiB file repeats the same 1 MiB urandom seed used by the 200 MiB phase). Flagged inRESULTS.md.bench_mount.pyare page-cache reads.Test plan
This PR adds new files only; no existing code changes.
benchmark/fs/bench_fs.pyandbenchmark/fs/bench_mount.pyto confirm numbers are reproducible on another workspace (creds load from~/.env)🤖 Generated with Claude Code