Bind a tunnel to a test
Use a tunnel dependency when the app under test runs on your laptop, a build agent or a private network.
Runners live in the cloud and cannot reach localhost. A tunnel gives the app a public
address, and the dependency hands that address to the script. Leave it out when the app already has a
public URL.
Bind a tunnel
Section titled “Bind a tunnel”- Create a named tunnel and copy its client token. See Create a tunnel. Guest tunnels have no account and cannot be bound.
- Open the test, go to Dependencies and click Add dependency.
- Select the Tunnel kind and pick the tunnel under Choose a tunnel.
- Type an Env var name, for example
SHOP. The hint showsMAXOPERF_TUNNEL_SHOP_URL. - Click Add.
The tunnel and the test must live in the same workspace. The API answers 404 when they do not.
The injected value is the tunnel’s public address, for example https://myapp.maxoperf-tunnel.com.
Open it in the script like any other URL:
await page.goto(process.env.MAXOPERF_TUNNEL_SHOP_URL!);Start the client before the run
Section titled “Start the client before the run”A run cannot start your tunnel client, because the client is a process on your machine. Start it first:
npx @maxoperf/tunnel http 3000 --token <your-tunnel-token> --name myappThen start the run. What the run does depends on the tunnel’s state:
| Tunnel state | What the run does |
|---|---|
| Online | The lease is ready at once. |
| Stopped manually or by its idle timeout | The run reactivates the tunnel and waits for your client to connect. |
| Stopped by the plan limit or by its expiry (TTL) | The run fails and names the reason: “was stopped by plan limit; start it manually” or “was stopped by expiry; start it manually”. |
If your client has not connected when the dependency timeout passes (600 seconds by default), the run fails with “did not come online within 600s”. Start the tunnel from its page or with the CLI, then rerun.
While the run is live
Section titled “While the run is live”A run never stops a tunnel, even one it reactivated. The client is your process, so you stop it. While a run holds the tunnel, the idle timeout does not stop it. The expiry (TTL) is a hard cap and still ends the tunnel mid-run. When the run ends, the lease is released and the tunnel stays as it was, and its idle timeout applies again.
If the tunnel goes offline during the run, for example because its expiry passed, MaxoPerf marks the
lease Degraded on the run’s Dependencies tab and fires the tunnel_disconnected_during_run
notification. The check runs about once a minute.
The tunnel’s own access controls (authentication mode, IP allow and deny lists, rate limit and maximum body size) apply to the run’s traffic as they do to any visitor. The run’s row links to Open stats, which shows the tunnel’s traffic for the run’s time window.
Spot localhost early
Section titled “Spot localhost early”If you type a localhost address into an HTTP request URL or a browser step, the builder shows “Runners
can’t reach localhost” with a tunnel picker beside it. Pick a tunnel and the field becomes a chip.
Next steps
Section titled “Next steps”- Tunnels: access controls, statistics and reconnect behavior.
- Run-time behavior: lease states and failures.
- Automate: bind through the API.