Tako vs Envoy, Caddy, HAProxy, and Nginx: HTTPS Proxy Benchmarks on a Small VPS

Tako vs Envoy, Caddy, HAProxy, and Nginx: HTTPS Proxy Benchmarks on a Small VPS

Tako-kun ·

We just published a public Tako performance report with the data people usually ask for first: HTTPS throughput, p99 latency, CPU, memory, and clean-run behavior under heavy concurrency.

The short version is honest and useful: nginx and HAProxy are still the raw reverse-proxy throughput leaders on this small VPS. Tako does not match them yet. But Tako stays clean through the largest tested row, beats Envoy and Caddy in the heavy rows, and does that while running the app-aware proxy path that powers tako deploy, routing, instance selection, and source-IP handling.

This is the search-shaped version of the report: fewer graphs, more table, all caveats left in.

The Benchmark Setup

The comparison used one small VM from exe.dev: 2 vCPU, 7.8 GiB RAM, Ubuntu 24.04.4, Linux 6.12.90, KVM, AMD EPYC 9554P. The load generator, proxy, and app all ran on that same machine, so this is not a pure proxy microbenchmark. It is closer to a practical VPS question: “How much HTTPS traffic can this box produce end to end?”

Every proxy used the same route, self-signed TLS certificate, upstream app, and HTTP/1.1-over-TLS path. The route was bench.test:18443, resolved to loopback on the VM, with Host and SNI set to bench.test. Each row had a 10 second warmup and 30 second measurement window, with metrics sampled from /proc once per second.

ItemValue
VM2 vCPU, 7.8 GiB RAM, no swap
RegionTokyo, Japan
OSUbuntu 24.04.4, Linux 6.12.90
PathHTTP/1.1 over TLS
Timing10s warmup, 30s measured
Routebench.test:18443 on loopback
AppSame small Go plaintext app behind every proxy

The software matrix was:

ProxyVersion in this run
Takotako-server 0.0.0-09b3dc6
nginxnginx/1.24.0 (Ubuntu)
HAProxy2.8.16-0ubuntu0.24.04.2
Envoy1.38.0
Caddyv2.11.3 with github.com/mholt/caddy-ratelimit

The raw report and row files are public in the tako-sh/performance repo. The HTTP run lives at results/20260602T052009Z/http-vm-local.

Diagram

Throughput, p99, And Clean Runs

For raw 200-response throughput, nginx and HAProxy are the ceiling in this run. Tako lands below them, but well above Envoy and Caddy once concurrency gets heavy.

Proxyc5000 200 RPSc10000 200 RPSc20000 200 RPSc20000 p99c20000 clean-run behavior
nginx17,69815,30910,9913.8s0.00% non-200, 0 client errors
HAProxy17,05014,78811,16215.7s0.00% non-200, 0 client errors
Tako12,50410,3737,26615.5s0.00% non-200, 0 client errors
Envoy4,7353,66482826.6s40.70% non-200, 1.02% client errors
Caddy5,1741,7051,27126.4s0.00% non-200, 7.51% client errors

That table is the headline. At c5000 and above, Tako is not chasing nginx yet. It reaches about 66-75% of nginx’s 200 RPS across c5000-c20000 and about 65-73% of HAProxy’s 200 RPS. If your only question is “which static reverse proxy moves the most clean HTTPS responses on this tiny VM?”, nginx and HAProxy win this run.

But clean-run behavior matters too. Envoy and Caddy both hit pressure in the heavy rows. Envoy starts recording client timeouts at c5000, then returns a large share of 503s at c15000 and c20000. Caddy starts returning 502s at c5000 and later records client timeouts. Tako stays all-200 with 0 client errors through c20000.

There is also a p99 story. nginx has the best c20000 p99 at 3.8s. HAProxy and Tako are roughly comparable at the largest row, around 15.5-15.7s. Envoy and Caddy are both above 26s. Under saturation, “how many requests completed?” and “how long did the slow tail wait?” need to be read together.

