ngrok's free plan caps data transfer at 1 GB a month and puts a warning page in front of every browser visitor. Using your own domain on ngrok starts at the $20 Pay-as-you-go plan. If any of that gets in your way, this post compares six alternatives on what their free tiers give you, what the paid plans cost, and what a visitor gets on the first request.
Prices and limits checked October 2026, and each section links its source. An AI assistant helped draft this post. The commands and numbers come from my own runs.
Ngrok overview
ngrok is a hosted ingress service. Its agent runs on your machine and gives a local app a public HTTPS address on ngrok's network, which makes it a common way to show a local app to someone outside your network or to receive webhooks during development.
What does ngrok's free plan include?
ngrok's free plan includes 1 GB of data transfer, 20,000 HTTP requests and 5,000 TCP connections a month, up to 3 endpoints online, and one assigned dev domain on ngrok-free.app (ngrok's free plan limits↗). Endpoints on the free plan don't time out. TCP endpoints need a verified credit card.
Browser visitors see a warning page before your app. Clicking Visit sets a cookie that hides it on that domain for 7 days, and requests from code, like webhooks, skip it. In my test the page also showed the visitor the public IP address of the machine running the tunnel.
Hobbyist costs $10 a month, or $96 a year with annual billing. It raises transfer to 5 GB and removes the warning page. Your own domain needs Pay-as-you-go, at $20 a month plus usage and $0.01 per active hour for each domain (ngrok pricing↗). Neither the pricing page nor ngrok's terms of service↗ restrict commercial use by plan. ngrok describes Pay-as-you-go as the plan "for teams shipping production traffic".
Pros of Ngrok
- Runs on macOS, Windows, Linux, FreeBSD, Docker and Raspberry Pi (ngrok downloads↗).
- Automatic HTTPS certificates.
- A local web interface at
localhost:4040to inspect and replay requests (web inspection interface↗).
Cons of Ngrok
- 1 GB of transfer a month on the free plan, 5 GB included on Hobbyist.
- A warning page for browser visitors on the free plan.
- 3 endpoints online on the free plan and on Hobbyist.
- No custom domain below Pay-as-you-go.
- TCP endpoints on the free plan need a verified credit card.
Ngrok Alternative
One row per tool. "What's free" is what you get without paying, "Paid from" is the cheapest listed plan.
| Tool | What's free | Paid from | Own domain | Trade-off |
|---|---|---|---|---|
| ngrok | 1 GB/month, 3 endpoints, warning page for browsers | $10/month (Hobbyist) | Pay-as-you-go: $20/month plus $0.01 per active hour | Usage-metered, own domain only on the usage plan |
| LocalCan | Free plan: 1 Public URL at a time, 60-minute sessions, 1 GB/month, HTTPS only | $10/month or $96/year (Solo), or $99 once (Lifetime License) | Solo and up, or the Lifetime License, via a CNAME | Free sessions end after 60 minutes and run from one New York edge. Closed source, no self-hosting |
| Cloudflare Tunnel | Quick tunnels with no account, named tunnels on Cloudflare's free plan | $0, Tunnel is on every plan | Domain must be on Cloudflare | Quick tunnels have no uptime guarantee and no Server-Sent Events |
| zrok | 5 GB/day, 25 environments, 50 shares | Commercial plans, priced on request | Custom domain frontend, not on the free tier | Account required. Unverified free accounts show a warning page until you add a card |
| localtunnel | Everything, there is no paid plan | n/a | No | Warning page that asks browser visitors for the host's IP, last npm release in 2021 |
| PageKite | 31-day trial with 2.5 GB | Pay What You Want from $4, subscriptions from $5.99/month | CNAMEs on paid plans | Not taking payments for new subscriptions, self-host the relay instead |
| Tailscale | Funnel on the free Personal plan, up to 6 users, non-commercial use only | $8/user/month (Standard) | No, ts.net names only | Funnel listens on 3 ports only |
Free ngrok alternatives: what a visitor sees first
Cloudflare quick tunnels and LocalCan's Free plan serve your app on the first request. ngrok's free plan and localtunnel put a warning page in front of browser visitors, and both pages showed the visitor my machine's public IP address.
On 11 October 2026 I served one static page on localhost:8765 and exposed it through every tool at once. I fetched each URL once with a Chrome User-Agent and once with curl's default User-Agent, then timed two rounds of 10 requests per URL from a laptop in Poland, opening a new connection each time so DNS and TLS are part of the number. LocalCan's paid plan joined in the second round only.
| Tunnel | Account | First browser request | First request from code | Median time to first byte |
|---|---|---|---|---|
| Cloudflare quick tunnel | None | Your app | Your app | 0.125 s |
| ngrok, free plan | ngrok account (free plan) | Warning page (ERR_NGROK_6024) | Your app | 0.173 s |
| LocalCan, paid plan (Amsterdam edge) | Paid license | Your app | Your app | 0.178 s |
| LocalCan, Free plan (New York edge) | Free plan key | Your app | Your app | 0.470 s |
| localtunnel | None | HTTP 511, "Tunnel website ahead!" | Your app | 0.534 s |
LocalCan's Free plan was the second slowest from Poland because every Free session runs on one edge in New York. The same app on a paid plan was routed to Amsterdam and came in level with ngrok. Cloudflare has a data center in Warsaw, close to the laptop, and was fastest. For throughput rather than latency, see the speed test of ngrok, Cloudflare Tunnel, LocalCan, Pinggy and LocalXpose.
This is what LocalCan printed on the Free plan:
localcan http 8765
Connecting tunnel to http://localhost:8765...
Forwarding https://mighty-forest.local → localhost:8765
Forwarding http://mighty-forest.local → localhost:8765
Forwarding https://faithful-maroon-swan.trylocalcan.com → localhost:8765
Free session: 60 min left · 1 GB/month · upgrade at localcan.com/pricing
And this is ngrok's warning page for the same app, with the hostname and IP address masked:
You are about to visit xxxx-xx-xx-xx-xx.ngrok-free.app, served by <host IP>. This website is served for free through ngrok.com. You should only visit this website if you trust whoever sent the link to you. (ERR_NGROK_6024)
Webhooks get through both warning pages because they don't send a browser User-Agent. A client or teammate who opens the link in a browser sees the warning first. From code, ngrok skips it for requests with an ngrok-skip-browser-warning header, and localtunnel for requests with a bypass-tunnel-reminder header.
LocalCan: the easiest solution
LocalCan is a desktop app for macOS and Windows, with a CLI-only build for Linux (installation). It gives a local app a Public URL (also called a tunnel) on *.localcan.dev (trylocalcan.com on the Free plan) or your own domain. On macOS and Windows it also publishes .local domains on your local network and shows the traffic in an inspector with replay (inspect traffic).
Features:
- Desktop app on macOS and Windows, CLI on Linux
- HTTPS Public URLs on every plan, TCP on paid plans
- Custom domains through a CNAME at your DNS provider, with certificates handled for you (custom domains)
.localdomains with HTTPS on your local network (macOS and Windows)- Traffic inspector with replay in the desktop app. On Linux, captured traffic is read from the CLI after
localcan traffic enable - Access control enforced on LocalCan's servers on paid subscription plans (Solo, Pro and Teams, not the Lifetime License): a password page, a secret link, or IP and user-agent rules (access control)
Pricing:
The Free plan gives you one Public URL at a time on trylocalcan.com, in sessions of up to 60 minutes, with 1 GB of traffic a month. Solo is $10 a month or $96 a year for 1 device, 5 live Public URLs and 2 custom domains. Pro is $16 a month or $144 a year for 2 devices, 10 live Public URLs and 4 custom domains. Teams is $15 per seat per month with 3 seats included. If you'd rather not subscribe, the Lifetime License is $99 once for 1 device, 5 Public URLs and 2 custom domains, with 1 year of app updates, and the license never expires (pricing).

