# How to open a public TCP port on a sandbox Run `runtime port 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 September 2026, [network products](/docs/pricing#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](/docs/pricing)). ## Open a port ```bash no-run runtime port 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({ funding: "paid" }); 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(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: ```bash no-run runtime sandbox exec -- sudo apt-get install -y redis-server runtime sandbox spawn -- redis-server --protected-mode no --requirepass "$REDIS_PASSWORD" runtime port 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, 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) 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 port ls` lists open ports and `runtime port close ` 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](/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 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 25 September 2026.