Vendor Evaluation·6 min read·2025-11-20·Colm Byrne, Technical Product Manager

ngrok Free Tier: What 'Limited Bandwidth and Ugly URLs' Means for Your Webhook Testing Setup

ngrok's free tier opened local webhook testing for millions of developers. The reviewer pattern around bandwidth limits and randomly-generated URLs isn't a complaint about reliability — it's about workflow friction as projects mature.

For most developers, the first time they discovered ngrok was the first time local webhook testing stopped being a deployment problem.

You had a Stripe integration to test. Stripe needed to POST to a real HTTPS URL. Your handler lived on localhost:3000. The old solution was a staging server — deploy your changes, wait, run the test. ngrok's solution was a tunnel command that handed you a public URL in under a second. No deploy. No DNS. No certificate. Just ngrok http 3000 and a URL you could paste directly into the Stripe webhook configuration screen. For how to test Stripe webhooks locally, ngrok's tunnel is still the fastest path.

That experience is genuinely good. Millions of developers have started their webhook development workflow with ngrok's free tier, and for that specific use case — quick local development against a live provider — it remains one of the most frictionless tools available. This post isn't an argument otherwise.

What this post examines is what the free tier includes, what it doesn't, what reviewers have noted about those limits, and when they start to matter as a project matures.

What the ngrok Free Tier Includes

The free tier covers the core tunnel use case thoroughly. You get:

A working tunnel. One active tunnel session that exposes your localhost to the public internet over HTTPS, with TLS handled by ngrok's edge infrastructure. This is the essential capability and it works reliably.

Traffic Inspector. The local web interface at http://localhost:4040 displays every incoming request in real time — full headers, full body, response status and body, timing. You can replay requests against your running handler directly from the Inspector. For local debugging work, this is a best-in-class feature.

Assigned static subdomain. ngrok now gives free tier users a stable assigned subdomain, which persists across tunnel restarts. This solved the most common friction point of the early free tier, where the URL changed every time you started a new session.

The free tier is a real tool for local development. The limitations it imposes don't affect its core functionality for the intended use case.

What Reviewers Noted About Free Tier Limits

Where the signal in public reviews surfaces is around two specific friction points that emerge as webhook projects grow.

G2 reviews for ngrok include one reviewer who described the free tier as offering "limited… bandwidth and… ugly URLs." This is a compact summary of two distinct issues, and it's worth unpacking each.

The bandwidth constraint is structural. ngrok's free tier does not offer unlimited data throughput. For a developer running occasional test events against a local handler, this boundary is rarely encountered. For a developer who needs to simulate production-volume traffic, run load tests, or receive large payloads repeatedly during a debugging session, the limit becomes a practical ceiling. The reviewer's characterization isn't a bug report — it's a statement about what the free tier was designed to accommodate and what it wasn't.

The "ugly URLs" observation refers to the randomly-generated subdomain format that was the default behavior in earlier versions of ngrok free — something like a3f7b2c1.ngrok.io. While ngrok now assigns a stable subdomain to free accounts, the randomly-generated format was the experience for a large cohort of users for a long time, and it produced a specific operational problem: every new tunnel session meant a new URL, which meant reconfiguring every provider that had been pointed at the old one. The G2 reviewer's note captures a workflow friction that was real even if it has since been partially addressed.

To be clear: these are product design trade-offs, not product defects. Free tiers exist to provide enough value to demonstrate the product; they are not full product equivalents at no cost. ngrok's free tier is more capable than most.

When the Limits Start Mattering

The bandwidth and URL limitations are largely invisible during the early stages of local development work. They surface in specific workflow transitions.

The stable URL problem. When you configure a webhook provider — Stripe, Twilio, GitHub, Shopify — you paste a URL into their dashboard and that URL is where they will send events. For providers that require URL verification, going through that process has a non-trivial cost in time and sometimes in rate limits. If the URL you configured changes — because your tunnel restarted with a new subdomain, because the tunnel session expired, because you closed your laptop — every configured provider needs to be updated. That's the workflow the assigned subdomain was meant to solve, and for developers who started ngrok before that feature existed, the memory of reconfiguring Stripe multiple times in a single week is real.

The team-sharing problem. When you're iterating on a webhook handler alone, your local tunnel URL is only shared with the providers you control. When you need to share a URL with a colleague, a QA environment, or an integration test suite that runs overnight, the tunnel model introduces a dependency on the tunnel being active. If the tunnel is down, the URL doesn't resolve. For asynchronous or overnight testing, this is a structural constraint.

