How to open a public TCP port on a sandbox
Run runtime port open <sandbox> 5432; it prints a public address:port that carries raw TCP to that port in the sandbox.
On Runtime a public TCP port costs nothing extra: ports are included with a paid account, and you pay only for the sandbox (pricing checked 25 September 2026, network products). That suits anything that is not HTTP: Postgres, Redis, MQTT, a game server's TCP side, or your own protocol. A 2 vCPU, 4 GiB sandbox serving it costs $0.03125 an hour while idle and $0.08 an hour with both CPUs busy (pricing).
Open a port
Terminalruntime port open <sandbox> 5432# 203.0.113.10:23456psql "postgres://app@203.0.113.10:23456/app?sslmode=require"TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();const sbx = await runtime.sandboxes.create({ funding: "paid" });const db = await runtime.ports.open({ sandboxId: sbx.id, port: 5432 });console.log(db.connect); // "203.0.113.10:23456"Pythonfrom withruntime import Runtimeruntime = Runtime()sbx = runtime.sandboxes.create(funding="paid")db = runtime.ports.open(sandbox_id=sbx.id, port=5432)print(db["connect"]) # "203.0.113.10:23456"The public port is chosen for you. Opening the same sandbox and port again
returns the same public port, so a retry never leaves two open. An MCP agent
uses runtime_port_open, runtime_port_list and runtime_port_close.
Run the service so it keeps answering
Start the server with spawn, which keeps it running after your call returns.
Everything an exec starts, nohup … & included, ends with its command:
Terminalruntime sandbox exec <sandbox> -- sudo apt-get install -y redis-serverruntime sandbox spawn <sandbox> -- redis-server --protected-mode no --requirepass "$REDIS_PASSWORD"runtime port open <sandbox> 6379Any server installed with apt-get, pip or npm can serve this way, or
bake the server into a custom image so every sandbox starts
with it.
Limits
| Limit | Value |
|---|---|
| Price | Included with a paid account |
| Ports per sandbox | 5 |
| Ports per account | 20 |
| Opened per day | 50 |
| Open connections, all of a sandbox's ports | 256 |
| New connections a second | 50 |
| Connections from one client address | 32 |
| Protocol | TCP only; UDP is not carried |
| Bandwidth and daily bytes | The sandbox's outbound limits |
Mistakes and how Runtime handles them
- No password on the service. Anyone who knows the address can connect.
Runtime carries the bytes as they are; use your service's own authentication
and TLS, as the
sslmode=requireabove does. - Expecting UDP. Only TCP is carried, so QUIC and most game servers' own traffic will not arrive. A TCP protocol works unchanged.
- Reusing an address after closing it. A closed port rests for a day before anyone else can be given it, so a client still pointed at it never reaches someone else's service.
- A trial sandbox. The answer is
payment_required(402): ports need a paid account and a paid sandbox. - Too many ports. Past the limits above the answer is
quota_exceeded(409) orrate_limited(429);no_capacity(503) means no public port is free just now (errors). - A paused sandbox. A connection wakes it. Its connections end when it stops, pauses or is deleted.
runtime port ls lists open ports and runtime port close <portId> closes
one. Every connection is logged with the sandbox, the account and the client's
address, without its contents.
Public port, forward or tunnel?
| You want | Use |
|---|---|
| Clients anywhere to connect | A public TCP port (this page) |
| Only you, from your laptop | Port forwarding: no public address at all |
| Your own servers, privately | A WireGuard tunnel |
| A web app at your own name | A custom domain, with HTTPS |
A port forward is the safer choice for a database only you use: it goes through Runtime's API with your key, and the sandbox opens nothing to the internet.
Related
- TCP ports in the networking guide.
- The sandbox environment: what is installed.
- Run Docker in a sandbox to serve a containerised database.
Facts on this page were checked on 25 September 2026.