ngrok vs. sish (The Self-Hosted Serveo): How to Build Your Own Private ngrok Using sish and a $5 VPS

 IT

InstaTunnel Team
Published by the InstaTunnel team | Editorial policy
ngrok vs. sish (The Self-Hosted Serveo): How to Build Your Own Private ngrok Using sish and a $5 VPS

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 guide

Quick answer

ngrok vs sish: Build Your Own Private Self-Hosted Serveo: quick answer

If free tunnel limits interrupt your workflow, compare session length, stable URLs, concurrent tunnels, and paid-plan pricing before choosing a localhost tunnel tool.

What free tunnel limits should developers check first?

Check session duration, URL stability, concurrent tunnels, custom subdomains, bandwidth or request limits, and whether webhook callbacks survive restarts.

How does InstaTunnel handle longer development sessions?

InstaTunnel Free is designed around 24-hour sessions, with Pro available for higher limits and MCP endpoint tunnel workflows.

In modern software development, exposing your local development environment to the public internet is a daily necessity. Whether you are testing webhooks, showcasing a work-in-progress to a client, or debugging a complex API integration, you need a reliable tunnel. For years, developers defaulted to third-party tools like ngrok or Serveo. However, as team sizes grow and security requirements tighten, relying on managed tunneling services can introduce bottlenecks, costs, and security compliance headaches.

If ngrok’s free-tier limits, rate limiting, or the unpredictable uptime of free alternatives like Serveo have ever frustrated you, it might be time to take control of your infrastructure. Enter sish, an open-source, actively maintained alternative that lets you build your own private version of localhost.run or Serveo — or, as of this year, simply use its official managed service instead of self-hosting at all.

In this guide, we’ll walk through the current state of SSH tunneling, compare ngrok and sish accurately against both projects’ own documentation, and provide a step-by-step tutorial for standing up your own private ngrok using sish and a $5 VPS.


The Evolution of Localhost Tunneling

The Reign of ngrok

When developers think of localhost tunneling, ngrok is usually the first name that comes to mind. It revolutionized the way we expose local servers. By running a simple command (ngrok http 8080), you instantly receive a public HTTPS URL forwarding traffic to your local machine.

ngrok’s free tier is genuinely limited, but not in the way most comparison articles describe it. As of ngrok’s own current pricing and limits documentation, the Free plan includes:

  • A one-time $5 usage credit
  • Up to 3 online endpoints and 3 concurrent agents
  • 1 GB of data transfer per month
  • 20,000 HTTP/S requests per month, capped at roughly 4,000 requests/minute
  • 5,000 TCP/TLS connections per month
  • One automatically assigned “dev domain” (e.g. your-name.ngrok-free.app)
  • An interstitial warning page shown to browser visitors on free HTTP/S endpoints (bypassable by sending an ngrok-skip-browser-warning header or a non-default User-Agent — no upgrade required)

A common myth worth correcting: many “ngrok alternative” marketing blogs claim the free tier now enforces a hard 2-hour session timeout. ngrok’s own documentation directly contradicts this — free-tier endpoints have no timeout and can run indefinitely as a background service. The actual constraints are the monthly data, request, and connection caps above, plus the inability to reserve a custom domain and the interstitial page. Treat any article citing a “2-hour limit” with skepticism.

Paid tiers have also been restructured. The current lineup (per ngrok’s pricing and limits pages) is:

PlanPriceData transferRequestsEndpoints
Free$01 GB/mo20k/mo3
Hobbyist$8/mo (annual) or $10/mo5 GB/mo100k/mo3
Pay-as-you-go$20/mo base (includes $20 usage credit)Metered ($0.10/GB)Metered ($1/100k)Unlimited
EnterpriseCustom / quote-onlyCustomCustomCustom

Aside from cost, some corporate networks also restrict or flag ngrok traffic by default, since its shared domains have historically been abused for phishing and malware command-and-control — a security posture problem independent of pricing.

