How Do I Set Up a Rust Dev Environment in a Cloud Sandbox?
Updated October 27, 2026 .md
Short answer: A new sandbox already has Rust 1.99.1 through rustup, so clone and run cargo build --release. On 2026-10-27 a clean release build of ripgrep 15.1.0 took a median 36.4 s on small, 19.5 s on default and 12.6 s on large, about $0.0002 each. Save the target directory in a named snapshot to skip rebuilds.
We ran every command on this page on prod on 2026-10-27 between 11:06 and 11:17 UTC, in eu-central. The project is BurntSushi/ripgrep at tag 15.1.0 (commit af60c2d): a real Cargo workspace with a Cargo.lock.
Results#
| Step | small (2 vCPU) |
default (4 vCPU) |
large (8 vCPU) |
|---|---|---|---|
cargo build --release, empty registry and target/ (3 runs) |
31.5, 36.4, 38.3 s | 20.4, 19.5, 19.3 s | 13.1, 11.9, 12.6 s |
cargo build --release, warm registry, cargo clean first (3 runs) |
37.2, 38.2, 38.4 s | 19.4, 18.8, 18.0 s | 11.2, 11.3, 11.4 s |
Rebuild after touch crates/core/main.rs |
10.3 s | 6.1 s | 4.1 s |
cargo test, first run (builds the debug profile, 443 tests) |
24.5 s | 12.2 s | 9.8 s |
cargo test, second run |
2.7 s | 1.2 s | 0.9 s |
From the named snapshot: cargo build --release / cargo test |
(source) | 0.1 s / 1.2 s | 0.1 s / 0.9 s |
sbx new --from the snapshot to ready |
3.2 s | 3.2 s |
Medians are in bold. Every build used -j equal to the vCPU count, which is also Cargo's default. One fresh sandbox per size, run one after another. Other sandboxes on the shared account were running at the same time, and lscpu on the small sandbox showed an AMD Ryzen 9 7950X3D host. Your sandbox can land on a different machine, so treat these as one dated sample, not a guarantee.
What the numbers say:
- The compile is the cost, not the download. An empty registry was no slower than a warm one: the medians differ by less than run-to-run noise. ripgrep's crates are only 37 MB. On
smallthe first cold run was even the shortest of all six. - More vCPUs help, but not linearly.
defaultwas 1.9 times faster thansmall, andlarge2.9 times. Parts of a Rust build, such as the final crate and the link step, can't be spread across cores. For per-core numbers see CPU performance by sandbox size. - A snapshot with
target/skips the build. Cargo decides what to rebuild from file timestamps, and the snapshot keeps them. A sandbox started from it found nothing to rebuild, even on a bigger size.
Price per build#
Prices from our pricing, billed per second: small $0.018/hour, default $0.036/hour, large $0.072/hour. For the median clean release build:
| Size | Arithmetic | Cost per build | Per 1,000 builds |
|---|---|---|---|
small |
36.4 s × $0.018 / 3600 | $0.000182 | $0.18 |
default |
19.5 s × $0.036 / 3600 | $0.000195 | $0.20 |
large |
12.6 s × $0.072 / 3600 | $0.000252 | $0.25 |
This counts build time only. Your sandbox also bills while you clone, test and copy files out. large costs about 38% more per build than small and finishes in about a third of the time. Pick it when someone is waiting on the result.
1. See what the sandbox already has#
sbx new --name rust-dev --type small
sbx exec sb_pxma7ivcrc bash -lc "rustc -V; cargo -V; rustup toolchain list; du -sh ~/.rustup"rustc 1.99.1 (58cf8f9c3 2026-10-13)
cargo 1.99.1 (5f94df478 2026-08-27)
stable-x86_64-unknown-linux-gnu (active, default)
600M /home/user/.rustupThe image also has gcc 13.3, which Cargo uses as the linker, plus clippy, rustfmt and rust-analyzer. Use bash -lc so the login PATH includes ~/.cargo/bin. These are the versions on 2026-10-27; the image changes over time. The full list is in What's pre-installed in a sandbox.
2. Pin a toolchain#
To add a dated nightly:
sbx exec sb_pxma7ivcrc --timeout 300 bash -lc "rustup toolchain install nightly-2026-10-25 --profile minimal; rustup run nightly-2026-10-25 rustc -V"info: downloading self-update (new version: 1.29.2)
…
rustc 1.101.0-nightly (12433c307 2026-10-24)That took 7.5 s, including a rustup self-update to 1.29.2.
To pin the project, add a rust-toolchain.toml file. One catch: the preinstalled toolchain is registered as stable, so pinning the same version by number downloads a second copy.
cd ~/ripgrep
printf '[toolchain]\nchannel = "1.99.1"\nprofile = "minimal"\n' > rust-toolchain.toml
rustc -V
rustup toolchain listinfo: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`
rustc 1.99.1 (58cf8f9c3 2026-10-13)
stable-x86_64-unknown-linux-gnu (default)
nightly-2026-10-25-x86_64-unknown-linux-gnu
1.99.1-x86_64-unknown-linux-gnu (active)The first rustc -V took 7.4 s while rustup installed 1.99.1. With both extra toolchains, ~/.rustup grew from 600 MB to 1.8 GB. That matters on small, so pin stable if the preinstalled version is good enough. You can also install your pinned version once and save it in a snapshot (step 5).
3. Build and test a real workspace#
sbx exec sb_pxma7ivcrc --timeout 120 bash -lc "git clone -q https://github.com/BurntSushi/ripgrep && cd ripgrep && git checkout -q 15.1.0 && git log -1 --format='%h %cs %s'"af60c2d 2025-10-22 15.1.0A full build and test run can take longer than the 30-second default timeout of sbx exec. Run it in the background with --detach and poll. We timed each step with this script, copied into the sandbox with sbx scp bench.sh sb_pxma7ivcrc:/home/user/:
#!/bin/bash
# bench.sh JOBS RUNS
. ~/.cargo/env; cd ~/ripgrep; J=$1; R=${2:-1}
t() { local s=$(date +%s.%N); "$@" >/tmp/last.log 2>&1; local rc=$?; local e=$(date +%s.%N)
printf '%s rc=%d %.1f s\n' "$LABEL" $rc $(awk "BEGIN{print $e-$s}"); tail -1 /tmp/last.log; }
for i in $(seq 1 $R); do rm -rf ~/.cargo/registry ~/.cargo/git target
LABEL="cold build $i" t cargo build --release --locked -j $J; done
for i in $(seq 1 $R); do cargo clean -q
LABEL="warm registry build $i" t cargo build --release --locked -j $J; done
LABEL="no-op build" t cargo build --release --locked -j $J
touch crates/core/main.rs
LABEL="touch main.rs build" t cargo build --release --locked -j $J
LABEL="cargo test first" t cargo test --locked -j $J
LABEL="cargo test again" t cargo test --locked -j $J
du -sh target ~/.cargo/registry ~/.rustupsbx exec sb_pxma7ivcrc --detach "bash ~/bench.sh 2 3 > ~/bench-small.log 2>&1"
sbx exec sb_pxma7ivcrc "cat ~/bench-small.log"cold build 1 rc=0 31.5 s
Finished `release` profile [optimized + debuginfo] target(s) in 31.47s
cold build 2 rc=0 36.4 s
…
touch main.rs build rc=0 10.3 s
cargo test first rc=0 24.5 s
cargo test again rc=0 2.7 s
676M target
37M /home/user/.cargo/registry
1.8G /home/user/.rustupAll 443 tests passed. --locked makes Cargo fail rather than change Cargo.lock. ripgrep's [profile.release] sets debug = 1, so the release binary carries debug info.
Disk used by target/#
| Path | Size |
|---|---|
target/release (release build) |
171 MB |
target/debug (from cargo test) |
505 MB |
~/.cargo/registry (downloaded crates) |
37 MB |
~/.rustup (stable, plus 1.99.1 and a nightly) |
1.8 GB |
For ripgrep, cargo test adds three times as much disk as the release build. On a bigger workspace, target/ is usually what fills a small disk first. cargo clean reclaims it.
4. Copy the binary out with sbx scp#
sbx scp sb_pxma7ivcrc:/home/user/ripgrep/target/release/rg ./rg
./rg --versionripgrep 15.1.0 (rev af60c2de9d)The 30.4 MB binary took 21 s to copy, and its SHA-256 matched the copy in the sandbox. Stripping the debug info first made it 5.3 MB and the copy took 6.4 s:
sbx exec sb_pxma7ivcrc bash -lc "cd ~/ripgrep && strip -o rg-stripped target/release/rg && ls -l rg-stripped"
sbx scp sb_pxma7ivcrc:/home/user/ripgrep/rg-stripped ./rg-stripped-rwxr-xr-x 1 user user 5281704 Oct 27 11:11 rg-strippedThe binary links against glibc from Ubuntu 24.04. It ran on our Linux x86-64 machine, but it won't run on macOS or on an older glibc. Build for those targets separately.
5. Save it as a named snapshot#
sbx snapshot sb_pxma7ivcrc rust-rg{"ok":true,"type":"snapshot.named.info","snapshot":{…,"name":"rust-rg",…,"status":"ready","type":"small",…}}The save took 2.1 s. It holds the toolchains, ~/.cargo/registry, the clone and the 676 MB target/. We started bigger sandboxes from it:
sbx new --name rust-dev-2 --type default --from rust-rg
sbx exec sb_kr2r5rjeif --timeout 300 "bash ~/snap.sh 4"rustc 1.99.1 (58cf8f9c3 2026-10-13)
as saved: release build rc=0 0.1 s
Finished `release` profile [optimized + debuginfo] target(s) in 0.07s
as saved: cargo test rc=0 1.2 s
passed 443 failed 0snap.sh runs the same timed cargo build --release and cargo test as bench.sh. Cargo rebuilt nothing on the new 4-vCPU sandbox. The same was true on large. Going up in size from a snapshot works, but moving to a smaller size isn't supported yet, so build the snapshot on the smallest size you plan to use. To rebuild the snapshot when Cargo.lock changes, name it after the lockfile's hash as in Cache dependencies in a named snapshot.
We didn't test sccache or other shared compiler caches. Within one project, a snapshot with target/ already skips the work they would save.
FAQ#
Is Rust already installed in a Sandboxer sandbox?#
Yes. On 2026-10-27 the image had rustc and cargo 1.99.1 as rustup's stable toolchain, plus clippy, rustfmt and rust-analyzer. Run rustc -V in your own sandbox, because the image is updated over time.
Which sandbox size is the best value for Rust builds?#
In our test small was cheapest per clean build ($0.000182) and large took the least time (12.6 s), at $0.000252 per build. Pick by whether someone is waiting. For repeat builds of the same project, a snapshot with target/ saves more than any size.
Should I set cargo -j to the number of vCPUs?#
Cargo already defaults to the number of CPUs it sees, and nproc shows the size's vCPUs (2, 4 or 8 here). We passed -j explicitly only to keep the runs comparable.
Does target/ survive sbx stop and sbx resume?#
Yes. target/, ~/.cargo and ~/.rustup live under /home/user on the sandbox disk. Stop keeps the disk, and a named snapshot or fork copies it. Our snapshot test shows Cargo still treats the saved build as fresh.
How do I get a long build's output if exec times out?#
Start it with sbx exec <id> --detach "…", which returns a process id. Then read its log with sbx exec <id> --status <pid> or follow it with --attach <pid>. Redirecting to a log file, as we did, also works.
Related#
More guides
For running AI-written code we rank Sandboxer, Freestyle and E2B first: each gives code its own VM with an API or SDK and can pause with memory. Pick Daytona for Windows or GPUs, Modal or Northflank for GPUs at scale, E2B or Northflank to run in your own cloud, and Vercel Sandbox if your app lives on Vercel.
For coding agents we rank Sandboxer first: a full Ubuntu VM with Claude Code and Codex preinstalled, Docker, and stop-and-resume that keeps the agent's session in memory. Freestyle and Amp Orbs also keep memory across pauses. Pick E2B for prebuilt agent templates on open source, Docker Sandboxes for free local runs, and Codespaces if you live in GitHub.
The best Daytona alternatives depend on why you're switching. For a full Linux microVM on every sandbox with memory-saving stop and Docker, we rank Sandboxer first. E2B suits open source and self-hosting, Modal massive short-job fleets, Northflank bring-your-own-cloud with GPUs, and Vercel Sandbox apps on Vercel.
If you're leaving E2B for longer sessions or a fuller machine, we rank Sandboxer first, then Freestyle: both give each sandbox a full Linux VM that keeps memory across pauses, with Docker and no short session cap. Pick Daytona for Windows or GPUs, Northflank for bring-your-own-cloud, and stay on E2B if you need open source.