Skip to content

Moving from E2B to OpenDsec ​

OpenDsec's E2B gateway (opendsec-e2b) serves the API that E2B's SDKs talk to. Code written for E2B, and agent frameworks built on its SDKs, run on your own OpenDsec cluster without changes: you point the SDK at the gateway and use an OpenDsec token as the API key. The design and its tests are in SPEC §37.

For callers: three environment variables ​

sh
export E2B_API_URL=http://<gateway>:7400       # https://... when TLS is on
export E2B_SANDBOX_URL=http://<gateway>:7400
export E2B_API_KEY=<your OpenDsec token>         # dsk.<id>.<secret>
python
from e2b import Sandbox

sbx = Sandbox.create()                          # template "base"
print(sbx.commands.run("python3 -V").stdout)
sbx.files.write("/tmp/a.txt", "hello")
sbx.kill()

E2B's JS SDK needs Node.js 22.19 or newer (Ubuntu 24.04's own nodejs is 18: take Node from nodejs.org):

js
import { Sandbox } from 'e2b'

const sbx = await Sandbox.create()
console.log((await sbx.commands.run('python3 -V')).stdout)
await sbx.kill()

The code interpreter works the same way, on a template your administrator built for it (see below):

python
from e2b_code_interpreter import Sandbox

sbx = Sandbox.create("code-interpreter-v1")
print(sbx.run_code("6 * 7").text)               # 42

Your token's permissions, quota and audit trail apply as for any OpenDsec call: the gateway keeps no state of its own and makes every call with your token.

What works ​

Checked with E2B's Python SDK (sync and async), JS/TS SDK and code interpreter SDKs (test/e2e/testdata/e2b_*):

AreaSupported
Sandboxescreate, connect, get_info, list, kill, set_timeout, is_running, metadata, environment variables
Commandsoutput and streaming, exit codes, envs, cwd, background processes, stdin, kill, list, reconnecting
Terminalspty.create, input, resize
Filesread, write (any size, 2 MB chunks), list, make_dir, rename, remove, exists, get_info
Portsget_host(port): HTTP, streamed responses, WebSocket to a server in the sandbox
Code interpreterrun_code with results, logs, errors, charts, pandas tables, contexts, envs
Fork and snapshotsfork(count), create_snapshot(name), list_snapshots, delete_snapshot, Sandbox.create(snapshot_id); on microVMs memory is kept, so running processes carry over
Lifecyclepause, resume through connect, lifecycle={"on_timeout": "pause"} (autoPause), the refresh keepalive
Networkallow_internet_access, network={"allow_out": [...], "deny_out": ["0.0.0.0/0"]}, update_network

What differs ​

E2BOpenDsec gateway
API keyE2B keyan OpenDsec token
Templatesbuilt by E2B's template buildnames an administrator maps to an OpenDsec image, backend and size in the cluster config; an OpenDsec image name (root/py:3.12) also works. No template build API
Sandbox portspublic access can be enabledalways need the token (the SDKs send it); no plain browser access
Paused sandboxesresumed by traffic only with autoResumeany call resumes them
After an auto-resumethe original timeout restartsthe idle timeout applies
Filesystem-only pausessupportedrefused (400): pauses keep memory
Filesystem-only snapshotssupportedrefused (400) on microVMs; container snapshots are filesystem-only (no memory to keep)
Egress denialsany CIDRonly all traffic (0.0.0.0/0); everything else is allowed by rule
Domain rules*.example.com covers subdomainsalso covers example.com itself
envVars given at creation, in run_codeappliednot applied (pass envs to run_code)
Code interpreter kernelsPython, JavaScript, R, Java, BashPython
Not availablewatching directories, signed file URLs, MCP, volumes, metrics (an empty list), request transform rules, egress proxy

An option the gateway cannot honour is refused with 400 rather than ignored, so a program never runs with settings it did not get.

Speed ​

Measured through the gateway on microVMs (Firecracker), on the project's bare-metal test hosts (AMD EPYC 9Y24), 2026-10-23:

Time
Sandbox.create(), template base (2 vCPU, 1 GB, cold boot)p50 166 ms
First command after creationp50 12 ms
Sandbox.create("code-interpreter-v1") (2 GB memory snapshot)about 250 ms
First run_codeabout 40 ms
fork(count=2)about 100–150 ms
create_snapshot()about 40–70 ms
Sandbox.create(snapshot_id)about 65–85 ms

For administrators ​

  1. Add an e2b section to the cluster config and roll it out (docs/OPERATIONS.md §4, "E2B 网关"):
    json
    "e2b": {
      "gateways": [{"addr": "10.0.0.11:7400"}, {"addr": "10.0.0.12:7400"}],
      "project": "root/e2b",
      "templates": {"base": {"image": "root/py:3.12", "backend": "microvm", "cpu": 2, "memory_mb": 1024}},
      "max_timeout_s": 86400
    }
  2. Give nodes the fleet role e2b=<index>, one at a time (opendsecctl fleet node set then fleet node sync).
  3. Put a load balancer in front: TCP 7400, health check HTTP 9467 /readyz, idle timeout at least 60 s. Terminate TLS there, or set tls_cert and tls_key on the gateways.
  4. Give callers tokens with sandbox.create and sandbox.operate on the project and layer.use on the images' projects. Snapshots also need layer.publish on the project, since a snapshot is an image there.
  5. The code interpreter needs its template: deploy/e2b/build-code-interpreter.py builds root/code-interpreter:v1, a memory snapshot of a microVM running E2B's code-interpreter server, and the template entry maps a name to it.
  6. As on E2B, sandboxes made through the gateway can reach the internet unless the caller turns it off (allow_internet_access=False, or deny_out of all traffic), whatever the cluster's network.default_rules.

Implements the paper DeepSeek Elastic Compute (DSec) (arXiv:2609.22978). An independent project, not affiliated with DeepSeek.