The Rise and Fall of Serveo

As an alternative to ngrok’s proprietary agent, developers flocked to Serveo. Serveo was notable because it required no installation — it leveraged the standard SSH client already installed on almost every developer’s machine. Running ssh -R 80:localhost:8080 serveo.net would instantly return a public URL.

Serveo became a go-to for free SSH tunneling, but its open, unauthenticated nature made it a magnet for phishing and malware abuse. This led to recurring blacklisting and outages. Serveo’s uptime today is still inconsistent — third-party uptime monitors show it flipping between “up” and “down” depending on region and time, consistent with a lightly-maintained free service rather than a reliably available one. It’s still reachable intermittently, but it’s not something to depend on for anything production-adjacent.

Enter sish: The Open-Source Successor

sish, created by developer Antonio Mika, is the open-source community’s answer to the gap Serveo left. It’s an actively maintained project — currently on release v2.23.0 (June 2026), with roughly 4.6k GitHub stars, 329 forks, and 64 tagged releases — and is now sponsored by pico.sh, the SSH-powered developer tools project Mika also maintains.

Unlike Serveo, which existed only as a public service, sish is explicitly designed to be self-hosted on your own infrastructure. It runs as an SSH server that forwards traffic back to connected clients.

One important update since sish’s earlier days: you no longer have to self-host it at all if you don’t want to. The project now offers an official managed service at tuns.sh, maintained by the same team, as the fastest way to try sish without touching a VPS:

ssh -R 80:localhost:8080 tuns.sh

This instantly creates a public URL for something running on local port 8080 — no signup, no client install. Self-hosting remains the better option for teams that need custom domains, private tunnels, or full control over data residency, which is what the rest of this guide covers.

The Superpower of sish

What makes sish stand out in the crowded field of tunneling tools?

  1. Protocol support: sish handles HTTP, HTTPS, TCP, WS (WebSockets), and WSS connections, plus SNI-based TLS routing without terminating the TLS connection itself.
  2. No client installation: Just like Serveo, sish uses the native SSH client (ssh -R). Your team doesn’t need any proprietary CLI tools or agents.
  3. TLS certificates: sish can serve HTTPS either from certificates you provide yourself, or by requesting them on demand from Let’s Encrypt (--https-ondemand-certificate), or — if you use the official Docker Compose deployment — fully automated wildcard certificates via DNS-01 challenges through the bundled dnsrobocert container.
  4. Multiplexing: sish supports wildcard subdomains, letting multiple developers request their own subdomains on the fly (e.g., dev1.yourdomain.com, api-test.yourdomain.com).
  5. Security and auth, on by default: As of the current release, sish requires SSH authentication by default (public key or password) — it is no longer an “open by default, secure it later” tool. You configure who’s allowed in before anyone can open a tunnel, not after.
  6. Private TCP aliases and load balancing: Beyond public tunnels, sish supports internal-only TCP aliases (reachable only via authenticated SSH jump-host access), plus optional load-balancing modes so multiple clients can share the same HTTP, TCP, or SNI endpoint.
  7. Traffic inspection: An optional admin console and per-tunnel service console let you inspect forwarded requests — closing some of the gap with ngrok’s traffic inspector, without sending your traffic through a third party.

ngrok vs. sish: Which is Right for You?

Featurengrok (SaaS)sish (Self-Hosted or Managed)
ArchitectureManaged third-party serviceSelf-hosted on your infrastructure, or use the official tuns.sh managed service
Client softwareRequires the ngrok CLI agentUses native SSH (ssh command)
Custom domainsRequires Hobbyist plan or higherFree on self-hosted; bring your own domain
CostFree (limited) up to $20/mo base + usage on Pay-as-you-go~$5/month VPS + domain, or free via tuns.sh for quick tests
Data privacyTraffic routes through ngrok’s cloudTraffic routes through your own VPS (self-hosted)
Rate limits1GB/20k requests (Free), 5GB/100k (Hobbyist), metered beyond thatNone inherent to sish; bounded only by your VPS bandwidth
Endpoint timeoutNone (a common myth says otherwise)None
Auth by defaultAccount-based (SaaS)SSH key/password auth required by default since recent releases
Setup timeInstantInstant via tuns.sh; ~15–30 minutes for self-hosted VPS setup
MaintenanceNone (managed for you)Minimal (OS and container updates) for self-hosted; none via tuns.sh

