# How to open a public TCP port on a sandbox Run `runtime ports open 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 October 2026, [network products](/docs/pricing#network-products)). That suits anything that is not HTTP: Postgres, Redis, MQTT, the TCP side of a game server, or your own protocol. A 2 vCPU, 4 GiB sandbox that serves a port costs $0.03125 an hour while idle, and $0.08 an hour with both CPUs busy ([pricing](/docs/pricing)). ## Open a port ```bash no-run runtime ports open 5432 # 203.0.113.10:23456 psql "postgres://app@203.0.113.10:23456/app?sslmode=require" ``` ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); const sbx = await runtime.sandboxes.create(); const db = await runtime.ports.open({ sandboxId: sbx.id, port: 5432 }); console.log(db.connect); // "203.0.113.10:23456" ``` ```python check from withruntime import Runtime runtime = Runtime() sbx = runtime.sandboxes.create() 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 ports open. An MCP agent uses `runtime_ports` with `open`, `list` and `close`. ## Run the service so it keeps answering Start the server with `spawn`. It keeps running after your call returns. Anything an `exec` starts ends with its command, even when it runs as `nohup … &`: ```bash no-run runtime sandboxes exec -- sh -c 'sudo apt-get update && sudo apt-get install -y redis-server' runtime sandboxes spawn -- redis-server --protected-mode no --requirepass "$REDIS_PASSWORD" runtime ports open 6379 ``` Any server installed with `apt-get`, `pip` or `npm` can serve this way. Or bake the server into a [custom image](/docs/images), 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=require` above does. - **Expecting UDP.** Only TCP is carried. 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 sandbox without credit.** The response is `payment_required` (402). Ports need a paid account and a paid sandbox. - **Too many ports.** Past the limits above, the response is `quota_exceeded` (409: close one first) or `rate_limited` (429). `no_capacity` (503) means no public port is free just now ([errors](/docs/networking#errors)). - **A paused sandbox.** A connection wakes it. Its connections end when it stops, pauses or is deleted. `runtime ports ls` lists open ports. `runtime ports close ` closes one, and ends its open connections before it returns. Every connection is logged with the sandbox, the account and the client's address. The log does not include the 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](/how-to/port-forward-a-database): no public address at all | | Your own servers, privately | A [WireGuard tunnel](/how-to/connect-a-wireguard-tunnel) | | A web app at your own name | A [custom domain](/how-to/add-a-custom-domain), with HTTPS | A port forward is the safer choice for a database that only you use. It goes through Runtime's API with your key, and the sandbox opens nothing to the internet. ## Related - [TCP ports](/docs/networking#tcp-ports) in the networking guide. - [The sandbox environment](/docs/sandbox-environment): what is installed. - [Run Docker in a sandbox](/how-to/run-docker-in-a-sandbox) to serve a containerised database. Facts on this page were checked on 26 October 2026.