top of page

Scaling VOD on a Dime: How to Pair a Budget VPS with S3-Compatible Object Storage for Infinite Media

3 days ago
6 min read

A small VPS can run a video streaming application, but storing a growing collection of movies and videos on that same server can become expensive.

Imagine running Jellyfin on a Linux VPS with only 20GB of local disk space. The operating system and applications already need some of that storage, leaving limited room for video files.


One solution is to keep the streaming application on the VPS and store the media in S3-compatible object storage.


This setup separates video storage from server processing. Your VPS handles Jellyfin and media delivery, while an external storage service holds the actual video library.


In this guide, we'll explain how video on demand VPS object storage works and how to connect S3 storage to a Linux VPS using Rclone.


Why Separate VPS Storage and Media Files?


When you install Jellyfin on a VPS, your media files are often stored on its local disk.


This works well for a small collection. As your library grows, however, the available disk space becomes a limitation.


Upgrading the entire VPS just to obtain more storage may not be the most suitable option.


S3-compatible object storage provides another approach.


You can keep your media files in an external bucket while running Jellyfin on the VPS.


The architecture looks like this:


S3 Object Storage → Rclone Mount → Linux VPS → Jellyfin → Viewers


Rclone makes the remote storage accessible through a directory on your Linux server.

Jellyfin can then read the media files from that directory.

This is useful for personal media libraries, video archives, and small video-on-demand platforms.


What Is S3-Compatible Object Storage?



S3-compatible object storage uses an API based on Amazon S3.

It stores files as objects inside buckets rather than providing a normal local filesystem.


Amazon S3, Wasabi, and self-hosted MinIO deployments are examples of services or software that support S3-style storage operations.


These options differ in pricing, performance, availability and configuration.

For a video library, object storage can hold media separately from the VPS running the streaming application.


The main benefit is independent storage expansion. You can increase media storage without necessarily replacing your VPS.


However, accessing remote files depends on network connectivity and the storage provider's response time.


Step 1: Prepare Your Linux VPS


Start with an Ubuntu 24.04 VPS and administrative access.

Install Rclone and the FUSE filesystem tools:

sudo apt update
sudo apt install -y rclone fuse3

Check the installed Rclone version:

rclone version

Make sure your VPS permits FUSE mounts. Some restricted container hosting environments do not allow them.

You will also need an S3-compatible storage bucket and credentials with the necessary access permissions.


Step 2: Connect Rclone to S3 Storage


Open the Rclone configuration tool:

rclone config

Create a new remote and give it a name such as:

media-s3

Select the S3 storage type.


Choose your storage provider and enter the appropriate region and endpoint when required.


Configure the access credentials securely.


For this tutorial, assume your remote is called media-s3 and the bucket containing your videos is called family-media.

Test the connection:

rclone lsd media-s3:

List the bucket contents:

rclone ls media-s3:family-media

If your files appear, the connection is working.

Avoid sharing S3 access keys or granting unnecessary permissions to the storage credentials.

For a library that Jellyfin only reads, read-only bucket permissions are preferable.


Step 3: Create a Local Mount Directory


Create a directory where the external media library will appear:

sudo mkdir -p /mnt/media

Also create space for Rclone's local cache:

sudo mkdir -p /var/cache/rclone-media

Give your mount service account access to these directories.

For example, if your VPS uses an ubuntu account:

sudo chown ubuntu:ubuntu /mnt/media
sudo chown ubuntu:ubuntu /var/cache/rclone-media

Replace ubuntu with your actual Linux username if it is different.

The local media directory will act as the entry point for Jellyfin.


Step 4: Mount S3 Storage Using Rclone


Run the following command from your configured Linux user account:

rclone mount media-s3:family-media /mnt/media \
  --vfs-cache-mode full \
  --vfs-read-chunk-size 16M \
  --vfs-cache-max-size 4G \
  --cache-dir /var/cache/rclone-media \
  --read-only

This mounts the storage bucket as a local directory.


The --vfs-cache-mode full option lets Rclone cache file reads and writes locally. In this read-only example, it is used for media reading and seeking.


The --vfs-read-chunk-size 16M option controls the initial size of chunks requested from remote storage.


The --vfs-cache-max-size 4G option provides a cache-management target. It isn't a strict hard limit, because open files and cleanup timing can temporarily increase usage.


These settings are examples, not universally optimal values. Monitor local disk usage and adjust the cache to match your server.


Rclone's VFS cache needs actual local disk space. On a 20GB VPS, leave enough room for Ubuntu, application data, logs and other services.


<Cite ref="turn819086search0"/>


