How to Keep Your ngrok URL Stable with Custom Subdomains
Stabilize your ngrok URLs with a custom subdomain. Reserve a permanent hostname once, then run local services with a fixed public link, inspect traffic, and secure the tunnel. Step‑by‑step guide, trade‑offs, and best practices.
03 Mar 2026, 19:19 UTC

Problem: Random URLs Make Sharing a Pain
When you run ngrok http 3000 on a free account, the public URL changes every time you start the tunnel. That means you have to copy a new link each time you want to share a demo, hook a webhook, or run automated tests that expect a fixed endpoint. For teams and continuous integration setups this churn is a real productivity killer.
The Custom Subdomain Feature
ngrok’s paid plans include a Custom Subdomain option. You reserve a human‑readable hostname once (e.g., dev-api.your‑app.ngrok.io) and every tunnel you launch with that subdomain will expose the same public URL, regardless of restarts or the machine you’re on.
Key points:
- Only available on paid tiers (Basic or higher).
- Subdomains are globally unique per account; a collision will block the reservation.
- Once bound, the URL is stable across all your tunnels until you cancel the reservation.
Step‑by‑Step Example
1️⃣ Prepare a Local Service
# Express API running on port 3000
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello from ngrok!'));
app.listen(3000, () => console.log('API listening on 3000'));
2️⃣ Reserve the Subdomain in the Dashboard
- Log in to ngrok dashboard.
- Navigate to Reserved Domains and click Reserve a Domain.
- Enter
dev-apias the subdomain and choose the region that matches your local machine. - Confirm the reservation; the dashboard will show
dev-api.your-app.ngrok.iounder your account.
3️⃣ Start the Tunnel with the Subdomain
# Run this in the terminal where your API is listening
ngrok http --subdomain=dev-api 3000
After a few seconds the console will display something like:
Forwarding https://dev-api.your-app.ngrok.io -> http://localhost:3000
Open that URL in a browser or send a request with curl to verify the response.
4️⃣ Inspect Traffic
The ngrok dashboard shows a live request inspector. You can replay any captured request, view headers, and debug payloads directly from the browser – a huge time‑saver when troubleshooting webhooks or third‑party integrations.
Trade‑offs & Security Considerations
| Aspect | Benefit | Risk / Cost |
|---|---|---|
| Cost | Monthly fee for the paid tier. | Must budget for the plan. |
| Security | Publicly reachable endpoint. | Require authentication, rate limits, or IP whitelisting. |
| Global Uniqueness | Ensures a stable URL. | Collision if someone else already owns your chosen subdomain. |
| Availability | Always works across machines. | Network issues or ngrok outage could affect access. |
Because the URL is exposed to the internet, treat it like any public API: add bearer tokens, OAuth, or basic auth; consider using ngrok’s auth header feature to gate traffic.
Actionable Next Steps
- Sign up for a paid ngrok plan if you don’t already have one.
- Reserve a subdomain that reflects the service you’ll expose (e.g.,
dev-apifor a development API). - Update your local service’s configuration to use the new URL in webhooks or callback URLs.
- Add basic auth or an API key to the tunnel with
ngrok http --auth "user:pass" --subdomain=dev-api 3000. - Use the request inspector to replay failing requests during debugging sessions.
- Keep an eye on the ngrok dashboard for usage metrics and any alerts.
With a reserved subdomain you’ll no longer need to chase a new URL each time you run ngrok. It gives your local services a stable, shareable address, making demos, integrations, and automated tests smoother and more reliable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.