Best VPS for Self-Hosted Media Server (Jellyfin & Plex) in 2026

One-sentence verdict: Hetzner’s CX32 (4 vCPU, 8 GB RAM, €7.59/mo) with a Storage Box add-on is the best value for a personal Jellyfin media server, while Contabo’s Storage VPS suits large libraries on a tight budget — but skip transcoding-heavy setups unless you are paying for dedicated CPU.

Who This Guide Is For

Who Should Not Use a VPS for Media Streaming

Jellyfin vs Plex: Which to Deploy on a VPS

FeatureJellyfinPlex
CostCompletely freeFree tier + Plex Pass ($5/mo or $120 lifetime)
TranscodingSoftware-only on VPS (no GPU)Hardware transcoding requires Plex Pass
Remote accessBuilt-in, no account requiredRequires Plex account, routes through Plex servers
PrivacyFully self-containedPlex phones home, collects metadata
Client appsWeb, Android, iOS (third-party), Roku, Fire TVPolished native apps on all platforms
Resource usageLighter on idleHigher baseline RAM usage
Best for VPSYes — no external dependenciesWorks, but Plex account requirement adds friction

Recommendation for VPS deployment: Jellyfin. It is lighter, fully open-source, requires no external account, and does not route discovery through third-party servers. Plex works fine too, but you are paying for infrastructure while also depending on Plex’s servers for authentication.

Hardware Requirements

Minimum Specs by Use Case

ScenariovCPURAMStorageBandwidthMonthly Cost Range
1 user, direct play only22 GB50 GB+2 TB$5–8/mo
2–3 users, occasional transcode44 GB100 GB+4 TB$8–15/mo
4–5 users, regular transcoding68 GB200 GB+8 TB$15–30/mo
Large library, metadata-heavy48 GB500 GB+Unmetered$20–40/mo

Key Resource Considerations

CPU: Each 1080p transcode stream needs roughly 2,000 PassMark score. A typical 4-vCPU VPS scores 4,000–6,000, handling 1–2 simultaneous transcodes. Direct play (client supports the file format natively) uses almost zero CPU.

RAM: Jellyfin idles at ~200 MB. Each active stream adds 100–300 MB. Metadata scanning for large libraries (5,000+ items) can spike to 2–3 GB temporarily.

Storage: This is the real constraint on a VPS. Options:

Bandwidth: A single 1080p stream uses 5–15 Mbps. A 2-hour movie at 8 Mbps consumes about 7 GB. Budget 500 GB–1 TB per active user per month.

VPS Provider Comparison for Media Servers

ProviderPlanvCPURAMStorageBandwidthPriceBest For
Hetzner CX32Cloud48 GB80 GB NVMe20 TB€7.59/moBest overall value
Hetzner CX32 + BX21Cloud + Storage Box48 GB80 GB + 5 TB20 TB€15.78/moLarge libraries
Contabo Storage VPS MVPS616 GB800 GB SSD32 TB€10.49/moMaximum storage per dollar
Netcup RS 2000 G11Root Server616 GB256 GB SSD80 TB€10.68/moHeavy bandwidth users
HostHatch Storage NVMeVPS48 GB250 GB NVMe5 TB$10/moNVMe speed + storage
Vultr High FrequencyCloud48 GB128 GB NVMe5 TB$48/moLow-latency streaming

Why Hetzner Wins for Most Users

When Contabo Makes Sense

Step-by-Step Deployment: Jellyfin on Docker

Prerequisites

Step 1: Initial Server Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# Install Docker Compose
sudo apt install docker-compose-plugin -y

# Create media directories
sudo mkdir -p /opt/media/{movies,shows,music}
sudo mkdir -p /opt/jellyfin/{config,cache}
sudo chown -R 1000:1000 /opt/media /opt/jellyfin

Step 2: Docker Compose Configuration

Create /opt/jellyfin/docker-compose.yml:

version: "3.8"
services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    ports:
      - "8096:8096"
    volumes:
      - /opt/jellyfin/config:/config
      - /opt/jellyfin/cache:/cache
      - /opt/media:/media:ro
    environment:
      - JELLYFIN_PublishedServerUrl=https://media.yourdomain.com
    deploy:
      resources:
        limits:
          memory: 4G

Step 3: Start and Configure

cd /opt/jellyfin
docker compose up -d

# Check logs
docker compose logs -f jellyfin

