{"schemaVersion":"1.0","type":"Article","types":["Article"],"slug":"self-hosting-from-home-cloudflare-tunnel-vs-tailscale-funnel-vs-ngrok-iya4a","url":"https://zyvop.com/self-hosting-from-home-cloudflare-tunnel-vs-tailscale-funnel-vs-ngrok-iya4a","title":"Self-Hosting from Home: Cloudflare Tunnel vs. Tailscale Funnel vs. ngrok","subtitle":"Cloudflare Tunnel, Tailscale Funnel and ngrok compared for serving a site from home: domains, free-tier limits, security and which one to pick.","tldr":"You can serve a site from a spare machine at home without opening a router port. This post compares Cloudflare Tunnel, Tailscale Funnel and ngrok on setup, domains, free-tier limits and security, with a decision flow for choosing the right one for a demo, a personal site or a real domain.","keywords":["self-hosting","ngrok","Tailscale","Cloudflare Tunnel","Homelab","Versus"],"entities":["Shobit Singh","self-hosting","ngrok","Tailscale","Cloudflare Tunnel","Homelab","Versus","ZyVOP"],"keyTakeaways":["The short version You can serve a site from a spare machine at home without opening a single router port, by using a tunnel that your machine opens to a provider.","They differ in whose domain you use, what the free tier allows, and what each one was built for.","Cloudflare Tunnel is the pick for a site you want to keep running under your own domain."],"headings":["The short version","How all three work","Cloudflare Tunnel: your domain, always on","Setting up a permanent tunnel","What you get","Where it falls short","Tailscale Funnel: the fastest start, with the tightest rules","Setting it up","ngrok: built for development, usable for hosting","What the plans give you","The interstitial page","Running it from a config file","Where it earns its place","Side by side","Security: the tunnel is your new front door","Which one should you pick?","Sources"],"outboundLinks":["https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/","https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/","https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/","https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/create-local-tunnel/","https://blog.cloudflare.com/tunnel-for-everyone/","https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/error-413/","https://blog.cloudflare.com/updated-tos/","https://tailscale.com/kb/1223/funnel","https://tailscale.com/kb/1311/tailscale-funnel","https://ngrok.com/docs/universal-gateway/domains/","https://ngrok.com/docs/gateway/endpoints/agent-cli-quickstart.md","https://ngrok.com/pricing","https://ngrok.com/docs/pricing-limits/free-plan-limits/","https://ngrok.com/docs/agent/config/v3/","https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-public-app/","https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/configuration-file/","https://ngrok.com/docs/gateway/agent/cli/"],"contentText":"The short version You can serve a site from a spare machine at home without opening a single router port, by using a tunnel that your machine opens to a provider. They differ in whose domain you use, what the free tier allows, and what each one was built for. Cloudflare Tunnel is the pick for a site you want to keep running under your own domain. Tailscale Funnel is the fastest to set up if you already use Tailscale: one command gives you a public HTTPS address with no domain to buy, but it has tight limits on ports and bandwidth, and it is still in beta. ngrok is built for development and demos. It has the best request inspector of the three, but its free plan has small monthly quotas. The rest of this post explains how each works, where each one breaks, and how to choose. Limits and pricing change often, so the figures here are as of October 2026 and link to their sources at the end. How all three work All three swap a port-forwarding problem for an outbound-connection problem. A small agent on your machine opens a connection to the provider, and the provider sends each visitor's request down it and returns the response the same way, so your router never accepts a connection from outside. Cloudflare notes that this works without a publicly routable IP address, which helps when your internet provider shares one address across many customers. flowchart LR V[\"Visitor&lt;br/&gt;with a browser\"] -- request --&gt; P[\"Provider's edge&lt;br/&gt;Cloudflare, Tailscale relay or ngrok\"] P &lt;==&gt;|\"one connection, opened outbound&lt;br/&gt;from your machine\"| A subgraph Home[\"Your home network: no inbound port open\"] A[\"Tunnel agent&lt;br/&gt;cloudflared, Tailscale or the ngrok agent\"] --&gt; App[\"Your app&lt;br/&gt;listens on localhost only\"] endCloudflare Tunnel: your domain, always on Cloudflare Tunnel is the one to use for a site that should stay up, because it puts a hostname on your own domain in front of your home server and keeps it there. A program called cloudflared opens outbound connections from your machine to the nearest Cloudflare data center, and Cloudflare's docs note that you can then block all inbound traffic at your firewall. The catch comes first: to publish an application through a tunnel, you must add a domain to Cloudflare. If you do not own one yet, a quick tunnel works for testing: cloudflared tunnel --url http://localhost:8080That prints a random trycloudflare.com address and needs no account or domain, but the address changes every time. Cloudflare says quick tunnels are for testing, have no uptime guarantee, allow 200 in-flight requests per tunnel (more get a 429), and do not support Server-Sent Events. Setting up a permanent tunnel There are two ways to do it: In the dashboard. Go to Networking, then Tunnels, and create a tunnel. Copy the install command it generates for your operating system and run it on the server. Then add a published application route: choose a subdomain and domain, and set the service URL, such as http://localhost:8000. With a config file. Keep the rules in config.yml and run the tunnel from it: tunnel: &lt;Tunnel-UUID&gt; credentials-file: /root/.cloudflared/&lt;Tunnel-UUID&gt;.json ingress: - hostname: example.com service: http://localhost:8000 - service: http_status:404The final http_status:404 rule is a required catch-all. Two commands help while you write the file: cloudflared tunnel ingress validate checks the rules, and cloudflared tunnel ingress rule https://example.com shows which rule a URL matches. To create and run the same tunnel from the command line, these four commands are enough: cloudflared tunnel login cloudflared tunnel create home cloudflared tunnel route dns home app.example.com cloudflared tunnel run homeIf your config file is elsewhere or has a custom name, put --config /path/your-config-file.yml before run. What you get No charge for the tunnel. Cloudflare announced in 2021 that any organization can use the outbound-only connection at no cost. Check current terms before you depend on it. More than websites. Tunnel can also connect SSH servers, remote desktops and other protocols. Failover. You can run as many cloudflared connectors as you like in one tunnel, so a second machine at home can take over. A login in front. Cloudflare Access applications are deny-by-default, so you add an Allow policy for the people you trust. The Security section covers the order to set it up in. Where it falls short Uploads are capped. Requests through Cloudflare's proxy are limited to 100 MB on the Free and Pro plans and 200 MB on Business. Media rules. Cloudflare's CDN terms still restrict video and large files hosted outside Cloudflare. The announcement does not say whether that covers Tunnel, so read the current terms before you stream media from home. Tailscale Funnel: the fastest start, with the tightest rules If you already run Tailscale, Funnel is the quickest way to make one service public: one command gives you an HTTPS address, with nothing to install beyond Tailscale. Tailscale describes it as routing traffic from the public internet to a service on a device in your tailnet, through an encrypted TCP proxy on Funnel relay servers that cannot decrypt the traffic. Setting it up You need Tailscale v1.38.3 or later, MagicDNS, HTTPS certificates enabled for the tailnet, and the funnel node attribute in your policy file (by default it goes to autogroup:member). The first time you run tailscale funnel, it opens a web page where you approve Funnel, and Tailscale then creates the certificates and adds the attribute for you. # Expose the app on local port 3000 and keep it running after reboots tailscale funnel --bg 3000 # See what is currently public tailscale funnel status # Turn everything off tailscale funnel resetThe --bg flag matters. Without it, Funnel stops when you reboot or restart Tailscale and you have to start it again by hand. With it, Funnel resumes on its own. What you get No domain to buy. Your address is a name under your tailnet's ts.net domain, and nothing else is needed. A private mode on the same tool. tailscale serve shares a service only with devices in your tailnet, while Funnel makes it public. A port cannot be both at once: the most recent serve or funnel command on it decides. Every plan. Funnel is available on all Tailscale plans. Where it falls short Three ports only. Funnel can listen only on 443, 8443 and 10000. TLS only. Funnel works only over TLS-encrypted connections, so it is not a way to expose a plain TCP service. Beta. Tailscale still labels Funnel as beta, so behavior and limits may change. Bandwidth limits you cannot tune. Traffic is subject to non-configurable bandwidth limits, and the docs give no figures. Test it with your real traffic before you rely on it, especially if you serve large files. Your names only. Funnel can use only names in your tailnet's domain, so your own domain is not an option. ngrok: built for development, usable for hosting ngrok is the tool here that is best at inspecting and shaping traffic, and its free plan is sized for testing rather than for running a site. Getting started takes one command: ngrok http 8080Every account gets a free dev domain. Per ngrok's docs, \"its URL is automatically generated and cannot be changed,\" and it is a stable, auto-assigned hostname. Choosing your own name with the --url flag is a paid-plan feature. What the plans give you Free Hobbyist ($10 a month) Domains 1 auto-assigned dev domain 10 ngrok-branded domains Data transfer out 1 GB a month 5 GB a month, then $0.10 per GB HTTP requests 20,000 a month 100,000 a month, then $1 per 100,000 Interstitial warning page Shown to browsers Removed Online endpoints 3 3 Traffic Inspector history 24 hours 72 hours Bringing your own custom domain starts at the Pay-as-you-go plan, which is $20 a month plus usage. The free-plan figures come from ngrok's limits page. The interstitial page On the free plan, ngrok shows a warning page before HTML traffic from a browser, to deter phishing. A visitor who clicks through gets a cookie that hides the page for that domain for 7 days. It does not affect API or programmatic clients, and you can skip it by sending an ngrok-skip-browser-warning header with any value. Running it from a config file Open the config with ngrok config edit, which creates ngrok.yml when you add your authtoken. A minimal v3 file looks like this: version: 3 agent: authtoken: YOUR_AUTHTOKEN endpoints: - name: home url: your-assigned-name.ngrok-free.app upstream: url: 8080Then ngrok start home runs it in the foreground. To keep it running without a terminal open, install the agent as an operating system service: ngrok service install --config=/etc/ngrok/ngrok.yml ngrok service startThe service behaves as if you had run ngrok start --all, so your config file has to define the endpoints. The docs do not say whether the service starts at boot, so reboot the machine once and check. Where it earns its place Seeing every request. The Traffic Inspector shows requests and responses, which is why ngrok is so good for webhook work. Rules in front of your app. Traffic Policy lets you add checks such as OAuth or webhook verification before a request reaches you. The free plan allows 5 rules per policy and 3 monthly active users on OAuth and OIDC logins. Where it falls short Small quotas. A page with a few images can use up the monthly data allowance quickly, and the request allowance is small for anything public. A warning page for browsers. The free-plan interstitial described above is a real annoyance on a website your friends open in a browser, and only a paid plan removes it. Side by side The three differ most in who owns the address and how much traffic they allow. Cloudflare Tunnel Tailscale Funnel ngrok (Free plan) Your address Your own domain; quick tunnels get a random trycloudflare.com name A name under your tailnet's ts.net domain An auto-assigned dev domain that cannot be changed Domain you must own Yes, added to Cloudflare, for a permanent tunnel No No What it carries HTTP sites, plus SSH, remote desktop and other protocols TLS-encrypted connections on ports 443, 8443 and 10000 HTTP endpoints; raw TLS endpoints need a paid plan Traffic limits 100 MB per upload on Free and Pro zones; no monthly quota stated Bandwidth limits you cannot change, with no figures published 1 GB out and 20,000 HTTP requests a month Maturity Quick tunnels have no uptime guarantee; permanent tunnels are the production path Beta Free plan shows a warning page to browsers Security: the tunnel is your new front door A tunnel removes your router as a barrier, so anything you publish is reachable from the whole internet and needs its own login before you point a hostname at it. Put a login in front first. With Cloudflare, create the Access application before the tunnel route, because a route without one is open to anyone, and turn on Protect with Access so cloudflared rejects requests that bypass Access. With ngrok, add OAuth through Traffic Policy. Tailscale's Funnel page describes no login layer, so the app has to handle authentication itself, or you can use tailscale serve to keep the service private to your tailnet. Bind the app to localhost. If the app listens only on 127.0.0.1, other devices on your home network cannot reach it directly, and the tunnel agent is the only way in. Keep the machine small. Use a dedicated machine, a VM or a container, run the app as a non-root user, turn on automatic security updates, and keep nothing sensitive beside it. Assume the provider can read HTTP traffic, except on Funnel. Cloudflare Access and ngrok's Traffic Policy and inspector work on the contents of HTTP requests, which means that traffic is visible to them. Tailscale says Funnel relays cannot decrypt what they carry. Either way, keep secrets out of URLs and logs. Know your off switch. tailscale funnel reset clears Funnel, ngrok service stop stops the ngrok service, and stopping the cloudflared process closes the tunnel. Try it once before you need it. Which one should you pick? Start with what the thing is for, then ask about your domain, and only then check whether Funnel's rules fit. flowchart TD Q1{\"Is it a demo, a webhook test&lt;br/&gt;or something you are still building?\"} Q1 -- yes --&gt; R1[\"ngrok&lt;br/&gt;Request inspector and replay, free dev domain\"] Q1 -- no --&gt; Q2{\"Do you want visitors to see&lt;br/&gt;your own domain in the address?\"} Q2 -- yes --&gt; R2[\"Cloudflare Tunnel&lt;br/&gt;Your domain, Access login in front, no charge for the tunnel\"] Q2 -- no --&gt; Q3{\"Do you already use Tailscale and need&lt;br/&gt;only TLS on 443, 8443 or 10000?\"} Q3 -- yes --&gt; R3[\"Tailscale Funnel&lt;br/&gt;One command, no domain to buy, beta, with limits you cannot tune\"] Q3 -- no --&gt; R4[\"Buy a domain, use Cloudflare Tunnel&lt;br/&gt;or move to a paid ngrok plan\"]The order matters because the free plans fail in different places. ngrok's quotas and warning page get in the way of a public site first, Cloudflare's domain requirement gets in the way if you do not own a domain, and Funnel's ports and bandwidth limits get in the way of anything heavy. If two answers fit, choose the one whose limit you can live with. Sources All pages were opened in October 2026. Cloudflare Cloudflare Tunnel overview Create a remotely-managed tunnel Create a locally-managed tunnel Tunnel configuration file Quick Tunnels (TryCloudflare) Secure a public hostname with Access Error 413 and maximum upload sizes Goodbye, section 2.8, and hello to Cloudflare's new terms of service Cloudflare Tunnel for everyone (April 2021) Tailscale Tailscale Funnel The tailscale funnel command ngrok Free plan limits Pricing Domains and dev domains Agent CLI quickstart Agent CLI reference Agent config v3","contentHash":"sha256:26ad2fc1fa2554183def95445f5ea8c51128054da0f607f519deef6c15c92969","authorName":"Shobit Singh","authorUrl":"https://zyvop.com/author/shobit","authorSameAs":[],"category":"Versus","tags":["self-hosting","ngrok","Tailscale","Cloudflare Tunnel","Homelab"],"audience":"Software engineers and developers building applications with Versus","tone":"Analytical, comparative, and data-driven","readingTimeMinutes":9,"wordCount":2369,"faqs":null,"primaryTopic":"Versus","publishedAt":"2026-10-26T10:33:49.865Z","updatedAt":"2026-10-26T10:33:49.865Z","canonicalUrl":"https://zyvop.com/self-hosting-from-home-cloudflare-tunnel-vs-tailscale-funnel-vs-ngrok-iya4a"}