When to choose ngrok: you want a polished, fully managed experience with built-in traffic inspection and don’t mind the free tier’s data/request ceilings, or you need enterprise features like SSO and audit logs.

When to choose sish: you have a team that wants persistent custom subdomains without SaaS fees, you handle data that shouldn’t route through a third party, or you want unmetered bandwidth bounded only by your own VPS.


How to Build Your Own Private ngrok Using sish and a $5 VPS

Prerequisites

  1. A Cloud VPS: a basic $5/month instance from DigitalOcean, Linode, Vultr, or Hetzner is sufficient. Choose Ubuntu 22.04 LTS or 24.04 LTS.
  2. A domain name (e.g., my-tunnels.com) to route traffic to your VPS.
  3. Basic terminal knowledge with SSH and the command line.
  4. Your local machine’s SSH public key (usually ~/.ssh/id_ed25519.pub) — you’ll need this up front, since sish now requires authentication from the start.

Step 1: Configure Your DNS Records

For sish to route traffic dynamically to different subdomains, set up a wildcard DNS record. In your domain registrar’s DNS panel, create two A records pointing to your VPS’s public IP:

  1. Primary record: Host my-tunnels.com (or @) → your VPS IP
  2. Wildcard record: Host *.my-tunnels.com → your VPS IP

DNS propagation can take anywhere from a few minutes to a few hours.

Step 2: Prepare Your VPS (Install Docker)

SSH into your VPS:

ssh root@your_vps_ip

Update packages:

sudo apt update && sudo apt upgrade -y

Install Docker via the official script:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
docker --version

Step 3: Deploy sish, Secured From the Start

Older sish guides had you deploy with authentication off and lock it down in a later step. That’s no longer the recommended flow — recent sish releases require SSH authentication by default, so the secure setup and the working setup are now the same step.

Create the required directories and drop your public key in before you start the container:

mkdir -p ~/sish/ssl ~/sish/keys ~/sish/pubkeys
cp ~/.ssh/id_ed25519.pub ~/sish/pubkeys/

Pull the current image and run it, substituting your own domain:

docker pull antoniomika/sish:latest

docker run -itd --name sish \
  --restart always \
  -v ~/sish/ssl:/ssl \
  -v ~/sish/keys:/keys \
  -v ~/sish/pubkeys:/pubkeys \
  --net=host antoniomika/sish:latest \
  --ssh-address=:2222 \
  --http-address=:80 \
  --https-address=:443 \
  --https=true \
  --https-certificate-directory=/ssl \
  --authentication-keys-directory=/pubkeys \
  --private-keys-directory=/keys \
  --bind-random-ports=false \
  --domain=my-tunnels.com

A few notes on these flags: * --net=host binds the container directly to the host’s network interfaces for accurate client IP logging. * --ssh-address=:2222 avoids conflicting with your VPS’s own SSH daemon on port 22. * --authentication-keys-directory=/pubkeys points sish at the folder it should watch for authorized keys; it reloads automatically when you add or remove files, no restart needed. * --bind-random-ports=false lets clients request specific TCP ports instead of always getting a random one. * This basic setup expects certificates already present in /ssl (for example via certbot). If you want sish to fetch Let’s Encrypt certificates on demand itself, add --https-ondemand-certificate --https-ondemand-certificate-accept-terms; for fully automated wildcard certs via DNS challenge, use sish’s official Docker Compose deployment instead, which bundles the dnsrobocert container for that purpose.