The persistence problem. ngrok tunnels don't store incoming requests. If a provider fires a webhook at 2am and your tunnel session has expired, that payload is gone. If you're debugging an intermittent issue — something that only fires under specific conditions, at unpredictable times — the tunnel's reliance on an active session means you may not be there to capture the relevant payload. This is the same dynamic that produces silent webhook failures — the event arrived, but you have no record of it.

None of these limitations are surprises if you read the product documentation. They're constraints that follow from the tunnel model itself. They start mattering when the use case shifts from "test this specific flow right now" to "capture everything this provider sends, at any time, and let me inspect it later."

The Permanent URL Alternative

The category of tool that addresses the bandwidth, URL stability, and persistence limitations isn't a tunnel at all — it's a capture endpoint.

HookTunnel features include a permanent URL at hooks.hooktunnel.com/h/[your-hook-id] from the moment you create it. There's no tunnel session to keep running. The URL doesn't change on restart. There's nothing to restart. Paste it into Stripe once and it captures every event Stripe sends — whether your browser is open, your laptop is closed, or you're in a different timezone.

Every payload that arrives at the URL is stored and available in the dashboard. Free tier keeps 24 hours of history. Pro keeps 30 days. Payloads are searchable, sortable by provider, and include full headers and body exactly as they arrived.

The positioning here isn't "HookTunnel instead of ngrok." For local development — real-time debugging against a running handler, iterating on response logic, checking headers live — ngrok's Traffic Inspector is excellent at that specific task. The two tools occupy different parts of the webhook workflow. See our full webhook debugging guide for a breakdown of when each category of tool applies.

For provider-configured webhook URLs — the URL you paste into Stripe, Twilio, GitHub, or Shopify and expect to remain stable indefinitely — the capture endpoint model is a better fit. The URL is permanent, the storage is unconditional, and there's nothing running on your machine that the URL depends on.

The free tier requires no credit card. Pro is $19/month flat — no bandwidth metering, no throughput limits, no per-hook charges.

What This Means for Your Setup

ngrok's free tier is the right starting point for local webhook development. The Traffic Inspector is genuinely good, the assigned subdomain is a meaningful improvement over the random-URL experience reviewers described, and the tunnel itself is reliable for interactive development work.

The friction reviewers documented — limited bandwidth, URL instability — isn't a critique of the product's core capability. It's a signal that the free tunnel model has a natural boundary, and that boundary appears at the point where you need your webhook URL to be as stable as a domain name rather than as stable as an open terminal session.

For the use case that ngrok's free tier doesn't fully address — a stable URL your providers can rely on indefinitely, with payload history that accumulates whether or not you're at your desk — ngrok's free tier is a great local dev shortcut, and for that specific subset of the problem, a different category of tool applies.

Create a free permanent webhook URL → No install. No credit card. No tunnel required.

Stop guessing. Start proving.

Generate a webhook URL in one click. No signup required.

Get started free →

Frequently Asked Questions

What does ngrok's free tier include?
The ngrok free tier includes one active tunnel session, a Traffic Inspector at localhost:4040 for real-time HTTP debugging with replay, and an assigned stable subdomain that persists across restarts. It does not offer unlimited bandwidth — high-volume or large-payload testing can hit the throughput ceiling.
Why did ngrok URLs used to be random strings, and has that changed?
Early ngrok free tier generated a random subdomain on every tunnel session, which changed each time you restarted. This meant reconfiguring every webhook provider each session. ngrok now assigns a stable subdomain to free accounts, so the URL persists across restarts. Reviewers describing 'ugly URLs' were largely describing the pre-stable-subdomain experience.
When does a stable webhook URL matter for my workflow?
A stable URL matters any time you configure a webhook provider and don't want to reconfigure it when your tunnel restarts. Providers like Stripe, Twilio, and GitHub store the URL you give them — if that URL changes, their events go nowhere. For persistent integrations, the URL needs to be as stable as a domain name, not just stable within a session.
How does HookTunnel handle stable webhook URLs?
Every HookTunnel hook URL is permanent — it does not change between sessions, restarts, or any other event. There is no tunnel to run. Configure your provider once and the URL continues capturing events indefinitely, whether or not your browser is open or your server is running.
How do I get started with HookTunnel?
Go to hooktunnel.com and click Generate Webhook URL — no signup required. You get a permanent webhook URL instantly. Free tier gives you one hook forever. Pro plan ($19/mo flat) adds 30-day request history and one-click replay to any endpoint.