Keep the command running during your initial test.

Open another SSH session and verify that the media files are visible:

ls /mnt/media

If the mount is working, you should see the folders stored in your S3 bucket.


Step 5: Connect the Mounted Storage to Jellyfin


Open the Jellyfin administrator dashboard.


Navigate to the Libraries section and create a new library.


Choose a suitable content type such as Movies or Shows.


Select the mounted media directory:


/mnt/media


If Jellyfin is running directly on Linux, its service account must have permission to read that directory.


For Docker-based installations, bind-mount the host directory into the Jellyfin container as a read-only media volume and use the matching path inside Jellyfin.



For example, map the host's /mnt/media directory to /media inside the container.


Make sure the Rclone mount is active before starting the Jellyfin container.


Once the library is configured, Jellyfin can scan the remote media and display it in the application.


Large scans may take longer because metadata and media files are being retrieved over the network.


Step 6: Configure Automatic Mounting with systemd


Manually starting Rclone after every reboot isn't convenient.


You can create a systemd service to mount the storage automatically.


First, stop the temporary Rclone mount from Step 4.


Create a service file:

sudo nano /etc/systemd/system/rclone-media.service

Add:

[Unit]
Description=Rclone S3 Media Mount
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
ExecStart=/usr/bin/rclone mount media-s3:family-media /mnt/media --config /home/ubuntu/.config/rclone/rclone.conf --vfs-cache-mode full --vfs-read-chunk-size 16M --vfs-cache-max-size 4G --cache-dir /var/cache/rclone-media --read-only --allow-other
ExecStop=/usr/bin/fusermount3 -uz /mnt/media
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Replace ubuntu and the Rclone configuration path with your actual service username and file location.


The service assumes that your system has Rclone at /usr/bin/rclone and fusermount3 at /usr/bin/fusermount3. Verify these paths on your VPS before starting it.


The --allow-other option lets other local users, including the Jellyfin service, access the mount. Your FUSE configuration must permit this option; when required, enable user_allow_other in /etc/fuse.conf.

Enable the service:

sudo systemctl daemon-reload
sudo systemctl enable --now rclone-media

Check its status:

sudo systemctl status rclone-media

Verify the mount:

findmnt /mnt/media

The service should now attempt to restore the S3 mount after a reboot.

For production, configure Jellyfin to wait until the media mount is available. Otherwise, a temporary network or storage failure may cause Jellyfin to scan an empty directory.


How Rclone Caching Helps Video Playback


Video streaming applications frequently read different parts of media files.

For example, a viewer may skip ahead while watching a movie.

Rclone's VFS cache can help manage these reads by retaining retrieved data on local disk.


This may reduce repeated requests for recently accessed media and support file seeking.


However, caching does not remove the need for network bandwidth.

The VPS still needs to retrieve uncached video data from object storage and deliver the content to viewers.


Object storage request charges, data transfer fees, and cache performance should all be considered when designing the system.


What Are the Limitations?


Separating storage and computing provides flexibility, but it introduces dependencies.

If the object storage provider becomes unavailable, Jellyfin may be unable to read uncached media.


Network latency can affect how quickly videos start.

Local cache files still consume VPS disk space.

Some storage providers also charge for requests or data transferred out of their infrastructure.


Before selecting a service, compare actual storage requirements, expected traffic, access charges, and provider conditions.

For additional information about VPS-based streaming infrastructure, read the media streaming server architecture on budget VPS.


Frequently Asked Questions


Can Jellyfin stream videos stored on S3?


Yes. Jellyfin can read media through a compatible Rclone filesystem mount, provided the mount and file permissions are configured correctly.


Does an S3 mount require a large VPS disk?


Not necessarily. The media remains in remote storage, but Rclone caching and application files still need local disk capacity.


Is Rclone caching necessary?


It depends on the application. Full VFS caching can improve compatibility with media applications that seek within files, but it uses local storage.


Can a 20GB VPS host a large media library?


It can run the streaming application while accessing a much larger remote media collection. However, performance depends on cache capacity, storage access, network bandwidth, and server resources.


Is S3 storage unlimited?


No. Object storage can be expanded independently from the VPS, but service limits, billing, and provider policies still apply.


Conclusion


Pairing a budget VPS with S3-compatible object storage is a practical way to grow a media library without keeping every video on the VPS's local disk.

Rclone connects the remote storage to Linux, while Jellyfin provides the media interface and playback features.


Start with a small collection, test playback and seeking, and monitor the VFS cache before expanding the library. This helps you understand the real storage and network requirements of your setup.

 
 
 

Comments


bottom of page