Cloudflare Tunnel
Cloudflare Tunnel connects a local service to Cloudflare's network through the cloudflared agent, and it is available on all Cloudflare plans (Cloudflare Tunnel↗).

There are two ways to use it. A quick tunnel needs no account: cloudflared tunnel --url http://localhost:8765 printed a random trycloudflare.com URL, and it was the fastest of the five tunnels in my test. Quick tunnels are meant for testing. They have no uptime guarantee, return 429 after 200 in-flight requests, don't support Server-Sent Events, and get a new hostname every run (quick tunnels↗). A named tunnel gives you a stable hostname, but publishing one requires a domain on Cloudflare (get started↗), and on a zone on Cloudflare's free plan request bodies are capped at 100 MB (error 413↗).
Features:
- Quick tunnels with no account
- Named tunnels on your own Cloudflare domain
- HTTP and HTTPS hostnames, plus TCP, SSH, RDP and SMB, which need
cloudflaredon the visitor's side too (routing↗)
Zrok
zrok is open source (Apache 2.0) and built on OpenZiti↗. The hosted service at zrok.io has a free tier with 5 GB of transfer a day, 25 environments and 50 shares, and commercial plans are priced on request (zrok pricing↗). Public shares from an unverified free account show a warning page until you add a card. zrok needs an account (zrok invite), so it isn't in the test above.
You can also run the whole service on your own servers. The latest release, v2.0.8, came out on 8 October 2026 (zrok on GitHub↗). Against ngrok, zrok's free tier gives 5 GB of transfer a day instead of 1 GB a month, and you can host the service yourself.

