SwitchProxy is a TCP proxy that enables live traffic switching between two backend servers without dropping connections. It's designed for zero-downtime database migrations where you need to redirect client traffic from one server to another.
SwitchProxy sits between your clients and backend servers, forwarding TCP traffic to a selected upstream server. When you switch backends, existing connections are seamlessly reconnected to the new server.
┌─────────────────┐
│ Server 1 │
┌─────────┐ │ (e.g., old DB) │
│ Clients │ ──────► │─────────────────│
└─────────┘ │ SwitchProxy │
│─────────────────│
│ Server 2 │
│ (e.g., new DB) │
└─────────────────┘switchproxy <api_addr> <listen_addr> <server1_addr> <server2_addr>Arguments:
| Argument | Description | Example |
|---|---|---|
api_addr | Control API listen address | 127.0.0.1:8009 |
listen_addr | Client connection listen address | 127.0.0.1:6379 |
server1_addr | Default backend server (server 1) | 10.0.0.1:6379 |
server2_addr | Alternate backend server (server 2) | 10.0.0.2:6379 |
Example:
# Start switchproxy for Redis migration
# - Control API on port 8009
# - Clients connect to port 6379
# - Server 1: old Redis on port 6378
# - Server 2: new Redis on port 6377
switchproxy 127.0.0.1:8009 127.0.0.1:6379 127.0.0.1:6378 127.0.0.1:6377SwitchProxy exposes a simple HTTP API for controlling traffic routing.
curl http://localhost:8009/routeResponse: Returns 1 or 2 indicating which server is currently selected.
# Switch to server 1
curl -X POST http://localhost:8009/route/1
# Switch to server 2
curl -X POST http://localhost:8009/route/2Response: Returns the previous server selection.
SwitchProxy also accepts commands via stdin for interactive control:
1 and press Enter to switch to server 12 and press Enter to switch to server 2Ctrl+C to shutdownHere's a complete example of using SwitchProxy for a Redis migration:
# Old Redis: localhost:6378
# New Redis: localhost:6377
# Clients will connect to: localhost:6379
switchproxy 127.0.0.1:8009 127.0.0.1:6379 localhost:6378 localhost:6377# Check current route (should be 1)
curl http://localhost:8009/route
# Output: 1
# Connect a client through the proxy
redis-cli -p 6379 SET mykey "hello"
redis-cli -p 6379 GET mykey
# Output: "hello"Sync data from old Redis to new Redis using your preferred method (e.g., DUMP/RESTORE, replication, or Eden migrations).
# Switch all traffic to the new server
curl -X POST http://localhost:8009/route/2
# Output: 1 (previous selection)
# Verify the switch
curl http://localhost:8009/route
# Output: 2# Clients are now transparently connected to the new server
redis-cli -p 6379 GET mykey
# Output: "hello" (from new server)- Notifies all active connection handlers
- Each handler closes its current upstream connection
- Immediately reconnects to the new backend server
- Continues relaying traffic without dropping the client connection
| Variable | Description | Default |
|---|---|---|
EDEN_LOG_LEVEL | Log levels to emit, semicolon-separated (info;warn) | All compiled logs |
RUST_LOG | Tracing subscriber filter (trace, debug, info, etc.) | info |
SwitchProxy uses Eden's logging system which supports two-tier filtering:
# Show only info and warn logs
EDEN_LOG_LEVEL=info;warn switchproxy 127.0.0.1:8009 127.0.0.1:6379 localhost:6378 localhost:6377
# Show only error logs
EDEN_LOG_LEVEL=error switchproxy 127.0.0.1:8009 127.0.0.1:6379 localhost:6378 localhost:6377
# Disable all logs
EDEN_LOG_LEVEL=none switchproxy 127.0.0.1:8009 127.0.0.1:6379 localhost:6378 localhost:6377
# Enable debug-level tracing output
RUST_LOG=debug switchproxy 127.0.0.1:8009 127.0.0.1:6379 localhost:6378 localhost:6377Note: If EDEN_LOG_LEVEL is not set, all compiled logs are emitted. When set, only the specified levels are shown.
SwitchProxy can be used as part of an Eden migration workflow:
See Redis Migration Demo for a complete example using Eden migrations with traffic switching.