Lifecycle
Ephemeral Box
EphemeralBox is a lightweight, short-lived sandbox that provides only exec and file operations. It's designed for quick, disposable compute tasks where a full Box (with agent, git, snapshots, etc.) is unnecessary.
Creation
box.ts
import { EphemeralBox } from "@upstash/box"const box = await EphemeralBox.create({ runtime: "node", // "node" | "python" | "golang" | "ruby" | "rust" ttl: 3600, // seconds, max 259200 (3 days), default 259200 name: "my-ephemeral-worker", // optional networkPolicy: { mode: "allow-all" }, // optional})box.py
from upstash_box import EphemeralBoxbox = EphemeralBox.create( runtime="node", # "node" | "python" | "golang" | "ruby" | "rust" ttl=3600, # seconds, max 259200 (3 days), default 259200 name="my-ephemeral-worker", # optional network_policy={"mode": "allow-all"}, # optional)Key difference from Box.create(): Ephemeral boxes are ready immediately — no polling. The API returns with status: "idle" and the box is usable right away.
The request sends { ephemeral: true, ttl?, runtime? } to POST /v2/box.
Available API
| Feature | Box | EphemeralBox |
|---|---|---|
exec.command() | Yes | Yes |
exec.code() | Yes | Yes |
exec.stream() | Yes | Yes |
exec.streamCode() | Yes | Yes |
files.read/write/list/upload/download | Yes | Yes |
schedule.exec/prompt/list/get/pause/resume/delete | Yes | Yes |
cd() / cwd | Yes | Yes |
getStatus() | Yes | Yes |
delete() | Yes | Yes |
networkPolicy / updateNetworkPolicy() | Yes | Yes |
expiresAt | No | Yes |
agent.run() / agent.stream() | Yes | No |
git.* | Yes | No |
getPublicURL() / listPublicURLs() / deletePublicURL() | Yes | No |
snapshot() / fromSnapshot() | Yes | Yes |
pause() / resume() | Yes | No |
configureModel() | Yes | No |
logs() / listRuns() | Yes | No |
Properties
id— box identifier (e.g."sweet-shark-26021")expiresAt— Unix timestamp (seconds) when the box auto-deletes
How it differs from Box
- Instant creation — no polling loop; the response is the ready box
- Auto-expiry — boxes are automatically deleted after TTL;
expiresAttracks this - Reduced surface — only exec + files; no agent, git, public URLs, snapshots, pause/resume
- Simpler config —
EphemeralBoxConfighas onlyapiKey,runtime,ttl,name,networkPolicy,baseUrl,timeout,debug(no agent, git, env, skills, mcpServers) - Composition over inheritance —
EphemeralBoxwraps an internalBoxand exposes only the relevant subset, so agent/git/etc. are not accessible even at runtime
Examples
Run a shell command
box.ts
const run = await box.exec.command("echo hello")console.log(run.result) // "hello"box.py
run = box.exec.command("echo hello")print(run.result) # "hello"Execute inline code
box.ts
const result = await box.exec.code({ code: 'console.log(JSON.stringify({ sum: 1 + 2 }))', lang: "js",})box.py
result = box.exec.code( code="import json; print(json.dumps({'sum': 1 + 2}))", lang="python",)File operations
box.ts
await box.files.write({ path: "data.json", content: '{"key":"value"}' })const content = await box.files.read("data.json")box.py
box.files.write(path="data.json", content='{"key":"value"}')content = box.files.read("data.json")Clean up early
Otherwise the box auto-deletes at expiresAt.
box.ts
await box.delete()box.py
box.delete()Exported types
EphemeralBox— the classEphemeralBoxConfig— config forEphemeralBox.create()EphemeralBoxData— extendsBoxDatawithephemeral: booleanandexpires_at: number