Features:
- Open source and self-hostable
- Public shares with
zrok share public localhost:8080 - Private shares between zrok users, including TCP and UDP
- A
drivemode for sharing a folder
LocalTunnel
localtunnel is an MIT-licensed npm package that gives a local port a loca.lt address with no account (localtunnel on GitHub↗). It has no paid plan. You can ask for a named subdomain with --subdomain, but there are no custom domains and no TCP tunnels. The newest npm release is 2.0.2, from September 2021 (localtunnel on npm↗).

In the test, a browser got an HTTP 511 page titled "Tunnel website ahead!" that shows the tunnel host's IP address and asks the visitor to type it in to continue. The page comes back once every 7 days per visitor IP. localtunnel was also the slowest in the test, at a median of 0.534 s.
Features:
- Open source (MIT), with localtunnel's server repository↗ published separately
- No account
- HTTPS on
loca.lt
Pagekite
PageKite is a tunneling service with an open-source client and relay, pagekite.py (AGPL). As of October 2026, its pricing page says "We are temporarily unable to process new subscriptions, consult our blog for details" (PageKite pricing↗), and the newest post on PageKite's blog↗ is from October 2021. The listed options start at Pay What You Want, with a $4 minimum payment, and subscriptions start at $5.99 a month. A free trial covers 31 days and 2.5 GB.

The trial signup form is still up. For anything past the trial, you can run pagekite.py as your own front-end relay on a server you control (pagekite.py manual↗).
Features:
- Open source (AGPL)
- Self-hosted relay with
--isfrontend
Tailscale
Tailscale is a mesh VPN that connects your devices to each other. Its Funnel feature publishes a service from one of those devices to the public internet, and Funnel is available on all plans (Funnel↗). The Personal plan is free for up to 6 users, and Tailscale says it is "only suitable for non-commercial use". Standard costs $8 per user per month and Premium $18 (Tailscale pricing↗).

Funnel is narrow for an ngrok replacement. It listens only on ports 443, 8443 and 10000, serves only names in your tailnet's ts.net domain, and its bandwidth limits are not configurable. In my Tailscale Funnel alternative test, new Funnel URLs took up to 10 minutes to serve their first request, and downloads through Funnel ran at a median of 7 Mbps. It fits a team that already runs Tailscale for private access.
Features:
- Private access between your devices, with Funnel for public links
- Funnel on every plan, including the free Personal plan
Open-source and self-hosted ngrok alternatives
Five tools here publish their code, and three of them let you run the whole service yourself:
- zrok (Apache 2.0) has a hosted service and a self-hosted setup.
- pagekite.py (AGPL) runs as a client or as your own front-end relay.
- localtunnel (MIT) publishes localtunnel's server repository↗, last updated in March 2019.
- cloudflared (Apache 2.0, cloudflared on GitHub↗) and the Tailscale client (BSD 3-Clause, Tailscale client on GitHub↗) are open source too, but this post uses them with Cloudflare's and Tailscale's hosted services.
LocalCan is closed source and has no self-hosted option.
What’s the best Ngrok alternative?
I build LocalCan, so weigh my answer with that in mind. It depends on who opens the link and how long it has to live:
- A one-off link for a quick test: a Cloudflare quick tunnel. No account, no warning page, fastest in my test.
- A link a client or teammate opens in a browser, for up to an hour: LocalCan's Free plan. No warning page, and pausing and resuming within the session keeps the same URL.
- A stable URL on your own domain without moving your DNS: LocalCan Solo, at $10 a month with 2 custom domains. ngrok needs Pay-as-you-go for the same thing.
- A domain that is already on Cloudflare: a named Cloudflare Tunnel. It gives you a stable hostname on your own domain, which ngrok only offers on Pay-as-you-go, at no charge.
- A free TCP tunnel: ngrok's free plan once you verify a card, or zrok private shares between zrok users. Cloudflare's TCP needs
cloudflaredon the visitor's side, and LocalCan's TCP is on paid plans. - Open source and self-hosted: zrok.
- A team that already runs Tailscale: Funnel, if
ts.netnames are fine.
For LocalCan against ngrok's Hobbyist plan feature by feature, see LocalCan as an ngrok alternative.
