I’m running n8n in Docker on CasaOS and exposing it via Cloudflare Tunnel so the Gmail API can hit my webhooks. The app itself is perfectly healthy, local access and Tailscale are both instant and rock-solid.
The problem only shows up when going through my Cloudflare-tunneled domain: pages take forever to load or just hang indefinitely.
A few things I’ve ruled out:
It’s not the app (local/Tailscale = flawless)
It’s not my hardware or Docker setup
What I’m suspecting:
Cloudflare routing my tunnel through a distant edge node (I’m in Southeast Asia)
Some Docker networking quirk with cloudflared
Has anyone dealt with consistent latency or timeouts through Cloudflare Tunnels, especially in the SEA region or with a Docker-based setup? Would love to hear what helped, whether it’s a cloudflared config tweak, region pinning, or something else entirely.
@mitidi Have you considered using Nginx as a reverse proxy instead of relying solely on Cloudflare Tunnel?
A setup that tends to work much better for self-hosted n8n is to put Nginx in front of it as a reverse proxy, then point your Cloudflare Tunnel (or even just Cloudflare’s DNS proxy) at Nginx rather than directly at n8n. Here’s the general approach:
Create a subdomain (e.g. n8n.yourdomain.com) and point it to your server via Cloudflare DNS.
Set up Nginx as a reverse proxy to forward traffic from that subdomain to your n8n container (typically running on port 5678).
Let Cloudflare handle SSL (Flexible or Full mode), so you don’t need to manage certificates manually.
Hi @mitidi, if local and Tailscale are flawless and only the Cloudflare domain hangs, this is very likely the editor’s push connection being rejected, not edge distance. Since v1.87 n8n strictly validates the Origin header on the /rest/push socket, and Cloudflare Tunnel forwards that header without the https:// scheme, so the check fails and the editor sits there waiting on a socket that never opens.
To confirm: open the editor on the Cloudflare domain with browser devtools, do you see a “Connection lost” banner and a failing /rest/push request? And what n8n version are you on? (Shawn’s reverse-proxy idea can work too, but if it’s this you can fix it in Cloudflare without adding Nginx.)
Look for the cf-ray header. The 3-letter code at the end (e.g., SIN for Singapore, HKG for Hong Kong) tells you which data center is handling your request.
If you see a code like SJC (San Jose) or LHR (London) while in SEA, you have a routing issue.
The Fix: If routing is the problem, the only “free” fix is to restart the cloudflared container to try and force a new connection to a closer PoP. If you have a paid plan, Argo Smart Routing solves this instantly.
By default, cloudflared tries to use QUIC (UDP 443) to connect to the Cloudflare edge. In some SEA ISPs, UDP traffic is throttled or aggressively shaped, leading to massive packet loss and the “infinite hang” you’re describing.
The Fix: Force the tunnel to use TCP instead of QUIC.
How to do it:
If running via Docker CLI/Compose, add the flag --protocol http2 to your cloudflared start command.
Example: cloudflared tunnel run --protocol http2 <tunnel-name>
Why this works: HTTP/2 over TCP is often more stable on restrictive SEA residential networks than QUIC.
Since local and Tailscale are both instant and only the Cloudflare-tunneled domain hangs, this is the tunnel path, not n8n. A couple of things that cause exactly this. Cloudflare buffers and can choke on the long-lived connections n8n’s UI uses (server-sent events for the editor), and a bare tunnel straight to n8n often handles those badly, which shows up as pages that load forever or hang. Putting Nginx as a reverse proxy in front of n8n and pointing the tunnel at Nginx, as suggested above, tends to fix it because Nginx handles the connection upgrades cleanly. Also check you have set N8N_PROTOCOL, N8N_HOST and WEBHOOK_URL to your real https domain, and that the tunnel is not adding a second layer of TLS negotiation on every request. Start with the Nginx-in-front setup, it resolves the majority of these.