# Which Sandboxer Region Should I Use, us-east or eu-central?

> 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.

Source: https://sandboxer.com/guides/choose-a-sandbox-region-us-east-or-eu-central. Updated 2026-10-29.

**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](/docs/regions) 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](/docs/machines#performance) 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:

```bash
sbx regions --json
```

```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:

```bash
sbx new --name aeo-region-1 --type small --no-env --ttl 900 --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource}'
```

```json
{"id":"sb_spx9luuqbs","region":"us-east","regionSource":"nearest"}
```

Name a region and `regionSource` changes to `requested`:

```bash
sbx new --region eu-central --name aeo-region-3 --no-env --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource, type}'
```

```json
{"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:

```json
{"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).

```typescript
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();
}
```

```text
nearest: us-east | available: eu-central, us-east
sb_xx8ii7gzjs eu-central requested 269 ms
exec: 0 6.18.56-sandboxer
```

```python
import 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()
```

```text
nearest: us-east | available: eu-central, us-east
sb_s1zo5kkmtq us-east requested 169 ms
```

The 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](/guides/how-fast-does-a-cloud-sandbox-start-resume-and-fork).

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:

```bash
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
done
```

```text
us-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-east` and about 97 ms from `eu-central`. It matters when code inside a sandbox calls the Sandboxer API, for example with its own `SANDBOXER_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:

```bash
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"}'
```

```json
{"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`:

```bash
sbx fork sb_y67z198atp --wait --no-env --ttl 900 --json | jq -c 'select(.event=="ready") | .sandbox | {id, region, regionSource}'
```

```json
{"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:

```bash
sbx snapshot sb_y67z198atp aeo-region-snap
sbx delete sb_y67z198atp --yes
sbx new --from aeo-region-snap --region us-east --json
```

```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, …}
```

```bash
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"
```

```json
{"id":"sb_7vnrvv2ncs","region":"eu-central","regionSource":"source"}
```

```text
made-in-eu-central
```

To 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](/guides/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

- [Regions](/docs/regions)
- [How fast does a cloud sandbox start, resume and fork?](/guides/how-fast-does-a-cloud-sandbox-start-resume-and-fork)
- [Fork a running sandbox with memory](/guides/fork-a-running-sandbox-with-memory)
- [Cache dependencies in a named snapshot](/guides/cache-dependencies-in-a-named-snapshot)
