Introduction

ngrok is a widely used tunneling and ingress platform that lets you expose local services to the public Internet with minimal configuration. This article explains how ngrok works at a technical level: the client/server components, connection lifecycle, traffic flow, security guarantees, and advanced features such as HTTP inspection, TCP tunnels, custom domains, and production ingress capabilities. Practical examples and architecture diagrams are included to help developers and architects understand when and how to use ngrok effectively.

Table of contents

  • Introduction
  • High-level overview: what ngrok provides
  • Core components and architecture
    • The ngrok client (agent)
    • ngrok cloud (coordinator, edges, PoPs)
    • Control plane vs data plane
  • Connection lifecycle and traffic flow
    • Establishing the tunnel
    • Request routing from public URL to local service
    • Long-lived multiplexed connections and reverse proxying
  • Protocols and transport details
    • How TCP tunnels work
    • HTTP(S) tunnels, TLS termination, and end-to-end TLS
    • WebSocket and non-HTTP protocols
  • Security model
    • Encryption in transit
    • Authentication and access controls
    • Best practices and common pitfalls
  • Developer features and observability
    • Request inspection, replay, and logs
    • Subdomains, reserved domains, and custom domains
    • Replay and request modification
  • Production features (beyond local dev)
    • API gateway, ingress for Kubernetes, identity-aware proxy
    • Load balancing, endpoint pools, and global PoPs
  • Practical examples
    • Quick CLI walkthrough (HTTP tunnel)
    • Exposing a database with TCP tunnel
    • Using a custom domain
  • When not to use ngrok
  • Conclusion

High-level overview: what ngrok provides

ngrok is a globally distributed reverse-proxy and tunnel/orchestration service that provides a public endpoint which forwards traffic to a service running on a developer’s local machine or private network[3]. The platform combines functionality commonly found across reverse proxies, API gateways, load balancers, and ingress controllers into a single service that is environment-independent and can be used for both development and production ingress scenarios[3][6].

Core components and architecture

The ngrok client (agent)

  • The client is a lightweight process you run locally; it initiates outbound connections to ngrok’s infrastructure and maps one or more local ports to publicly addressable endpoints[2][4]. When you run ngrok, the client authenticates using an account token and establishes one or more long-lived connections to ngrok’s cloud[2][3].

ngrok cloud: coordinator, edges, and PoPs

  • ngrok operates a global network of servers (Points of Presence, or PoPs) that accept inbound traffic on public endpoints and forward it over secure tunnels to the client[3][6]. The cloud includes components that act as edge reverse-proxies, load balancers, and API gateway-like components that apply policies (authentication, routing, transformations)[1][3].

Control plane vs data plane

  • Control plane: handles authentication, tunnel/session management, configuration, and the management API.
  • Data plane: carries the actual application traffic (HTTP, TCP, WebSocket) between clients and the local service over long-lived encrypted channels. ngrok keeps them separate to enable efficient, secure forwarding and quick policy changes[3][7].

Connection lifecycle and traffic flow

Establishing the tunnel

  1. Start your local service on a port (e.g., localhost:3000).
  2. Run the ngrok client specifying protocol and port (for example, ngrok http 3000). The client authenticates to the ngrok control plane using your account token and requests a public endpoint. The ngrok service assigns a public URL (random subdomain or reserved/custom domain) and responds with tunnel configuration[2][4][3].
  3. The client opens a long-lived TLS-encrypted connection (or in some cases multiple multiplexed connections) to the ngrok PoP. This outbound connection traverses NAT and firewalls because it is initiated from inside your network[2][5].

Request routing from public URL to local service

  • When an external client requests the ngrok public URL, DNS directs that request to the nearest ngrok PoP. The PoP accepts the request and, based on the mapping created during tunnel setup, forwards the request through the established long-lived connection to your local ngrok client[3][4].
  • The local client receives the forwarded request and proxies it to the specified local port (e.g., your web server). The local server’s response is returned to the ngrok client, which sends it back over the encrypted channel to the PoP to respond to the external requester[2][4].

Long-lived multiplexed connections and reverse proxying

  • To be efficient and resilient, the ngrok client often maintains multiplexed streams over a small number of long-lived TCP/TLS connections, enabling many independent requests to be proxied concurrently without needing a separate connection per request. This design also reduces the chance that transient network issues will tear down active tunnels[2][3].

Protocols and transport details

How TCP tunnels work

  • For non-HTTP services, ngrok supports raw TCP tunnels. The ngrok client opens a TCP listener on the PoP with a public address (or port), and incoming TCP bytes are forwarded over the established encrypted tunnel to the local client, which proxies the traffic to the local service (for example, an SSH, database, or custom TCP protocol)[2][4]. This allows exposing arbitrary TCP-based services without adjusting NAT or firewall rules.

HTTP(S) tunnels, TLS termination, and end-to-end TLS

  • By default, ngrok provides HTTP and HTTPS endpoints. ngrok’s edge can terminate TLS to inspect and apply routing or policy logic[3]. If you require end-to-end TLS (for example to ensure ngrok cannot decrypt payloads), you can use TLS passthrough or configure client certificate / mutual TLS depending on product features and plan[3][6].
  • Terminating TLS at the edge enables features like request inspection, replay, authentication transforms, and WAF-style actions; terminating at the client side preserves full confidentiality but limits some platform features[3][7].