Check the logs to confirm it started cleanly:

docker logs -f sish

Step 4: Test Your New Private ngrok

From your local machine — not the VPS — with a local server running on port 3000:

ssh -p 2222 -R 80:localhost:3000 my-tunnels.com

Because your public key is already trusted, this connects immediately and returns an HTTPS URL such as:

Press Ctrl-C to close the session.
Forwarding to:
https://randomstring.my-tunnels.com

Requesting a Custom Subdomain

ssh -p 2222 -R custom-name:80:localhost:3000 my-tunnels.com

This attempts to bind https://custom-name.my-tunnels.com, as long as that subdomain isn’t already claimed by another user on your server.

Managing Developer Access

Because the pubkeys directory is watched continuously, adding or removing a teammate’s access is just a file operation — no restart required:

nano ~/sish/pubkeys/new_teammate.pub
# paste their public key, save

A convenient shortcut for onboarding via GitHub-hosted keys:

curl https://github.com/their-github-username.keys > ~/sish/pubkeys/their-github-username

Advanced sish Use Cases

1. Bypassing Firewalls with TCP Tunnels

sish isn’t limited to HTTP/HTTPS. To expose a local MySQL instance (port 3306) to a remote client:

ssh -p 2222 -R 3306:localhost:3306 my-tunnels.com

Your remote client connects to my-tunnels.com:3306 and traffic routes securely to your local database.

2. Private TCP Aliases (No Public Exposure at All)

For access patterns that shouldn’t be internet-facing even behind auth, sish supports TCP aliases reachable only through an authenticated SSH jump host — nothing is bound publicly:

ssh -p 2222 -R mylaptop:22:localhost:22 my-tunnels.com

A teammate with access can then reach it via:

ssh -J my-tunnels.com mylaptop

3. Team-Wide Integration

Standardize the tunnel command into your team’s package.json or Makefile:

"scripts": {
  "start": "react-scripts start",
  "tunnel": "ssh -p 2222 -R $(whoami)-dev:80:localhost:3000 my-tunnels.com"
}

When Alice runs npm run tunnel, she gets alice-dev.my-tunnels.com; Bob gets bob-dev.my-tunnels.com.

4. CI/CD Pipeline Testing

Since sish only needs a standard SSH client, it’s straightforward to integrate into GitHub Actions or GitLab CI — spin up a temporary app instance, tunnel it through your sish server, and run end-to-end tests against the public URL before tearing it down.

5. Load Balancing and SNI Routing

If your use case grows beyond a single developer’s tunnel, sish’s optional load-balancer modes (--http-load-balancer, --tcp-load-balancer, --sni-load-balancer) let multiple clients share the same bound domain, port, or SNI hostname — useful for basic multi-instance failover without standing up a separate load balancer.


Summary

ngrok’s polish and traffic-inspection tooling remain genuinely useful, and its free tier — while capped on data and requests, not session length — is a reasonable way to kick the tires. But for teams that want control, data privacy, and predictable costs, self-hosting has gotten easier, not harder: sish now ships secure by default, offers a managed tuns.sh option for zero-setup testing, and has grown features (TCP aliases, SNI proxying, load balancing, traffic consoles) that narrow the gap with commercial tunneling platforms.

By investing about $5 a month and 20 minutes of setup time, you can run a private, custom-branded tunneling server that your whole team controls.


Changelog

This article was rewritten from a submitted draft and fact-checked against primary sources on July 18, 2026.

