Browse documentation
Under the wire
One connection. Many independent streams.
From localhost to the public edge
The client authenticates to the server, requests a tunnel, and receives its public address. New incoming requests become streams on the existing connection. The client forwards those streams to your local application.
A purpose-built binary protocol
The wire protocol starts with magic bytes WRF and version 1. Each frame has a 9-byte header: version, type, a 3-byte stream ID and a 4-byte payload length.
+---------+------+----------+--------+
| Version | Type | StreamID | Length |
| 1 byte | 1 B | 3 bytes | 4 B |
+---------+------+----------+--------+
| Payload (variable) |
+----------------------------------+Multiplexing and backpressure
Independent streams share one TCP connection. Per-stream flow control provides backpressure; heartbeat frames keep track of connection liveness. The client reconnects with exponential backoff and recreates tunnels after a dropped connection.
A deliberately small runtime
The server and client use the Go standard library. Release binaries are built for multiple operating systems and CPU architectures. You can run the server directly or use the repository's Dockerfile and Compose configuration.