Access the setup wizard at http://YOUR_SERVER_IP:8096 and configure:

  1. Create an admin account.
  2. Add media libraries pointing to /media/movies, /media/shows, etc.
  3. Set preferred language and metadata providers.
  4. Configure remote access (enable automatic port mapping if behind NAT).

Step 4: Reverse Proxy with Caddy (HTTPS)

# Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy -y

Create /etc/caddy/Caddyfile:

media.yourdomain.com {
    reverse_proxy localhost:8096
    encode gzip
}
sudo systemctl restart caddy

Step 5: Mount External Storage (Hetzner Storage Box Example)

# Install CIFS utilities
sudo apt install cifs-utils -y

# Create mount point
sudo mkdir -p /mnt/storagebox

# Add to /etc/fstab for persistent mount
echo "//uXXXXXX.your-storagebox.de/backup /mnt/storagebox cifs credentials=/etc/smbcredentials,uid=1000,gid=1000,iocharset=utf8 0 0" | sudo tee -a /etc/fstab

# Create credentials file
echo -e "username=uXXXXXX\npassword=YOUR_PASSWORD" | sudo tee /etc/smbcredentials
sudo chmod 600 /etc/smbcredentials

# Mount
sudo mount -a

Then update your Docker Compose to include /mnt/storagebox:/media/external:ro.

Performance Optimization Tips

1. Avoid Transcoding When Possible

Configure client apps to direct play. Most modern devices handle H.264/AAC natively. Transcoding is the biggest CPU killer.

Set Jellyfin’s transcoding policy to “allow” but educate users to choose “Original” quality in client settings.

2. Use Hardware-Accelerated Tone Mapping

Even without GPU, you can enable VAAPI or QSV if the VPS host exposes it (rare on cloud VPS, common on dedicated servers):

# Add to docker-compose.yml under jellyfin service
devices:
  - /dev/dri:/dev/dri

3. Optimize Metadata Scanning

4. Cache Aggressively

Allocate 2–4 GB for Jellyfin’s transcoding cache. Fast NVMe for the cache directory reduces buffering during partial transcodes.

Storage Cost Comparison

Solution1 TB Cost/mo5 TB Cost/moSpeedBest For
Hetzner Storage Box€3.81€15.12~100 MB/s via SMBLarge libraries, reliable
Contabo local SSDIncluded (800 GB plan)~€15 (upgrade)NVMe speedAll-in-one simplicity
Backblaze B2 + rclone$6$30Variable (cache-dependent)Archival, rarely accessed
Wasabi + rclone$7$35Good with local cacheNo egress fees
Local VPS NVMe (Hetzner)~€4.60 (extra volume)~€23Native NVMeMetadata, cache, hot files

Risk Factors and Honest Warnings

CPU contention on shared VPS: During peak hours, your transcoding performance can drop 30–50% on providers like Contabo or OVH Starter. If you need consistent transcode performance, pay for dedicated-core plans.

Bandwidth overages: A family of 4 streaming nightly can easily hit 3–5 TB/month. Check your provider’s overage policy. Hetzner charges €1.19/TB overage; Vultr charges $0.01/GB (that is $10/TB).

Data durability: VPS storage is not backup. Keep a local copy of irreplaceable media. Cloud VPS disks can fail, and most providers do not guarantee recovery.

Legal considerations: Self-hosting media you own (ripped DVDs, purchased downloads, recorded content) is legal in most jurisdictions. Distributing copyrighted content is not. A media server accessible only to your household is generally fine; sharing with dozens of strangers is legally risky.

Single point of failure: Unlike Plex’s relay fallback, a Jellyfin VPS that goes down means zero streaming until it is back. Consider basic monitoring (UptimeRobot, free tier) and automated Docker restart policies.

Monthly Budget Examples

Budget Setup (~$12/mo)

Power User Setup (~$35/mo)

Final Verdict

For most self-hosters, the Hetzner CX32 + Storage Box combination hits the sweet spot of price, performance, and storage flexibility. Start with Jellyfin in Docker, use Caddy for HTTPS, and only scale up when you actually hit performance limits.

Do not over-provision. A 2-vCPU machine handling direct play for 1–2 users is perfectly adequate. Add CPU and RAM only when transcoding demand proves it necessary.

The entire setup — server, storage, domain, HTTPS — can run for under $15/month and replace multiple streaming subscriptions while giving you complete control over your media library.