WebSocket and other protocols

  • Because the data plane forwards raw traffic for TCP or HTTP upgrades, WebSocket connections (which are upgraded from HTTP) work naturally across ngrok tunnels, allowing real-time apps to be tested behind the tunnel[4][5].

Security model

Encryption in transit

  • The client establishes TLS-encrypted connections to ngrok’s PoPs, protecting traffic between your local machine and ngrok infrastructure[2][3]. For HTTPS endpoints, TLS is presented to external clients at ngrok’s edge; whether traffic remains encrypted end-to-end depends on your configuration (edge termination vs passthrough)[3].

Authentication and access controls

  • ngrok supports account tokens for client authentication, and on the edge you can configure various access controls: HTTP basic auth, OAuth/OIDC, JWT validation, IP allow/deny lists, mutual TLS, or API-key style checks[3][1]. These mechanisms help restrict who can use or reach the public endpoint[1][3].

Best practices and common pitfalls

  • Avoid exposing production-sensitive services via short-lived public tunnels without proper authentication or network-level protections; random public URLs are discoverable if leaked and are less secure than properly configured production ingress[2][5].
  • Use reserved subdomains, custom domains, and identity-aware proxy features for production-facing endpoints rather than ephemeral tunnels[3].
  • Monitor logs and request activity; ngrok provides request inspection and logging to detect misuse[4][3].

Developer features and observability

Request inspection, replay, and logs

  • ngrok records and surfaces incoming requests for each tunnel via a web-based inspector and API, enabling developers to inspect headers, bodies, and replay requests against their local service for debugging[4][5]. This is especially useful for webhook development.

Subdomains, reserved domains, and custom domains

  • By default, tunnels get randomly generated subdomains (e.g., abc123.ngrok.io), but paid/reserved domain features allow predictable subdomains and attaching your own domain (CNAME configuration) so the tunnel can serve production-like hostnames and TLS certificates[3][4].

Replay and request modification

  • The inspection layer enables replaying requests and sometimes modifying and replaying them. This is valuable for testing webhook retries or debugging brittle integrations[4][5].

Production features (beyond local dev)

While originally focused on developer convenience, ngrok now offers features intended for production traffic and ingress:

  • API gateway capabilities: policies, transformations, and authentication applied at the edge before forwarding to backends[3].
  • Kubernetes ingress: an ngrok operator/controller can provide ingress for services across clusters[3].
  • Identity-Aware Proxy (IAP): integrate with OIDC/SAML to restrict access to authenticated users and federate identity providers[1][3].
  • Load balancing and endpoint pools: route and scale traffic across multiple backends, enable failover and canary deployments[3].
  • Global Points of Presence: reduce latency by routing clients to the nearest PoP and providing robust delivery[6][3].

These features make ngrok usable as a unified ingress layer where organizations want quick setup of secure gateways without operating separate complex infrastructure stacks[7].

Practical examples

Quick CLI walkthrough (HTTP tunnel)

  • Start your local web server: e.g., python -m http.server 3000 (or your app on port 3000).
  • Authenticate ngrok (one-time): ngrok authtoken <your-token> (ngrok stores this token locally) — this lets the client register with your account and reserve features[2][3].
  • Expose port 3000: ngrok http 3000. The client will print assigned public URLs (HTTP and HTTPS) and a local inspector URL (often http://127.0.0.1:4040) where you can view requests[4][5].

Exposing a database with TCP tunnel

  • To expose an SSH server or database on port 22/5432: ngrok tcp 22 (or ngrok tcp 5432). ngrok returns a public host:port which forwards raw TCP bytes to your local port over the encrypted tunnel; connect to that host:port with your client[2][4]. Use strong authentication and IP restrictions before exposing sensitive services.

Using a custom domain

  • Configure your DNS (CNAME or ALIAS) to point your domain to ngrok’s endpoint as described in the ngrok documentation, then bind the custom domain in your ngrok dashboard or config. This lets your tunnel serve traffic under a branded domain with appropriate TLS certs managed by ngrok or provided by you[3].

When not to use ngrok

  • For long-term production hosting of critical services with strict compliance or where full control over the edge network is required, running your own ingress stack (e.g., dedicated load balancers, WAFs, and API gateways) may be preferable. ngrok is great for development, demos, testing webhooks, and some production ingress scenarios where managed features fit requirements, but evaluate compliance, latency, and architecture constraints first[2][3][7].

Conclusion

ngrok works by running a local agent that establishes secure, long-lived outbound connections to a globally distributed network of edge reverse-proxies. Those edges expose public endpoints that route incoming traffic through the encrypted tunnel to your local service while providing inspection, authentication, load balancing, and other ingress features[2][3][4]. The platform’s separation of control and data planes, support for HTTP/TCP/WebSocket protocols, and developer-first tooling (request inspection, replay) make it a powerful tool for both rapid development workflows and for some production ingress use cases[3][4].

Resources

  • Official ngrok documentation: What is ngrok? and product pages[3][6].
  • Sendbird tutorial and explanation of ngrok features[1].
  • PubNub developer guide on how ngrok creates tunnels and bypasses NAT[2].
  • BrowserStack guide covering tunnels, common use cases, and inspection features[4].
  • Requestly blog on using ngrok for webhook development and security considerations[5].

Note: The links above reference the authoritative docs and developer guides that explain ngrok’s architecture, features, and recommended usage patterns; consult the official documentation for the latest configuration options and security practices[3][6].