Skip to content
rustle
Current version 1.0.0

A fast forward proxy written in Rust

HTTP/1.1, HTTPS, HTTP/2, WebSocket and SOCKS5 in one binary. One event loop per core: ~55k requests per second on one core, ~440k on eight, against ~21k (3proxy) and ~117k (Squid) for the best competitor in each case.

curl -fsSL https://raw.githubusercontent.com/EdouardCourty/rustle/main/install.sh | sh

See the benchmarksSource on GitHub

Benchmarked on Scaleway Elastic Metal servers, authentication on: 1 core per proxy, and up to 8 cores for plain HTTP. See the full benchmark data

Headline benchmark figures

Benchmarked on Scaleway Elastic Metal servers, authentication on: 1 core per proxy, and up to 8 cores for plain HTTP. See the full benchmark data

Benchmarks

rustle against 3proxy, Squid, gost and Tinyproxy

Each competitor ran with the tuning its own documentation recommends, at the connection count where it performs best.

Small requests, 1 core: 1 KB responses

req/s, higher is better.

  1. rustle55k
  2. 3proxy21k
  3. Squid15k
  4. Tinyproxy7.6k
  5. gost4.8k

1 KB responses, keep-alive. Plain HTTP proxy port.

Data table
Small requests, 1 core: 1 KB responses: req/s, measured values by proxy
ProxyVersionreq/sConnections
rustle1.0.055,25864
3proxy1.0.021,032256
Squid7.715,14064
Tinyproxy1.11.37,58064
gost3.3.04,75564

1 core per proxy · authentication on · Scaleway Elastic Metal, Paris, AMD EPYC 8224P · 25 Gbit/s private network (23.5 measured) · median of 3 runs · seed 2004113323 · campaign of 2026-10-28.

Memory with 25,000 open tunnels, 1 core

MB, lower is better.

  1. rustle95
  2. Tinyproxy274
  3. Squid912
  4. 3proxy2.5k
  5. gost3.2k

25,000 idle CONNECT tunnels held open, peak RSS of the proxy. Plain HTTP proxy port.

Data table
Memory with 25,000 open tunnels, 1 core: MB, measured values by proxy
ProxyVersionMBConnections
rustle1.0.095n/a
Tinyproxy1.11.3274n/a
Squid7.7912n/a
3proxy1.0.02,461n/a
gost3.3.03,228n/a

1 core per proxy · authentication on · Scaleway Elastic Metal, Paris, AMD EPYC 8224P · 25 Gbit/s private network (23.5 measured) · median of 3 runs · seed 2004113323 · campaign of 2026-10-28.

All the results side by side

Benchmark results of rustle and four other proxies, one core unless stated, authentication on
1 core unless stated, auth onrustle3proxySquidgostTinyproxy
1 KB responses, req/s55k21k15k4.8k7.6k
1 KB responses, 8 cores, req/s440k115k117k31k—
1 KB, new connection per request, req/s28k5.1k7.8k4.8k7.6k
1 MB responses, req/s2.6k1.8k3531k199
CONNECT tunnels, Gbit/s221614131.8
RAM with 25,000 open tunnels, MB952.5k9123.2k274
HTTPS proxy, 1 KB, req/s49k—14k2.5k—
HTTP/2 proxy, 1 KB, req/s33k——5.2k—
WebSocket, 64 B messages, msg/s59k33k44k47k—

Benchmarked on Scaleway Elastic Metal servers, authentication on: 1 core per proxy, and up to 8 cores for plain HTTP. Best value of each row in bold; “—” means not supported or not measured. See the full benchmark data

How it is built

One core, one lane. Nothing shared.

Each core runs its own event loop, its own listener and its own connection pool. A connection never leaves its core: no locks on the hot path, no work stealing, no cross-core wakeups.

1 core
~55k
req/s
8 cores
~440k
req/s
Scaling
~8×
plain HTTP, 1 KB

See the multi-core results

Under the hood

Three layers, one idea: never share.

From the design down to the kernel, every level is built so that a connection stays on one core.

Shared-nothing shards

One core is one shard: a thread that owns its listener, its connection pool and its buffers. A connection is accepted, served and closed on the same core. The only shared state is cold: the configuration, the keys, the DNS cache and a few atomic counters. So there is no lock on the hot path.

~8×the throughput on 8 cores against 1, plain HTTP at 1 KB

One Tokio runtime per core

Each shard runs its own single-threaded Tokio runtime: no work stealing, no cross-core wakeup. Request heads are parsed in place, as spans into the read buffer, and scratch buffers live as long as the connection, so the hot path does not allocate.

~18 µsof CPU per 1 KB request, against ~48 µs for 3proxy

Let the kernel do the heavy lifting

The kernel spreads new connections across the cores. On Linux, it also moves the bytes of tunnels and large transfers straight from one socket to the other, so the proxy never copies them: less copying, less CPU. TLS and HTTP/2 cannot take this shortcut, so their throughput is lower.

~28k connections/son one core when every request opens a new connection, against ~7.8k for Squid.

Safe by default

A proxy that refuses what it should refuse.

The defaults are the safe ones. Anything that opens the proxy up is a line you write in the config.

With api_keys empty, the proxy is an open relay. On the plain port and on SOCKS5, the key travels in clear text: expose them only on a trusted interface (loopback, VPN) and use the HTTPS port over the Internet. Read the security guide

Configuration

One TOML file, ten lines to start

An unknown or misplaced key fails the startup. Reload it without restarting, rustle reload, and the file is validated first.

[server]
listen  = "127.0.0.1:8080"
workers = 0                       # one worker per CPU core

[auth]
api_keys = ["<openssl rand -base64 32>"]

[tls]                             # HTTPS to the proxy, also speaks HTTP/2
listen = "0.0.0.0:8443"
cert   = "/etc/rustle/fullchain.pem"
key    = "/etc/rustle/privkey.pem"

[socks5]
listen = "127.0.0.1:1080"

Every section and its defaults are in the configuration reference.

Get started

Installed in one command, without sudo

The installer detects your system, verifies the release SHA-256 and installs rustle into ~/.local/bin.

curl -fsSL https://raw.githubusercontent.com/EdouardCourty/rustle/main/install.sh | sh
  1. rustle initwrite a config with a fresh API key (~/.config/rustle/config.toml)
  2. rustle runrun in the foreground
  3. rustle service enableor install it as a systemd user unit / launchd agent

Pin a version with RUSTLE_VERSION=v1.0.0. Release archives carry a GitHub build provenance attestation:

gh attestation verify rustle-<target>.tar.gz --repo EdouardCourty/rustle

Platforms

  • Linux (x86_64, aarch64), glibc ≥ 2.35: the reference platform, with every fast path (splice, kernel TLS, core pinning).
  • macOS (Apple Silicon, Intel): fully functional, without the Linux-only fast paths.

From source: cargo build --release -p rustle. MIT licensed, source on GitHub.