ngrok vs. bore: Comparing an Enterprise Gateway to a Minimalist TCP Tunnel

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 bore: The Ultimate Minimalist Rust Tunneling Tool: quick comparison answer
Choose the tunnel tool based on the network model: public HTTPS URLs for webhooks and demos, private mesh access for internal apps, and managed infrastructure when policy controls matter most.
Which tunnel tool is best for public webhook testing?
Use a public HTTPS localhost tunnel with stable URLs. InstaTunnel focuses on webhook testing, demos, OAuth callbacks, and MCP endpoint workflows.
When should I choose a private network tool instead?
Choose a private mesh or Zero Trust tool when every user and service should stay inside a controlled private network.
Exposing a local development server to the public internet used to mean router configuration, NAT traversal workarounds, and dynamic DNS. Then came ngrok, which let developers tunnel a localhost environment to a public URL in seconds. For years it was the default choice for local port forwarding.
But ngrok has since grown from a simple developer tool into a full cloud edge network — API gateways, AI traffic routing, OAuth layers, WAFs, and a correspondingly heavier dashboard and pricing model. That growth has pushed some developers toward smaller, single-purpose alternatives. One of the most-starred is bore, a TCP tunnel written entirely in Rust that does exactly one thing: forward a local port to a public endpoint, with no dashboard and no account.
This guide compares the two directly: architecture, features, security model, pricing, and setup, using ngrok’s own documentation and bore’s source and release history as primary references.
1. The core problem: why tunneling tools exist
When you run an application on localhost:3000, it’s reachable only from your own machine. Your router’s NAT and firewall block inbound traffic from the public internet by default. If you need to demo work to a client, test a mobile app against a local API, or receive webhooks from Stripe or GitHub, you need a public URL that routes traffic back to your machine.
Tunneling tools solve this with an outbound-initiated connection: a client on your machine connects out to a public server (which your firewall allows, since it’s outbound), and that server pipes incoming public traffic back down the tunnel. Both ngrok and bore use this same basic architecture — what differs is everything built on top of it.
2. ngrok: the API and AI gateway
Created by Alan Shreve and founded in 2013, ngrok started as a simple tunneling utility and has since repositioned itself as an all-in-one networking layer — endpoints, traffic policy, and secure tunnels combined into what it now markets as a single gateway for AI, API, and web traffic.
What ngrok offers today
- Traffic Policy: a CEL-expression-based rules engine that runs at ngrok’s edge — routing, authentication, rate limiting, and transformation are all declared as YAML attached to an endpoint, rather than configured in nginx or a Lua plugin.
- API gateway capabilities: JWT validation, OAuth/OIDC/SAML, mTLS, IP allowlisting, and a WAF with managed rules covering the OWASP Top 10, all enforced before traffic reaches your origin.
- AI Gateway: launched in early access in December 2025 under the
ngrok.aidomain. It sits between your application and one or more LLM providers, routing across OpenAI, Anthropic, and Google or to self-hosted models served via Ollama or vLLM, with automatic failover, PII redaction on requests, and response sanitization — all configured through the same Traffic Policy engine used for regular HTTP traffic. - Web Inspection and Replay: a local and dashboard-based inspector that captures and replays HTTP requests, useful for debugging webhooks.
- Kubernetes Operator: consumes standard Ingress and Gateway API resources and turns them into ngrok endpoints and policies automatically.
ngrok’s free tier, accurately
ngrok’s own pricing documentation (current as of mid-2026) lists these free-tier limits:
| Resource | Free tier limit |
|---|---|
| Online endpoints | Up to 3 |
| Concurrent agents | 3 |
| Data transfer out | 1 GB/month |
| HTTP requests | 20,000/month |
| TCP/TLS connections | 5,000/month |
| HTTP request rate | 4,000/min |
| Webhook verifications | 500/month |
One correction worth making here, since it’s repeated across a lot of third-party comparison content: the free tier does not enforce a 2-hour (or 8-hour) session timeout. ngrok’s documentation states this explicitly — a free-tier endpoint can run continuously as a background service. The real constraints are the bandwidth and request ceilings above, the inability to reserve a custom domain, and the interstitial warning page (below), not a forced disconnect.
The interstitial (“Visit Site”) warning page
To reduce phishing abuse of its shared domains, ngrok injects a warning page in front of HTML browser traffic on free-tier endpoints, informing the visitor they’re viewing a site served through ngrok. This is bypassed by sending an ngrok-skip-browser-warning header (or a non-default User-Agent) with the request — it does not require upgrading to a paid plan, though ngrok’s docs also note paid plans remove it by default. For API clients, automated tests, and webhook consumers that can’t easily set custom headers, this remains a common source of friction (ERR_NGROK_6024), particularly with tools like EventSource where header injection isn’t possible client-side.
Pricing, corrected
ngrok’s current plan structure (2026) is:
- Free — $0, limits as above.
- Hobbyist — $10/month ($8/month billed annually), 5 GB data transfer, 100,000 HTTP requests, 1 TCP address, still capped at 3 online endpoints.
- Pay-as-you-go — $20/month base fee that includes $20 of usage credit, then metered billing: $0.10/GB data transfer, $1 per 100k HTTP requests, $2 per 100k TCP connections beyond the included amount. No endpoint limit. Additional users are $5/month each beyond the first 3.
- Add-ons available on Pay-as-you-go include SSO/RBAC ($10/user/month), custom TLS certificates ($200/month), and dedicated agent IPs ($900/month per region) — enterprise features, not part of a base “per-seat” price.
This is a meaningfully different shape than a flat “$15–30 per user” figure: the entry paid tier is $8–10/month, and the production tier is a $20 base plus metered usage rather than a flat per-seat license.
Security posture worth flagging for an infra audience
ngrok is tracked in the MITRE ATT&CK framework as Software S0508 — not because the tool itself is malicious, but because it has repeatedly been abused by threat actors (including groups tracked as Scattered Spider and Cadet Blizzard) for command-and-control, lateral movement, and data exfiltration, precisely because it’s a legitimate, widely-allowed tool that tunnels through NAT and firewalls. Some enterprise security teams block ngrok’s domains outright as a result — worth knowing if you’re introducing it into a corporate environment with an active security team.
3. bore: the Rust-powered minimalist
Created by Eric Zhang (@ekzhang1) and MIT-licensed, bore is a CLI tool with one job: forward a local TCP port to a remote server, bypassing NAT. As of its latest release (v0.6.0), the project sits at roughly 11,100 GitHub stars and 493 forks — a strong signal of community traction for a tool this narrow in scope.
Why it’s minimal
- ~400 lines of async Rust: the entire client and server implementation is small enough to read in one sitting and audit for yourself.
- No account, no dashboard, no authtoken: you can run
bore local <port> --to bore.pubagainst the maintainer’s public server immediately. - Trivial self-hosting:
bore serveron your own VPS starts a fully functional tunnel server with no additional dependencies. - Tiny binary, near-zero memory footprint: suitable for constrained environments like a Raspberry Pi.
How the protocol works
bore uses an implicit control port at 7835. The client sends a “Hello” message to the server over this control port, requesting to proxy a chosen remote port. When an external connection hits the server, the server generates a UUID for it and sends that UUID to the client; the client opens a new TCP stream, presents the UUID in an “Accept” message, and the server proxies the two connections together. Unclaimed incoming connections are discarded by the server after 10 seconds to avoid memory leaks — this detail comes directly from the project’s own protocol documentation.
Installation
- macOS:
brew install bore-cli - Arch Linux: available in the AUR as
bore - Gentoo: available via the
gentoo-zhoverlay - Any platform with Rust:
cargo install bore-cli - Prebuilt binaries for macOS, Windows, and Linux on the GitHub releases page
- Docker: versioned images published for each release (
docker run -it --init --rm --network host ekzhang/bore <ARGS>)
By default, bore local <port> --to <host> exposes localhost, but a --local-host flag lets you expose a different host on your local network instead — useful if you’re tunneling to another device on your LAN rather than your own machine.
Security model, precisely
bore supports an optional HMAC-based secret (--secret, or the BORE_SECRET environment variable) that authenticates the tunnel creation handshake — a client must prove possession of the secret to open a tunnel on a given server. This prevents unauthorized use of your self-hosted server. It does not encrypt the tunneled traffic itself: once a tunnel is open, the payload is raw TCP. If you’re tunneling something that isn’t already encrypted (e.g. plain HTTP or a raw database protocol), the traffic is visible to anyone positioned to observe it between the bore server and the destination. Production use generally means pairing bore with your own TLS termination (e.g. via Nginx or Caddy in front of the exposed service) or only tunneling protocols that are already encrypted end-to-end, like HTTPS or SSH.
4. Head-to-head
Architecture and performance
ngrok is written in Go and does substantial HTTP/HTTPS-aware processing on every request — payload inspection, header manipulation, and policy evaluation all cost some latency and memory relative to a pure byte-forwarder. bore is written in Rust and is protocol-agnostic: it moves bytes without caring whether they’re HTTP, WebSocket, SSH, or a custom game protocol, which keeps overhead close to zero on both client and server.
Features vs. minimalism
ngrok’s feature surface — HTTPS termination, automatic certificates, request replay, OAuth/SAML, IP allow/deny lists, webhook signature verification, a Kubernetes operator, load balancing, and now AI traffic routing — has no equivalent in bore. bore’s feature surface is, deliberately, just port forwarding. If you need to inspect HTTP payloads while debugging a webhook, ngrok’s dashboard does that natively; if you just need a port open and you’re relying on your own application logs, bore adds effectively no overhead getting there.
Pricing and licensing
ngrok is a freemium SaaS product: free tier with the limits above, $8–10/month for Hobbyist, $20/month base plus usage for Pay-as-you-go, and negotiated enterprise contracts on top. bore is fully open-source under the MIT license — free to use against the public bore.pub server, or self-hosted on infrastructure you already control (a small VPS is enough) with no bandwidth ceiling imposed by the tool itself.
5. Setup
ngrok
# 1. Sign up at ngrok.com and copy your authtoken from the dashboard
ngrok config add-authtoken <YOUR_AUTH_TOKEN>
# 2. Expose a local port
ngrok http 3000
ngrok prints an HTTPS URL (e.g. https://abc-123.ngrok-free.app) that proxies to your local port.
bore (client only, using the public server)
# Install
brew install bore-cli # macOS
cargo install bore-cli # any platform with Rust
# Expose port 8000 via the public bore.pub server
bore local 8000 --to bore.pub
bore prints an assigned port on bore.pub (e.g. bore.pub:43219) where your local server becomes reachable.
Self-hosting bore
# On your VPS
bore server --min-port 10000 --max-port 20000 --secret super_secure_password
# On your local machine
bore local 8000 --to your-vps-ip.com --secret super_secure_password
6. Which one fits your workflow
Reach for ngrok when: - You need HTTP-layer visibility — request replay, payload inspection, header manipulation — while debugging. - You need to gate access with OAuth, OIDC, or SAML in front of a preview environment. - You want a stable custom domain bound to a tunnel without managing your own reverse proxy. - You’re routing or governing AI/LLM traffic across multiple providers and want that in the same policy layer as your regular API traffic.
Reach for bore when: - You want a minimal, auditable, fully open-source tool with no account and no vendor lock-in. - You need to share a port for a few minutes without dealing with tokens or interstitial pages. - You’re running on constrained hardware (Raspberry Pi, embedded devices, IoT) where footprint matters. - You’re tunneling non-HTTP TCP traffic — SSH, a game server, a custom protocol — where ngrok’s HTTP-oriented tooling isn’t adding value anyway. - You want to self-host on your own infrastructure with no imposed bandwidth ceiling.
7. Frequently asked questions
Is bore a complete replacement for ngrok? For basic port forwarding, yes. If you rely on ngrok’s HTTPS termination, payload inspection, or built-in authentication layers, bore doesn’t provide those — you’d need to put your own reverse proxy (Nginx, Caddy) in front of a self-hosted bore server to get equivalent HTTPS handling.
How do I get rid of ngrok’s “Visit Site” warning page?
Send the ngrok-skip-browser-warning header (any value) or a custom User-Agent with your request — this works on the free tier itself and doesn’t require upgrading. Paid plans remove the page by default.
Can I use a custom domain with bore?
Yes, if you self-host: point your domain’s DNS A-record at your VPS running bore server, then connect your client to that address.
Is bore’s traffic encrypted?
No, not by default. The optional --secret authenticates who can open a tunnel; it doesn’t encrypt what flows through it. Pair bore with TLS at the application layer, or only tunnel protocols that are already encrypted, for anything beyond casual local testing.
Does ngrok’s free tier disconnect after a fixed session length? No — this is a common claim in comparison articles, but ngrok’s own documentation states the free tier has no endpoint timeout. The binding constraints are the monthly data, request, and connection caps.
Changelog
Corrections
1. ngrok paid pricing — Original draft stated paid tiers run “$15 to $30+ per user per month.” Corrected to the actual 2026 structure: Hobbyist $10/month ($8/month annual), Pay-as-you-go $20/month base fee including $20 usage credit, then metered overage. Source: ngrok Pricing and Limits documentation.
2. Interstitial page bypass — Original draft implied upgrading to a paid plan was one of the only fixes. Clarified that the ngrok-skip-browser-warning header bypasses the page on the free tier itself, without upgrading. Source: ngrok Free Plan Limits documentation and ngrok error reference ERR_NGROK_6024.
3. bore star count — Updated “over 11,000 stars” to the current precise figure, 11.1k stars / 493 forks, per the live repository page.
Additions
1. Added a dedicated correction addressing the widespread but false claim that ngrok’s free tier has a 2-hour/8-hour session timeout — ngrok’s documentation explicitly states free-tier endpoints have no timeout. Source: ngrok Free Plan Limits.
2. Added ngrok’s AI Gateway (early access since December 2025, under ngrok.ai) — multi-provider LLM routing, self-hosted model support (Ollama, vLLM), automatic failover, and PII redaction, all configured through Traffic Policy. Sources: ngrok AI Gateway launch post, ngrok AI Gateway documentation.
3. Added ngrok’s classification in MITRE ATT&CK as Software S0508, given this blog’s security-focused audience — relevant context for anyone introducing ngrok into an enterprise environment with an active security team. Source: MITRE ATT&CK S0508.
4. Added bore’s --local-host flag (expose a LAN host other than localhost) and additional install paths (AUR, Gentoo overlay, Docker images), all sourced directly from the bore GitHub repository.
5. Added the precise current ngrok free-tier limits table (TCP/TLS connections, request rate limits, webhook verification cap) directly from ngrok’s own documentation rather than paraphrased third-party figures.
6. Noted bore’s current release, v0.6.0, and confirmed the ~400-line codebase figure and control-port/UUID handshake protocol details directly against the project’s own README and protocol documentation rather than secondary sources.
Removed 1. Removed the “Frequently Asked Questions (FAQ) for SEO Optimization” section heading and related SEO-oriented framing language throughout, along with promotional phrasing (“undisputed king,” “godsend,” “masterpiece of lean engineering”) not needed for a technical readership. 2. Removed malformed inline code artifacts from the original draft (e.g., “Bashngrok config add-authtoken” run together as one word) and replaced with properly fenced, labeled code blocks. 3. Removed unsupported claims about bore lacking any security posture beyond what its documentation states — reframed to what the HMAC secret actually protects (tunnel creation, not payload confidentiality).
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.