Corrections: 1. Removed the “ngrok free-tier 2-hour session timeout” claim entirely and added an explicit correction. ngrok’s own Free Plan Limits documentation states free-tier endpoints have no timeout and can run as a background service indefinitely; the real constraints are monthly data/request/connection caps. Source: ngrok.com/docs/pricing-limits/free-plan-limits. 2. Updated ngrok’s pricing structure, which the original draft only described in general terms. Current tiers per ngrok’s own pricing/limits docs: Free ($0, $5 one-time credit, 3 endpoints, 1GB/20k requests monthly), Hobbyist ($8/mo annual or $10/mo, 5GB/100k requests, still 3-endpoint cap), Pay-as-you-go ($20/mo base including $20 usage credit, unlimited endpoints, metered overage), Enterprise (custom/quote-only). Source: ngrok.com/docs/pricing-limits. 3. Corrected the sish Docker deployment flow. The original draft’s “Step 5: secure your server” pattern (deploy with --authentication=false, then lock it down later) no longer matches sish’s current defaults: the --authentication flag now defaults to true, meaning sish requires SSH auth out of the box. The tutorial was restructured to place your public key in ~/sish/pubkeys before first launch rather than deploying an open relay first. Source: docs.ssi.sh/cli and docs.ssi.sh/getting-started. 4. Updated the Docker run command to match the current officially documented example, which adds --private-keys-directory=/keys and --bind-random-ports=false flags not present in the original draft. Source: github.com/antoniomika/sish (README) and docs.ssi.sh/getting-started. 5. Corrected the Let’s Encrypt automation claim. The plain docker run deployment does not automatically provision Let’s Encrypt certificates on its own — it expects certificates already present in the mounted /ssl directory unless you add the --https-ondemand-certificate flag, or use sish’s official Docker Compose deployment, which bundles the dnsrobocert container specifically for automated wildcard DNS-01 certificates. Source: docs.ssi.sh/getting-started.

Additions (not in the original draft): 6. Added sish’s official managed service, tuns.sh, as a zero-setup option for trying sish without a VPS. Source: github.com/antoniomika/sish, docs.ssi.sh/getting-started. 7. Added current project stats and status: sish is at release v2.23.0 (June 2026), ~4.6k GitHub stars, 329 forks, 64 tagged releases, and is sponsored by pico.sh. Source: github.com/antoniomika/sish. 8. Added coverage of sish’s private TCP alias feature (SSH jump-host access with no public binding) and its optional HTTP/TCP/SNI load-balancer modes, neither of which appeared in the original draft. Source: docs.ssi.sh/cli, github.com/antoniomika/sish. 9. Added sish’s admin/service console feature for inspecting forwarded traffic, as a self-hosted parallel to ngrok’s traffic inspector. Source: docs.ssi.sh/cli. 10. Softened the Serveo reliability claim to reflect current, mixed uptime-monitor reports rather than presenting a specific characterization of its downtime, since third-party monitors show it as intermittently reachable rather than consistently down. Source: aggregated third-party uptime monitors (isitdownorjustme.net, notopening.com), cross-checked July 2026.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#ngrok vs sish, sish vs ngrok, sish, ngrok alternative, best ngrok alternative, free ngrok alternative, self hosted ngrok, self hosted ngrok alternative, serveo alternative, self hosted serveo, open source ngrok alternative, open source serveo alternative, ssh tunneling, ssh reverse tunnel, secure shell tunnel, local tunneling tool, private ngrok, build private ngrok, $5 vps proxy, cheap vps tunnel, self hosted tunneling service, private tunneling tool, route local traffic, expose localhost via ssh, bypass third party infrastructure, team ssh tunneling, standard ssh commands, port forwarding ssh, open source reverse proxy, self host webhooks, dynamic subdomain routing, automatic let's encrypt, custom domains proxy, http tunnel, https tunnel, tcp tunnel, websocket tunnel, ws tunnel, wss tunnel, sish github, sish tutorial, install sish vps, ngrok pricing alternative, ngrok limits bypass, local development server sharing, forward ports ssh, private localhost.run, self managed tunnel, ssh client port forwarding, secure tcp tunnel, websockets reverse proxy, let's encrypt ssl tunnel, custom domain ssh tunnel, web development tunneling tools, devops ssh tools, host internal apps public, self hosted url generator, persistent ssh tunnel, local environment proxy, bypass ngrok paywall

Comments