How the WebSocket Relay Works
Architecture Overview
ReqPour's relay system uses WebSocket connections to forward webhook requests from the cloud to your local development server. The architecture has three components: the ReqPour server (cloud), the ReqPour CLI (your machine), and your local development server.
When you run npx reqpour relay --to http://localhost:3000, the CLI establishes a persistent WebSocket connection to the ReqPour server at wss://api.reqpour.com/relay. The connection is authenticated using your account token and associated with your endpoint.
When a webhook request arrives at your endpoint URL, the ReqPour server captures it in the database (for the dashboard) and checks if there is an active WebSocket connection for that endpoint. If there is, the server pushes the request through the WebSocket to the CLI.
Request Flow
The complete request flow works as follows:
1. A webhook provider sends an HTTP POST to https://abc123.reqpour.com/path
2. The ReqPour server receives and stores the request
3. The server serializes the request (method, path, headers, body) and sends it through the WebSocket to the CLI
4. The CLI receives the serialized request
5. The CLI makes a local HTTP request to your target URL (http://localhost:3000/path)
6. Your local server processes the request and returns a response
7. The CLI sends the response back through the WebSocket to the ReqPour server
8. The ReqPour server forwards the response to the original webhook sender
The entire round trip typically takes 20-100ms depending on your internet connection and local server processing time. The ReqPour dashboard shows this timing breakdown.
Connection Management
The WebSocket connection includes automatic reconnection logic. If the connection drops due to a network issue, the CLI automatically attempts to reconnect with exponential backoff. During disconnection, incoming webhook requests are still captured and stored in the dashboard — they just are not forwarded until the connection is restored.
The connection uses WebSocket ping/pong frames to detect and handle dead connections. The server sends pings every 30 seconds, and the CLI responds with pongs. If three consecutive pings go unanswered, the server considers the connection dead and cleans up the relay association.
Multiple CLI instances can connect to the same endpoint. In this case, the server round-robins requests across active connections. This is useful for load testing or running relays on multiple development machines.
Data Serialization
Requests are serialized as JSON messages over the WebSocket:
{
"type": "request",
"id": "req_abc123",
"method": "POST",
"path": "/webhooks/stripe",
"headers": {
"content-type": "application/json",
"stripe-signature": "t=123,v1=abc..."
},
"body": "{"type":"payment_intent.succeeded",...}"
}The body is transmitted as a string (for JSON) or base64-encoded (for binary data). Headers are preserved exactly as received, including case and duplicates.
Responses flow back in the same format:
{
"type": "response",
"requestId": "req_abc123",
"status": 200,
"headers": {
"content-type": "application/json"
},
"body": "{"received":true}"
}This bidirectional communication means the webhook provider receives your actual server's response, not just a generic acknowledgment from ReqPour.
Performance and Limitations
The relay adds minimal overhead to request processing. The WebSocket connection is persistent (no connection setup per request), and JSON serialization/deserialization is fast. Most of the latency comes from the network round trip between your machine and the ReqPour server.
Current limitations: the relay handles HTTP requests only (not raw TCP or UDP). Maximum request body size is 10MB. The WebSocket connection requires a stable internet connection — intermittent connections will cause relay interruptions (though requests are still captured in the dashboard).
For development, these limitations are rarely an issue. Webhook payloads are almost always well under 1MB, and the HTTP-only restriction matches webhook use cases perfectly. If you need to handle larger payloads or non-HTTP protocols, consider a general-purpose tunneling tool for those specific cases.
Related
Get started with ReqPour
Catch, inspect, and relay webhooks to localhost. Free to start, $3/mo for Pro.