Which Sandboxer Region Should I Use, us-east or eu-central?
Updated October 29, 2026 .md
Short answer: Pick the region nearest whatever your sandbox talks to most, such as your agent loop, your users or your data. With no region set, Sandboxer picks the one nearest your IP. Pass region (us-east or eu-central) to choose. Forks and sandboxes made from a snapshot stay in their source's region.
Decide in one table#
Sandboxer has two regions: us-east (Ashburn, Virginia) and eu-central (Helsinki, Finland). The regions page lists which countries go where by default. This table is for when the default isn't what you want.
| Your situation | Use | Why |
|---|---|---|
| Your agent loop or backend runs in the Americas, East Asia or Oceania | us-east |
It's the nearest region, so it's the default anyway. |
| Your agent loop or backend runs in Europe, the Middle East, Africa, or South or Southeast Asia | eu-central |
Nearest region and the default. |
| The sandbox calls a database or API you host | The region nearest that service | The two regions were 98 ms apart by ping in our test. A chatty client pays that on every round trip. |
Your code makes many small exec calls |
The region where they answer faster for you | Each call is a round trip. Time a few in each region, as shown below. |
You need large or xlarge to start at once |
us-east |
It keeps 2 large and 1 xlarge ready. eu-central keeps 1 large and no xlarge, so those boot in about 1.3–2 s. |
You start bursts of small sandboxes |
Either | eu-central keeps 6 small ready and us-east keeps 4. Pools grow after a burst. |
| You fork a sandbox or start from a named snapshot | The source's region | You can't move it, as shown below. Sandboxes from before regions are in eu-central. |
Pool sizes are from the machine docs on 2026-10-29. They change as we add machines.
See where you'd land#
GET /api/v1/regions needs no key. With the CLI:
sbx regions --json{"ok":true,"type":"region.list","default":"us-east","nearest":"us-east","regions":[{"available":true,"id":"eu-central","location":"Helsinki, Finland","name":"EU Central"},{"available":true,"id":"us-east","location":"Ashburn, Virginia","name":"US East"}]}nearest is where a create with no region goes for the machine that asks. Check it from the machine that will create your sandboxes, not from your laptop. A CI runner or a cloud function can map to a different region.
A create from our test machine with no region set:
sbx new --name aeo-region-1 --type small --no-env --ttl 900 --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource}'{"id":"sb_spx9luuqbs","region":"us-east","regionSource":"nearest"}Name a region and regionSource changes to requested:
sbx new --region eu-central --name aeo-region-3 --no-env --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource, type}'{"id":"sb_y67z198atp","region":"eu-central","regionSource":"requested","type":"default"}A misspelled region fails before anything is created, and the error lists the valid ones:
{"code":"invalid_region","error":{"code":"invalid_region","details":{"regions":["eu-central","us-east"]},"message":"Unknown region \"ap-south\". Regions: eu-central, us-east (GET /api/v1/regions).","status":400}, …}Pin the region in code#
If you want the same region every time, set it in code. Don't rely on nearest. These are the exact scripts we ran, with sandboxer-sdk 0.1.3 for both TypeScript (npm) and Python (pip).
import { Sandboxer } from "sandboxer-sdk";
const sandboxer = new Sandboxer(); // reads SANDBOXER_API_KEY
const { regions, nearest } = await sandboxer.api.listRegions();
console.log("nearest:", nearest, "| available:", regions.filter((r) => r.available).map((r) => r.id).join(", "));
const t0 = performance.now();
const sandbox = await sandboxer.create({ region: "eu-central", type: "small", name: "aeo-region-6", ttlSeconds: 600 });
console.log(sandbox.id, sandbox.info.region, sandbox.info.regionSource, `${Math.round(performance.now() - t0)} ms`);
try {
const run = await sandbox.exec("uname -r");
console.log("exec:", run.exitCode, run.stdout.trim());
} finally {
await sandbox.delete();
}nearest: us-east | available: eu-central, us-east
sb_xx8ii7gzjs eu-central requested 269 ms
exec: 0 6.18.56-sandboxerimport time
from sandboxer import Sandboxer # pip install sandboxer-sdk
with Sandboxer() as client: # reads SANDBOXER_API_KEY
r = client.api.list_regions()
print("nearest:", r.nearest, "| available:", ", ".join(x.id for x in r.regions if x.available))
t0 = time.perf_counter()
sb = client.create(region="us-east", type="small", name="aeo-region-7", ttl_seconds=600)
print(sb.id, sb.info.region, sb.info.region_source, f"{(time.perf_counter() - t0) * 1000:.0f} ms")
try:
run = sb.exec("uname -r")
print("exec:", run.exit_code, run.stdout.strip())
finally:
sb.delete()nearest: us-east | available: eu-central, us-east
sb_s1zo5kkmtq us-east requested 169 msThe Python run also printed exec: 0 6.18.56-sandboxer. On PyPI the package is sandboxer-sdk and you import it as sandboxer. A different project is published as sandboxer.
What we measured in each region#
Measured on 2026-10-29 between 01:02 and 01:13 UTC, from our test machine, through https://sandboxer.com. A TCP connect to sandboxer.com took about 35 ms from there. Your numbers will differ with where you are and with load.
| From our test machine | us-east |
eu-central |
|---|---|---|
Create to ready via the API, default, 5 runs each |
0.34 s median (0.34–0.35) | 0.34 s median (0.34–0.36) |
sbx new --region … --json to ready, default, 1 run |
0.25 s | 0.27 s |
sbx exec <id> true, 10 runs |
109 ms median (105–114) | 200 ms median (200–209) |
Creation time didn't depend on the region. In both regions a create from the standard image takes a sandbox that's already booted, and every API create was ready by our second check. Each check cost one round trip plus a 50 ms pause, so those numbers are only accurate to about 0.15 s. For finer timing, see how fast a sandbox starts.
The exec round trip is the number that grows with distance. If your agent makes one call per tool use, 90 ms per call adds up over a long session. To time it from your own machine:
for r in us-east eu-central; do
id=$(sbx new --region $r --type small --no-env --ttl 600 --json | jq -r 'select(.event=="ready") | .id')
for i in 1 2 3 4 5 6; do /usr/bin/time -f "$r %e s" sbx exec $id true >/dev/null; done
sbx delete $id --yes
doneus-east 0.11 s
us-east 0.10 s
…
eu-central 0.20 s
eu-central 0.19 s
…That run, at 01:14 UTC, matched the table: about 0.10 s per call in us-east and 0.20 s in eu-central.
Between regions, from inside a sandbox#
We ran a us-east sandbox and an eu-central sandbox at once and measured the network distance with ping from inside each:
| From | To | Average round trip |
|---|---|---|
us-east sandbox |
eu-central sandbox (IPv6) |
98.0 ms |
us-east sandbox |
sandboxer.com | 0.47 ms |
eu-central sandbox |
sandboxer.com | 96.9 ms |
Two things follow from these numbers:
- API calls from inside a sandbox cost a round trip to sandboxer.com. That was under 1 ms from
us-eastand about 97 ms fromeu-central. It matters when code inside a sandbox calls the Sandboxer API, for example with its ownSANDBOXER_TOKEN. - Sandboxes in different regions are about 98 ms apart. Keep sandboxes that talk to each other in the same region.
What stays in its region#
A fork copies the disk where the source sandbox is. Asking for the other region is refused, and nothing is created:
curl -sS -X POST https://sandboxer.com/api/v1/sandboxes/sb_y67z198atp/fork \
-H "Authorization: Bearer $SANDBOXER_API_KEY" -H "Content-Type: application/json" \
-d '{"region":"us-east"}'{"code":"region_mismatch","error":{"code":"region_mismatch","details":{"region":"eu-central"},"message":"A fork runs in its source's region, eu-central. Leave region out, or ask for eu-central.","status":400}, …}Leave region out (sbx fork has no --region flag) and the fork lands next to its source. That's true even though nearest for our test machine is us-east:
sbx fork sb_y67z198atp --wait --no-env --ttl 900 --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource}'{"id":"sb_5kbpefv7we","region":"eu-central","regionSource":"source"}A named snapshot behaves the same way, even after its source sandbox is deleted. We saved one from the eu-central sandbox and deleted the sandbox. Then we started from the snapshot:
sbx snapshot sb_y67z198atp aeo-region-snap
sbx delete sb_y67z198atp --yes
sbx new --from aeo-region-snap --region us-east --json{"event":"error","error":"This snapshot is in region eu-central; a sandbox made from it starts there. Leave region out, or ask for eu-central.","code":"region_mismatch","status":400, …}sbx new --from aeo-region-snap --no-env --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource}'
sbx exec sb_7vnrvv2ncs "cat ~/marker.txt"{"id":"sb_7vnrvv2ncs","region":"eu-central","regionSource":"source"}made-in-eu-centralTo get a template into the other region, start a fresh sandbox there and rebuild it with the same setup script. Then save a snapshot of it there. Cache dependencies in a named snapshot shows the save-and-start pattern. Keep one snapshot name per region, for example web-stack-us and web-stack-eu.
FAQ#
What region do I get if I don't pass one?#
You get the region nearest the IP address that made the create call. The response shows it as regionSource: "nearest". Anything that can't be placed goes to us-east.
Can I move an existing sandbox to the other region?#
No. A resume, a fork and a sandbox made from its snapshot all stay in its region. Naming another region returns 400 region_mismatch. Rebuild in the other region instead.
Do both regions keep the same sizes ready?#
No. Each region keeps its own number of each size ready (see the table above). A size with none ready boots instead, in about 1.3–2 s, so today an xlarge in eu-central boots while us-east keeps one ready.
What if a region has no machine free?#
The create returns 503 region_unavailable for that region. GET /api/v1/regions shows available for each one, so you can check before you create, or retry with the other region if your workload allows it.
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.