· infrastructure · 5 min read

You Secured Plex. Now It Buffers.

The old setup was ugly in a familiar way: port 32400 open, DDNS, and a reverse proxy that only existed because you knew where it lived. The new setup looked better on paper: no exposed ports, Cloudflare Tunnel, cleaner perimeter. The problem showed up at the couch.

on this page
  1. What Changes In The Path
  2. Where The Tunnel Belongs
  3. What Plex Actually Needs
  4. A Better Rule
  5. What I Would Do Again
  6. The Part That Matters

The old setup was ugly in a familiar way: port 32400 open, DDNS, and a reverse proxy that only existed because you knew where it lived. The new setup looked better on paper: no exposed ports, Cloudflare Tunnel, cleaner perimeter. The problem showed up at the couch. Streams started slower, buffers appeared more often, and the thing that was supposed to feel safer started feeling broken.

That is the part most tunnel writeups skip. Cloudflare Tunnel is a good answer for a lot of things. Plex is not one of them.

I am not arguing that tunnels are bad. I am arguing that not every service is shaped like a browser tab. Some services are short, request/response, and forgiving. Others are continuous, bandwidth-heavy, or protocol-specific. Plex sits in the second group. When I moved it off the tunnel and onto direct WireGuard access, remote startup dropped by roughly 4 to 6 seconds and buffering went from about 3 to 5 hits per two-hour film to near zero. That was not a lab benchmark. It was the thing I could actually feel while watching.

What Changes In The Path

With the old setup, a client reached Plex directly through my public address and a proxy in front of it. With Cloudflare Tunnel, the path changes:

client -> Cloudflare edge -> cloudflared -> Plex

That extra hop matters less for a dashboard. A login page, a settings screen, or a tiny JSON API response can absorb a little added latency and nobody notices. It matters a lot more when the connection has to keep pushing video, chunk after chunk, for minutes at a time.

For Plex, the issue is not just latency. It is latency plus sustained throughput plus jitter. A stream is not one request. It is a long series of reads that need to arrive on time. If one segment stalls, playback pauses. If enough segments arrive late, users call it “buffering” and stop caring why.

You can see the difference with a simple test from a remote client:

curl -svo /dev/null -H "X-Plex-Token: YOUR_TOKEN" \
  -w "TTFB: %{time_starttransfer}s | Total: %{time_total}s\n" \
  "https://plex.example.com/library/metadata/123/stream"

curl -svo /dev/null -H "X-Plex-Token: YOUR_TOKEN" \
  -w "TTFB: %{time_starttransfer}s | Total: %{time_total}s\n" \
  "http://plex.lan:32400/library/metadata/123/stream"

That is not a perfect benchmark. It does not tell you everything about sustained playback. It does tell you whether your remote path is adding visible overhead before the stream even settles in.

Where The Tunnel Belongs

The real mistake is treating “secure” as a single category. Different services need different exposure models.

Service type Tunnel Better path
Admin dashboards Yes Cloudflare Tunnel is a strong fit
Small HTTP APIs Yes Cloudflare Tunnel is usually fine
Plex or Jellyfin No WireGuard or direct LAN access
Game servers No VPN, direct port mapping, or a protocol-specific relay
Databases and binary protocols No Keep them off the public edge

That table is the whole argument in compact form. If a service is browser-shaped, tunnel it. If it moves a lot of data continuously, or if it is not really HTTP at all, stop trying to squeeze it through the same opening you use for Grafana.

There is also a security mistake hidden in over-tunneling. A service that should stay internal does not become safer because you routed it through a third-party edge. It becomes dependent on another system that now sits in the middle of your traffic. For a control plane, that tradeoff can be worth it. For a media plane, it usually is not.

What Plex Actually Needs

Plex is not just “a web app with video.” It is a media delivery system that wants low friction, predictable bandwidth, and as few hops as possible. When I tunneled it, I was asking Cloudflare to play traffic cop for a stream that never stops. The tunnel did its job. The stream paid the price.

That is why the failure was so frustrating. Nothing was obviously down. The tunnel stayed healthy. The dashboard stayed green. The stream still looked reachable. The bad part was subtler: everything appeared fine until the video had to move at real speed.

The difference between “reachable” and “usable” matters here.

Plex being reachable through a tunnel is not the same as Plex being pleasant to use through a tunnel.

A Better Rule

The rule I use now is simple:

If the service is interactive, short-lived, and mostly HTTP, Cloudflare Tunnel is a good option.

If the service is continuous, high-throughput, or protocol-sensitive, do not tunnel it.

If you are unsure, ask two questions:

  1. Does this service spend most of its time waiting for short requests, or does it stream data for long stretches?
  2. If the path adds 20 to 40 ms, or occasionally 200 ms, will users notice?

For a dashboard, the answer is usually no. For Plex, the answer is yes immediately.

That is why WireGuard was the clean fix for me. Once I moved Plex onto VPN access, it behaved like a local service again. The tunnel stayed in place for the things it is actually good at: admin surfaces, small APIs, and the bits of infrastructure I want reachable without opening the whole house.

What I Would Do Again

If I were rebuilding the stack today, I would split it like this:

Cloudflare Tunnel for:

WireGuard or LAN-only access for:

That keeps the perimeter narrow without forcing every service to share the same remote path. It also keeps the mental model honest. A tunnel is not “secure by default.” It is “appropriate for a specific class of traffic.” Those are not the same thing.

The Part That Matters

The real lesson is not “never use Cloudflare Tunnel.” It is “do not confuse exposure with fit.”

I like the tunnel for the services it was built for. I still use it. But Plex taught me the edge of the idea. Security improves when you expose less, yes. It also improves when you choose a path that matches the traffic instead of forcing everything through the same gate.

If you want the shortest version, it is this:

Cloudflare Tunnel is great for control planes. Plex is a media plane. Those are different problems, and they deserve different routes.

What a Tunnel Is (The Long Way Round Your House) The old setup: port 32400 open, DDNS, a Caddy proxy. The new setup: zero exposed ports, Cloudflare Tunnel, clean. More s

The Performance Problem Is Two Problems, Depending on How Plex Streams The old setup: port 32400 open, DDNS, a Caddy proxy. The new setup: zero exposed ports, Cloudflare Tunnel, clean. More s