rathole vs. frp vs. ngrok: What the Benchmarks Actually Show

Current comparison
Looking for the main ngrok alternative guide?
We keep the latest ngrok alternative comparison, CLI commands, pricing notes, and webhook examples on one canonical page.
Open the InstaTunnel ngrok alternative guideQuick answer
ngrok vs rathole: The Rust-Based Performance King for Self-H: quick answer
If free tunnel limits interrupt your workflow, compare session length, stable URLs, concurrent tunnels, and paid-plan pricing before choosing a localhost tunnel tool.
What free tunnel limits should developers check first?
Check session duration, URL stability, concurrent tunnels, custom subdomains, bandwidth or request limits, and whether webhook callbacks survive restarts.
How does InstaTunnel handle longer development sessions?
InstaTunnel Free is designed around 24-hour sessions, with Pro available for higher limits and MCP endpoint tunnel workflows.
CGNAT and IPv4 exhaustion have made “just open a port on your router” a non-option for most home connections and a lot of cloud deployments too. If you’re testing webhooks, running a homelab service, or managing remote IoT devices, you need something to broker the NAT traversal for you. Three names come up constantly in that conversation: ngrok, frp, and the newer Rust entrant, rathole. Here’s what each one actually does, and — since a lot of the enthusiasm around rathole online is copy-pasted from the same few sources — what the numbers behind the claims actually say.
ngrok: convenient, centralized, and still bandwidth-capped
ngrok’s pitch hasn’t changed: run one command, get a public HTTPS URL pointing at your local server, no server of your own required. That convenience comes from routing your traffic through ngrok’s edge network, which is also where its limitations live.
As of 2026, ngrok’s free tier caps you at 1 GB of bandwidth per month with a single active endpoint, and it reassigns a random .ngrok-free.app subdomain every time you restart the agent — a real problem if you’re pointing a webhook at it. Free-tier HTML traffic also gets an interstitial warning page (skippable via an API header, but not for browser-facing demos). Custom subdomains require a paid plan, starting at the Personal tier ($8/month, 5 GB, then $0.10/GB overage), up through Pro ($20/month, 15 GB) and Enterprise ($39/month), with pay-as-you-go usage-based pricing available from $18/month for production workloads.
The more structural limitation is protocol support: ngrok still has no native UDP tunneling, at any tier. That rules it out for game servers, VoIP, and IoT protocols like CoAP or MQTT-over-UDP variants — you’re limited to HTTP, HTTPS, TCP, and TLS. Where ngrok remains genuinely strong is the stuff around the tunnel: request replay, traffic inspection, webhook verification, OAuth/SAML/OIDC gating, and a polished API for managing tunnel lifecycle — none of which frp or rathole attempt to replicate.
frp: mature, actively developed, and larger than either alternative
frp (Fast Reverse Proxy), written in Go, is the long-standing self-hosted option: you run frps on a VPS with a public IP and connect frpc from behind the NAT. It’s worth being precise about frp’s current state, because a lot of “frp is bloated and insecure” framing online is several years stale.
frp is under very active development — v0.70.0 shipped July 11, 2026, and the project sits at roughly 106,000+ GitHub stars with about 15,000 forks, an order of magnitude larger than any Rust alternative in this space. TLS encryption has been enabled by default since v0.50.0, and modern configs use TOML, YAML, or JSON (the old INI format is deprecated). Authentication supports both static tokens and OIDC.
On the “clients can open arbitrary ports” security concern: that’s true only in the sense that frp doesn’t restrict port binding out of the box. The server config supports an allowPorts directive that whitelists which port ranges a client is permitted to bind, plus a maxPortsPerClient cap — but it’s opt-in, not the default. If you deploy frp without setting allowPorts, a client with a valid token can indeed request any port on the server. That’s a real operational gotcha worth flagging in any frp deployment guide, though it’s a config oversight rather than an architectural flaw.
The garbage-collection critique is architecturally real — Go’s GC does introduce non-deterministic pause behavior that a GC-less language avoids by construction — but it’s worth weighing against the fact that frp has scaled to hundreds of thousands of production deployments with that architecture. Whether GC pauses matter to your use case depends heavily on your traffic pattern, not just the language choice.
rathole: genuinely fast, but essentially unmaintained since 2023
This is the section where the “dethroning” narrative needs the most correction. rathole, originally built by GitHub user rapiz1 and now maintained under the rathole-org organization, is a Rust reverse proxy explicitly built as a leaner alternative to frp: TCP/UDP forwarding only, no built-in web server, no load balancer, no plugin system.
The maintenance status matters more than the benchmarks. rathole’s most recent tagged release, v0.5.0, shipped October 1, 2023. As of this writing (mid-2026), that’s just under three years without a new release, and it’s an active enough concern that rathole’s own user community has openly asked whether a better-maintained alternative has since emerged. The repository sits at 13.9k stars and 791 forks — a real, respected project, but roughly a tenth the size and community of frp, and without frp’s release cadence. That’s not disqualifying for a hobby project on a Raspberry Pi, but it’s a meaningfully different risk profile than “the modern standard” framing implies, especially for anything you’d call production infrastructure.
What rathole does deliver, factually:
- Small binary. The official build guide gets the compiled binary down to roughly 500 KiB for embedded targets — genuinely tiny, and a real advantage on flash-constrained routers.
- Mandatory per-service tokens. Every service on both client and server needs its own token; there’s no “trust by default” equivalent to frp’s un-whitelisted port binding.
- Noise Protocol support, as an alternative to TLS, avoiding certificate management entirely.
- Hot-reloadable config — services can be added or removed without restarting the process.
Configuration
rathole’s actual config format (from the project’s own documentation) is TOML-based, split between client and server files:
Server (server.toml, on your public VPS):
[server]
bind_addr = "0.0.0.0:2333" # Port rathole listens on for the client
[server.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know"
bind_addr = "0.0.0.0:5202" # Public port exposing the service
Client (client.toml, behind the NAT):
[client]
remote_addr = "myserver.com:2333"
[client.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # Must match the server
local_addr = "127.0.0.1:22"
Run ./rathole server.toml on the VPS and ./rathole client.toml on the local host, and ssh myserver.com:5202 reaches the NAS. The token-per-service model is the one clear security improvement over frp’s default configuration.
The benchmark everyone cites — and its actual caveats
The numbers behind “rathole crushes frp under load” are real, but they come from a single source: rathole’s own docs/benchmark.md, dated December 28, 2021, run on one machine (an Arch Linux box with a dual Xeon E5-2620 and 16 GB RAM), comparing an early rathole development commit against frp v0.38.0 — a version roughly 30 releases behind frp’s current v0.70.0. It’s also a loopback benchmark, which the rathole docs themselves note reflects CPU-bound performance rather than real network conditions.
With those caveats stated, here’s the actual latency table from that benchmark, using vegeta to generate HTTP load against both proxies:
| QPS | rathole latency | frp latency |
|---|---|---|
| 1 | 2.113 ms | 2.55 ms |
| 1000 | 1.723 ms | 1.742 ms |
| 2000 | 1.845 ms | 1.749 ms |
| 3000 | 2.064 ms | 2.011 ms |
| 4000 | 2.569 ms | 7,907 ms |
Up to 3,000 QPS the two are essentially indistinguishable. At 4,000 QPS, frp 0.38.0 fell over hard in this specific test, while rathole’s latency barely moved. That’s a genuinely dramatic result, and it’s the origin of essentially every “rathole is faster” claim you’ll see repeated across blogs and forums. What none of those repeats mention is that nobody appears to have re-run this comparison against a current frp release, on different hardware, or under real (non-loopback) network conditions in the years since. Treat the throughput ceiling as “true for a 2021 frp binary in one lab,” not as a settled verdict on the current codebases.
The memory comparison from the same benchmark run is more straightforwardly credible: under a sustained vegeta attack -duration 30s -rate 1000, frp’s memory footprint grows substantially larger than rathole’s, consistent with what you’d expect from a garbage-collected runtime buffering connections versus Rust’s ownership-based allocation. This is the argument that holds up best for rathole on genuinely resource-constrained hardware — a 128 MB OpenWrt router or a $3/month VPS is far more likely to hit an OOM-killer event under frp’s memory profile than rathole’s.
Noise Protocol: what it actually replaces, and who else uses it
Both TLS and the Noise Protocol Framework solve the same problem — encrypting the tunnel between client and server — but Noise skips the certificate authority model entirely in favor of pre-shared or exchanged static keys. rathole’s default Noise pattern is Noise_NK_25519_ChaChaPoly_BLAKE2s.
Noise is a real, credible framework, not a rathole-specific invention: WireGuard’s handshake is built on Noise’s IKpsk2 pattern, and WhatsApp uses Noise for its client-to-server transport encryption. Slack has also used Noise-based implementations. One correction worth making here: Signal’s messaging protocol (X3DH plus the Double Ratchet algorithm) is a different, older design — despite some conceptual lineage, Signal does not use the Noise Protocol Framework, so it shouldn’t be cited alongside WireGuard and WhatsApp as a Noise adopter.
Where each tool actually fits
ngrok — you want a public URL in ten seconds, you don’t want to run a VPS, and UDP isn’t a requirement. Its request-inspection and webhook-debugging tooling remains the most polished of the three, and that’s the real reason to pay for it.
frp — you want a self-hosted, actively developed tool with a large community, HTTP/TCP/UDP support, load balancing, and dashboards, and you’re willing to explicitly configure allowPorts and keep the default TLS enabled rather than relying on defaults alone.
rathole — you’re running on genuinely memory-constrained hardware (an OpenWrt router, a 512 MB VPS) where rathole’s small footprint and per-service tokens are a real win, and you’re comfortable with the fact that you’re depending on a project that hasn’t tagged a release in close to three years. That’s a reasonable trade for a homelab; it’s a much harder sell for anything you’d call production infrastructure without a plan for what happens if a security issue surfaces and nobody ships a fix.
Changelog
- Removed all SEO-style framing, unstated “market share” and “violently disrupted” claims, and the “Ini, TOML” code-fence label artifacts that had leaked into the body text of the original draft.
- Corrected the central narrative: the original draft presented rathole as actively “dethroning” frp. In fact, rathole’s last tagged release was v0.5.0 on October 1, 2023 (~13.9k GitHub stars, 791 forks), while frp shipped v0.70.0 on July 11, 2026 and has roughly 106k+ stars and 15k forks — frp is both larger and far more actively maintained. (rathole releases, frp releases)
- Verified and re-sourced the QPS/latency benchmark table (previously stated without attribution) directly against rathole’s own
docs/benchmark.md, and added the missing context that it dates to December 28, 2021, used frp v0.38.0 (now ~30 releases out of date), ran on a single lab machine, and was a loopback test — not an independent or current benchmark. (rathole benchmark.md) - Corrected the frp security claim: frp does support an opt-in
allowPortswhitelist andmaxPortsPerClientlimit to restrict client port binding, and has shipped with TLS enabled by default since v0.50.0 — the original draft implied no such controls exist. (frp GitHub, frp config reference) - Corrected the binary size claim from a vague “well under 1MB” to the sourced, specific figure of ~500 KiB from rathole’s own build documentation.
- Corrected the Noise Protocol adopter list: removed Signal (which uses the separate X3DH/Double Ratchet-based Signal Protocol, not Noise) and confirmed WireGuard (Noise_IKpsk2 pattern), WhatsApp (client-server transport), and Slack as actual Noise adopters. (Noise Protocol Framework overview, Wikipedia: Noise Protocol Framework)
- Corrected and updated ngrok free-tier specifics with current, sourced figures: 1 GB/month bandwidth, 1 active endpoint, random subdomain per restart, no native UDP support at any tier, and current pricing tiers (Personal $8/mo, Pro $20/mo, Enterprise $39/mo, pay-as-you-go from $18/mo). (ngrok pricing/limits summary, ngrok blog on static domains)
- Replaced the fabricated TOML configuration example with rathole’s actual documented client/server config syntax and field names, sourced from the project README.
- Softened the “Go’s GC vs. Rust’s zero-cost abstractions” framing from an absolute claim into a stated architectural trade-off, noting frp’s GC-based design hasn’t prevented large-scale production adoption.
- Rewrote the conclusion to reflect the maintenance-status finding: rathole is recommended for constrained hobbyist hardware with an explicit caveat about its stale release cycle, rather than positioned as the general-purpose “modern standard.”
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.