Remote ports

A dev server running on a runner can be opened in the browser on your own machine. Strado forwards the port through the same tunnel the runner already holds open.

How it reaches you

Your machine binds a listener on loopback and pipes it to the runner's port through the relay. Nothing on either machine is exposed to the network: the listener is 127.0.0.1 only, and the runner still opens no inbound port.

Heads up

The local port is not the remote port. The forwarder always takes an arbitrary free port on your machine, so a dev server on the runner's 8080 might arrive at localhost:59022. Strado tells you which one — do not assume the numbers match. This is deliberate: the remote port is never claimed locally, so a runner's dev server can never collide with your own.

The forwarding runs in its own process rather than inside the server that enumerates your worktrees, so a heavy page load cannot slow the rest of the app down.

What the runner will let through

Not every port. A runner only forwards ports it can account for: the ports its own worktrees are configured to use, its repos' default ports, and anything the operator has opted into by hand in ~/.strado/runner.env.

That is defence in depth rather than a security boundary — anyone who can open a forward already has a shell on the box through the same tunnel — but it means a bug or a stolen ticket cannot turn into an enumeration of the runner's loopback, and a refusal in the log means something.

Latency, honestly

Note

Measured on one setup — a Mac and a runner on the same LAN, with the relay in Mumbai. Treat these as the shape of the problem, not a guarantee.

MeasureResult
Median per request~170 ms
Bulk transfer5 MB in 1.67 s, about 3.1 MB/s
Terminal round trip64 ms median

Bulk transfer is fine. Request count is what hurts. At ~170 ms each, a cold page making 200 requests costs roughly 34 seconds serialised, or about 6 across a browser's usual six connections. A page that is already loaded, doing hot module reloads of a few small messages, feels fine.

The reason is the route rather than the distance: every request goes from your machine to the relay and back down the runner's tunnel, even when the runner is five milliseconds away on your own LAN.

When the runner goes away

Connections reset immediately rather than hanging, and the mapping is kept and marked unreachable rather than deleted. When the runner comes back, the forward resumes on the same local port — measured at about five seconds — so a browser tab you left open keeps working instead of pointing at nothing.

Where to go next