Skip to main content

Basic Usage

Expose a local service by specifying the port:
rs-tunnel up --port 3000
The CLI will:
  1. Start a local reverse proxy
  2. Create a Cloudflare tunnel
  3. Register a DNS record at <random-slug>.<base-domain>
  4. Display an ngrok-style dashboard
Without the --url flag, the server assigns a random slug for your tunnel hostname.

Custom URL Slug

Specify a custom slug for your tunnel URL:
rs-tunnel up --port 3000 --url my-app
This creates a tunnel at https://my-app.<base-domain> forwarding to http://localhost:3000.
Single-label slugs only: Nested domains are not allowed. Use my-app, not my.app or app.subdomain.

Verbose Mode

Show raw cloudflared output alongside the dashboard:
rs-tunnel up --port 3000 --verbose
Verbose mode displays:
  • Standard dashboard metrics
  • Raw cloudflared connection logs
  • Region/datacenter information from cloudflared
Use --verbose when debugging connection issues or when you need to see detailed cloudflared diagnostics.

Runtime Dashboard

When a tunnel starts, the CLI displays an ngrok-style dashboard:
Account       [email protected]                                       Region     IAD
Version       0.1.2                                                 Latency    45ms
Forwarding    https://my-app.tunnel.example.com -> http://localhost:3000

Connections   ttl     opn     rt1     rt5     p50     p90
              142     3       1.2s    1.4s    125ms   380ms

HTTP Requests
-------------------------------------------------------------------------------
POST /api/users                      200 OK                            
GET  /health                         200 OK                            
GET  /api/products                   200 OK                            

Dashboard Metrics

Connection Stats

ttl: Total requests processed
opn: Currently open connections
rt1: Average response time (1 min)
rt5: Average response time (5 min)
p50: 50th percentile latency
p90: 90th percentile latency

Request Stream

Live HTTP requests showing:
  • HTTP method and path
  • Status code
  • Timestamp
    Real-time as requests flow through your tunnel
Region and Latency are best-effort metrics derived from cloudflared logs. They may show n/a if cloudflared doesn’t emit region information.

How It Works

1

Local Reverse Proxy

The CLI starts a reverse proxy on an ephemeral localhost port. This proxy:
  • Forwards requests to your target port
  • Tracks connection metrics
  • Captures request/response data for the dashboard
2

Tunnel Creation

The API server:
  • Creates a new Cloudflare tunnel
  • Registers DNS record: <slug>.<base-domain> → tunnel
  • Returns a short-lived tunnel token
3

Cloudflared Process

The CLI spawns cloudflared with the tunnel token, establishing a secure connection to Cloudflare’s edge.
4

Heartbeat Loop

Every 20 seconds (configurable), the CLI sends a heartbeat to the API to maintain the tunnel lease.

Automatic Cleanup

Tunnels are automatically stopped when:
  • You press Ctrl+C or send SIGINT/SIGTERM
  • The CLI process exits normally
  • The cloudflared process terminates
On graceful shutdown, the CLI:
  1. Stops the remote tunnel (removes DNS record)
  2. Kills the cloudflared process
  3. Stops the local reverse proxy

Tunnel Quotas

The server enforces a maximum number of active tunnels per user:
Default limit: 5 active tunnels per user. Attempting to create more will fail with a quota exceeded error.
To free up quota, stop tunnels you’re no longer using:
rs-tunnel list
rs-tunnel stop <tunnel-id-or-hostname>

Stale Tunnel Cleanup

If the CLI crashes or loses connectivity:
  • The server monitors heartbeats from all active tunnels
  • Tunnels without heartbeats for 60 seconds (configurable) are marked stale
  • A reaper process runs every 30 seconds to clean up stale tunnels
  • DNS records are automatically removed
If you kill the CLI forcefully and your tunnel is still active, it will be automatically cleaned up within ~60 seconds.

Examples

Local Web Server

# Expose a Next.js dev server
rs-tunnel up --port 3000 --url my-nextjs-app

API Development

# Share your local API with a frontend team
rs-tunnel up --port 8080 --url backend-api

Webhook Testing

# Test webhooks from Stripe, GitHub, etc.
rs-tunnel up --port 4000 --url webhook-receiver --verbose

Random URL

# Quick share without picking a name
rs-tunnel up --port 5000
# Generates: https://x7k2p9m.tunnel.example.com

Next Steps

Manage Tunnels

List and stop active tunnels

Configuration

Customize API domain and behavior

Build docs developers (and LLMs) love