CPU And Memory

The VM is saturated in the heavy rows. Total CPU is basically 100% for all proxies, so CPU by itself is not the differentiator. The useful questions are how that budget turns into clean responses, what tail latency looks like, and how much memory each proxy keeps while thousands of TLS connections are open.

Proxyc20000 max CPUc20000 proxy CPUc20000 app CPUc20000 loadgen CPUc20000 proxy RSSMax TLS conns
nginx100.0%40.8%18.0%41.2%262 MiB14,168
HAProxy100.0%54.5%17.4%49.6%896 MiB20,012
Tako99.9%60.1%18.6%44.0%2,723 MiB20,396
Envoy99.9%99.4%7.0%72.6%999 MiB20,175
Caddy100.0%76.1%7.8%27.1%1,534 MiB20,000

Tako’s RSS is the uncomfortable number, and we should keep it visible. The report includes controls: on the same VM at 5k live HTTPS keepalive connections, raw Tokio + OpenSSL used about 136.6 MiB RSS, a Pingora HTTPS responder used about 341.4 MiB, a fixed-upstream Pingora reverse proxy used about 535.3 MiB, and full Tako used about 549.0 MiB after deploy. Full Tako was only about 14 MiB above the comparable fixed Pingora reverse proxy.

So the current read is not “Tako has a simple routing leak.” It is that Pingora/TLS reverse-proxy connection state is expensive in this high-keepalive shape, and Tako still needs tuning before we can call it nginx/HAProxy parity on raw proxy efficiency.

Why Tako Is Doing More Than A Static Proxy

nginx and HAProxy are configured here as static reverse proxies. That is the right raw-throughput comparison, but it is not the same request path.

Tako still does product work on the proxy path:

Request-path workWhy Tako does it
App route lookupRoutes come from app environments in tako.toml
Source-IP derivationSupports direct, Cloudflare, and trusted-proxy modes
Per-client limiter accountingProtects deployed apps from one derived client IP
App and instance selectionConnects routing to Tako’s app lifecycle
In-flight accountingSupports draining, scale decisions, and healthy instance use
Forwarding header normalizationKeeps app-visible request metadata consistent

That is the point of using Tako instead of adding a proxy config file next to a deploy script. tako-server owns routing, TLS, app processes, readiness, scale, and rolling deploy state together. A request can find the deployed app, pick a healthy loopback instance, and participate in the same state model that deploys and logs use.

This is also why the benchmark result is encouraging without being finished. Tako stayed clean under c20000 while doing that app-aware work, but it still trails nginx and HAProxy on raw RPS and nginx on p99. The report calls out the next targets: larger-VM runs, external same-region load generation, Pingora session and upstream tuning, and precomputed per-instance upstream/header state.

The report also includes a current-master feature rerun for durable channels and workflows. Those paths are not proxy-only: the app uses the JavaScript SDK, publishes a channel message, or enqueues a workflow with one persisted ctx.run("ack", ...) step. Both paths stay clean through c8000: channel publish reaches 4,595 200 RPS with 6.4s p99, and workflow enqueue reaches 4,001 200 RPS with 7.7s p99.

What To Take Away

If you need the highest raw HTTPS reverse-proxy throughput on a small VPS, this run says nginx and HAProxy are still the references to beat. They are excellent tools, and the numbers show why people trust them.

If you want the deployment tool to own routing, TLS, process lifecycle, readiness, scale-to-zero, secrets, and app-aware request handling, the Tako result is the useful one: 12.5k clean 200 RPS at c5000 and 7.3k clean 200 RPS at c20000 on a 2 vCPU VM, with zero non-200 responses and zero client errors in every Tako HTTP row.

That is not the finish line. It is a clear baseline, in public, with the rough edges left in. Read the full performance page, inspect the raw benchmark repo, or start from the Tako docs if you want to see how the deploy and proxy pieces fit together.