You board a train to Edinburgh. Three-hour ride, you have one Netflix episode downloaded but you remember a full season of "Severance" waiting in 1080p on your home Jellyfin. You connect to onboard Wi-Fi, open the Jellyfin app on your phone. First eight seconds play smoothly. Then buffering. Bitrate drops from 8 Mbps to 2. From 1080p to 480p. Ben Stiller's face turns into a JPEG mosaic. You hit pause, restart - same thing. WireGuard? Even worse, because encryption and MTU fragmentation pile on. You fall back to the downloaded Netflix. Most remote streaming methods are simply broken - and it's not your Wi-Fi's fault.
Why Jellyfin is harder to stream than HA or Nextcloud#
Home Assistant pushes a few kilobytes of telemetry and the occasional camera snapshot. Nextcloud sync runs once a day and can wait. Jellyfin must deliver a constant stream with guaranteed throughput, no dropped frames, and no pause longer than the player buffer (typically 10 seconds).
Bandwidth is a merciless equation. 4K HDR HEVC = 25 Mbps sustained. 1080p H.264 = 8 Mbps. WireGuard + UDP fragmentation + retransmits = real overhead of 20-30% end-to-end. Your home 50 Mbps upload suddenly becomes 35 Mbps usable - critically close to the 25 Mbps a 4K stream needs.
HTTPS is required by modern players. Chromecast since 2023 refuses to cast HTTP streams. Jellyfin Mobile (iOS/Android) requires TLS for background playback. Jellyfin Web in Chrome blocks mixed content. Without HTTPS - only desktop browser with --disable-web-security works. So nothing.
Cloudflare Tunnel has a streaming media limit baked into ToS - Section 2.8 of the Self-Serve Subscription Agreement forbids using free services for "caching or serving disproportionate amounts of non-HTML content". In practice: above ~50 GB/month of video you get a warning first, then a subdomain ban. Jellyfin with a family watching shows after work = 200 GB/month easily.
DLNA / uPnP assumes local UDP broadcast on port 1900. Doesn't work over VPN, doesn't work over HTTP tunnel - forget DLNA for remote access.
4 ways to access Jellyfin remotely - brutal ranking#
1. Port forwarding 8096#
How it works: open port 8096 (HTTP) or 8920 (HTTPS) on your router, point it at the Jellyfin machine. Set up DynDNS (myflicks.duckdns.org), generate a Let's Encrypt cert via certbot or reverse proxy, and Jellyfin is live on a public address.
Pros: zero external dependencies, full control, lowest latency (1 hop).
Cons:
- No HTTPS by default - port 8096 is plain HTTP, you must add Caddy/Nginx + LE separately.
- You expose the Jellyfin admin panel to the public internet. CVE-2023-49096 (path traversal) and similar appear regularly.
- Doesn't work behind CGNAT (mobile carriers, some fiber). Check your router's IP - if it starts with
100.64.x.xto100.127.x.x, you're behind CGNAT. - Shodan bots find your Jellyfin within 6 hours of opening the port.
Verdict: like HA over port forwarding - insecure and no HTTPS by default.
2. WireGuard VPN#
How it works: stand up WG on your router (UniFi, MikroTik, OpenWRT) or in a separate container. Each household device runs the WG app with a peer config. They connect as if at home, Jellyfin sits on LAN (http://192.168.1.50:8096).
Pros: strong ChaCha20 encryption, zero Jellyfin exposure, access to other home services too.
Cons:
- App on every device. Your partner has to launch WireGuard before watching a Sunday show? Good luck. Kids on a Switch? No WG there.
- Chromecast / smart TVs don't support WG. No native app = no streaming to the big screen at the hotel.
- 20-30% overhead on HD/4K throughput.
- Doesn't work behind CGNAT on the server side - your home router behind CGNAT = external clients can't reach your WG.
Verdict: fine for a solo developer watching alone on a laptop. Poor for families and big screens.
3. Cloudflare Tunnel#
How it works: install cloudflared on the Jellyfin machine, authorize the tunnel, in the CF dashboard map myflicks.yourdomain.com → http://localhost:8096. Automatic HTTPS via Cloudflare CDN.
Pros: free, works behind CGNAT, your own domain, built-in DDoS shield.
Cons docs don't shout about:
- ToS Section 2.8 forbids video streaming > ~50 GB/month on free tier. Cloudflare bans subdomains after detection - sometimes after a month, sometimes a year, lottery.
- Unpredictable throttling. CF eventually starts throttling your video traffic, bitrate drops, the player buffers for no apparent reason.
- 100 MB per HTTP request limit on free plan - some Jellyfin operations (initial library scan with metadata images) can fail.
- WAF sometimes blocks legitimate player requests (HLS chunks, range requests) - debugging becomes "why doesn't the 2009 series stream".
Verdict: free, BUT Cloudflare ToS forbids streaming larger than ~50 GB/month - they ban. Broader comparison.
4. Reverse SSH tunnel (SmartHomeEntry)#
How it works: an agent on the Jellyfin machine opens an outbound SSH tunnel to a relay server. The relay exposes your Jellyfin on a stable HTTPS subdomain, e.g. myflicks.smarthomeentry.com. Zero ports on your end.
Pros:
- No transcoding overhead - the relay only forwards TCP, doesn't decode video. Bitrate intact.
- No ToS issues - no video transfer caps.
- Works with any client app - Jellyfin Web, Jellyfin Mobile, Findroid, Streamyfin, Chromecast, Apple TV, smart TV (browser).
- Stable HTTPS subdomain, automatic LE cert at the relay.
- Works behind CGNAT (outbound tunnel).
Cons:
- Dependency on the relay (managed uptime).
- Paid - from £6/month for the hobby plan.
Verdict: for most Jellyfin users - best ratio of quality, convenience and security.
| Method | Behind CGNAT | HTTPS | ToS limit | Family/TV apps | Setup |
|---|---|---|---|---|---|
| Port forwarding 8096 | no | manual | none | yes | hard |
| WireGuard | no | n/a | none | no | medium |
| Cloudflare Tunnel | yes | auto | ~50 GB/mo | yes | medium |
| Reverse SSH (SHE) | yes | auto | none | yes | 60 sec |
Setup Jellyfin + SSH tunnel in 60 seconds#
I assume you have Jellyfin running locally at http://192.168.1.50:8096 or http://jellyfin.local:8096. If not - start with the HA pillar on self-hosted install (the process is analogous).
-
Sign up for SmartHomeEntry and pick a subdomain (e.g.
myflicks.smarthomeentry.com). On signup we allocate a unique relay port and bind the subdomain to your tunnel record. -
Set Jellyfin's local address in the dashboard ("Local address" field in onboarding). This is the address Jellyfin listens on inside your network - the agent forwards tunnel traffic there. Jellyfin runs on port 8096 by default, so enter
localhost:8096. The field defaults tolocalhost:8080, and the tunnel will not work on that. To check on the Jellyfin host:sudo ss -tlnp | grep 8096 -
Grab the install command from the dashboard and paste it into the Jellyfin host terminal:
curl -sSL https://api.smarthomeentry.com/api/install/YOUR_TOKEN | sudo bashThe script installs the agent as a systemd service, fetches the SSH key via a one-time install token (TTL 15 min), writes the local address to
/etc/smarthomeentry/agent.envand opens the tunnel to the relay. -
Edit
/etc/jellyfin/network.xml- add the subdomain toBaseUrl(empty = root) and the relay IP toKnownProxies, so Jellyfin reads the real client IP from X-Forwarded-For correctly:<NetworkConfiguration> <BaseUrl></BaseUrl> <RequireHttps>false</RequireHttps> <EnableHttps>false</EnableHttps> <KnownProxies> <string>relay.smarthomeentry.com</string> </KnownProxies> <PublishedServerUriBySubnet> <string>external=https://myflicks.smarthomeentry.com</string> </PublishedServerUriBySubnet> </NetworkConfiguration> -
In Jellyfin Dashboard → Networking set:
- Public HTTPS port:
443 - External Domain:
myflicks.smarthomeentry.com - Enable automatic port mapping: OFF (unnecessary, the relay handles it)
- Public HTTPS port:
-
Restart Jellyfin (
systemctl restart jellyfin) and openhttps://myflicks.smarthomeentry.com. You should see the Jellyfin login screen over HTTPS - no certificate warnings, no router config.
Cloudflare Tunnel free tier explicitly forbids video streaming > ~50 GB/month in ToS Section 2.8. Jellyfin with a family blows through that in week one. The subdomain ban arrives without notice - you lose access to all tunnels on the account at once.
Best practices after setup#
The tunnel is up, you can watch from a hotel. Now five minutes of hygiene so you don't come back to this in six months.
- Disable server-side transcoding (Dashboard → Playback → Transcoding) unless you have Hardware Acceleration NVENC (Nvidia), QSV (Intel) or VAAPI (AMD). CPU transcoding 4K → 1080p eats 100% of cores and still won't keep up in real time.
- Set max bitrate per user (Dashboard → Users → pick user → Playback → Internet streaming bitrate). 4 Mbps for parents, 20 Mbps for yourself. Protects against the "kid plays 4K on a 100 GB mobile data plan, burns it in 8 hours" scenario.
- Enable HTTPS-only redirect in Jellyfin (Dashboard → Networking → Require HTTPS for external connections).
- Disable DLNA (Dashboard → DLNA → all OFF). Doesn't work over the tunnel anyway, and it's an attack vector locally (CVEs in SSDP discovery).
- Library backup: metadata DB only, not media files. Back up
/var/lib/jellyfin/data/library.db+metadata/via Borg / Restic. You don't tunnel petabytes of.mkvfor backup - the tunnel is for streaming, not for offsite backup. - Update Jellyfin monthly - security patches for the web UI (XSS in movie descriptions is a classic).
If you have an Intel CPU from 7th gen onward, enable QSV transcoding (Dashboard → Playback → Hardware acceleration → Intel QuickSync). Single-pass HEVC encode at 4K → 1080p uses ~3% CPU instead of 100%. It completely changes the economics of remote streaming from a laptop server.
Set Jellyfin logs (/var/log/jellyfin/) to Information level in production, not Debug. Debug records every HLS chunk and every seek - a few hours of streaming = hundreds of MB of logs per day and unnecessary disk IO.
FAQ#
| Question | Answer |
|---|---|
| Does 4K streaming work over the tunnel? | Yes, but you need home upload > 25 Mbps sustained. Test Speedtest upload at prime time, not at 3 AM. Realistically you need 30-35 Mbps to leave headroom for TCP + SSH overhead. |
| Do Chromecast and TV apps work? | Yes - enter https://myflicks.smarthomeentry.com as the server address in Jellyfin Mobile, cast works via the HTTPS subdomain. Smart TVs (LG, Samsung, Android TV) run Jellyfin Web in the browser. |
| Live TV / DVR over the tunnel? | Yes, but the DVB-T/DVB-C tuner stays physically at home (USB to the Jellyfin machine). The tunnel forwards the tuner stream the same way it forwards recorded files. Recordings also save locally, not in the cloud. |
| What about subtitles / HDR? | The tunnel is transparent - it forwards the stream bit-for-bit. SRT, ASS, VobSub, PGS, HDR10, HDR10+, Dolby Vision (if the player supports it) - unchanged. |
| Plex vs Jellyfin over the tunnel - differences? | Plex Remote has a built-in relay via plex.tv (transcoding on their side, requires an account), works without setup but is bandwidth-throttled on free tier and needs Plex Pass for some features ($120 lifetime). Jellyfin has no built-in remote - you must expose it yourself via tunnel/VPN/port-fwd. Upside: full control, no third-party account, FOSS. |
| Can I tunnel other services from the same machine? | Yes. One agent handles many subdomains - myflicks.smarthomeentry.com → Jellyfin, cloud.smarthomeentry.com → Nextcloud, ha.smarthomeentry.com → Home Assistant. |
Verdict#
A reverse SSH tunnel is the best choice for Jellyfin if you want: streaming without the Cloudflare ToS lottery, operation behind CGNAT, HTTPS for every client app (Chromecast, mobile, TV), full control of your library, and no plex.tv lock-in. Plus your family opens a link in a browser - no VPN apps to install.
Alternative? Plex Remote if you don't want to fiddle and accept a plex.tv account plus their throttling. WireGuard if you only watch alone. Port forwarding only if IT is your day job and you read auth.log every morning. For everyone else - Jellyfin + SmartHomeEntry - a link in a browser, works everywhere, 60-second setup.



