# How to port-forward a database from a sandbox to your machine Run `runtime sandboxes port-forward 5432`. `localhost:5432` on your machine then reaches Postgres inside the sandbox. **On Runtime, a port forward exposes nothing publicly. It runs through Runtime's API with your key, and the sandbox never opens a port to the internet.** Any TCP port works, not only HTTP. So Postgres, MySQL, Redis, a debugger or a dev server with WebSockets all reach your laptop the same way. A paused sandbox wakes when the connection arrives. The database runs in a Firecracker microVM. At 2 vCPU and 4 GiB, it costs $0.03125 an hour while it waits for queries ([pricing](/docs/pricing)). ## Forward Postgres Install and start the database in the sandbox with `spawn`, which keeps it running. Then forward its port: ```bash no-run runtime sandboxes exec -- sh -c 'sudo apt-get update && sudo apt-get install -y postgresql' runtime sandboxes spawn -- sudo -u postgres /usr/lib/postgresql/16/bin/postgres -D /var/lib/postgresql/16/main -c config_file=/etc/postgresql/16/main/postgresql.conf runtime sandboxes port-forward 5432 # localhost:5432 here is 5432 in the sandbox psql -h 127.0.0.1 -p 5432 -U postgres ``` Those are the paths of Ubuntu 24.04's PostgreSQL 16 package. A process started by `exec` ends with its command, `nohup … &` included. That is why the server starts with `spawn`. The server may listen on `127.0.0.1`, `::1` or every address inside the sandbox. `port-forward` listens on `127.0.0.1` on your side unless you pass `--address`. It runs until you press Ctrl-C. It says so when nothing listens on the port. ## Several ports, or a different local port ```bash no-run runtime sandboxes port-forward 3000 15432:5432 # local:remote; 3000 as 3000, 5432 as 15432 ``` A local database already on 5432 keeps that port. The sandbox's port arrives at 15432. ## From code The SDKs open the same forward from a test or a script. `localPort: 0` picks a free port: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create(); await sbx.exec("sudo apt-get update && sudo apt-get install -y redis-server", { check: true, timeoutMs: 300_000, }); await sbx.spawn("redis-server --port 6379"); const forward = await sbx.forwardPort(6379, { localPort: 0 }); console.log(`redis://127.0.0.1:${forward.localPort}`); await forward.close(); ``` ```python check from withruntime import Sandbox with Sandbox.create() as sbx: sbx.exec("sudo apt-get update && sudo apt-get install -y redis-server", check=True, timeout_ms=300_000) sbx.spawn("redis-server --port 6379") with sbx.forward_port(6379, local_port=0) as forward: print(f"redis://127.0.0.1:{forward.local_port}") ``` In JavaScript, `sbx.tunnel()` opens one connection at a time instead. `tunnel.connect(5432)` gives a stream to the port, for a driver that accepts one. ## Limits | Limit | Value | | --------------------------------------------- | ----------------------------------------------------------- | | Ports | Any TCP port except 10800, the sandbox's own outbound proxy | | Connections through one forward | 64 at the same time | | SSH logins and forwards open at the same time | 16 per organization | | Longest forward | 24 hours; open it again to go on | | Local listen address | `127.0.0.1` unless `--address` says otherwise | ## Mistakes and how Runtime handles them - **"Nothing listens on the port."** The server was started with `exec` and ended, or it has not finished starting. Start it with `spawn`. Check it with `runtime sandboxes ps ` and `runtime sandboxes logs `. - **The forward drops at a time limit.** An open forward keeps a sandbox running. A sandbox has no time limit by default, and it runs while credit or the free usage lasts. One created with `--timeout` still ends at its limit. Leave the limit out, or extend it (`runtime sandboxes extend 3600`). - **A connection pool larger than 64.** One forward carries at most 64 connections at the same time. Size the pool below that. - **Sharing the forward with teammates.** `--address` can listen on another interface. But each teammate can run their own forward with their own key instead, and nothing is exposed. ## Forward, public port or tunnel? A forward is for you, from your own machine, for as long as you work. When clients elsewhere must connect, a paid account can [open a public TCP port](/how-to/open-a-tcp-port). When your own servers need steady private access to many sandboxes, use a [WireGuard tunnel](/how-to/connect-a-wireguard-tunnel). The same forward serves a published Docker port. See [run Docker in a sandbox](/how-to/run-docker-in-a-sandbox). ## Related - [Forward ports](/docs/editors#forward-ports) in the SSH and editors guide. - [SSH into a sandbox](/how-to/ssh-into-a-sandbox). - [The sandbox environment](/docs/sandbox-environment). ## Start ```bash no-run npx withruntime sandboxes run --keep -- true ``` A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card needed. Facts on this page were checked on 26 October 2026.