Use a Storage Server with WordPress: what works and what does not
Not everything you read about WordPress and external storage actually works. This article separates the three cases: backups work right away, downloads with little effort, and the media library only under one condition.
The directory wp-content/uploads is the part of WordPress that grows without a brake. Images, PDF files, videos, plus several sizes of every image that WordPress generates automatically. After a few years there are dozens of gigabytes sitting there, and space on the web server is the most expensive space you can buy.
A Storage Server costs a fraction of that. The only question is what can really be moved off. There is a lot written about this online that does not work in practice. This article separates the three cases cleanly.
The three cases at a glance
| What | Does it work? | Effort |
|---|---|---|
| Backups | yes, right away | a quarter of an hour, free plugin |
| Large downloads | yes | a small script or a download plugin |
| Media library, your own server | yes | mount it once, then invisible |
| Media library, shared hosting | no | the matching plugin does not exist |
The last point is the one most people trip over. So the inconvenient truth first.
Why there is no plugin for the media library
The well-known offloading plugins for WordPress all speak the same language: S3. They connect to Amazon S3 or a compatible service, upload the file there, delete the local copy and replace the address in the post with a public address of that service.
Exactly that cannot be transferred to a Storage Server, for two reasons:
- The storage speaks SMB, SFTP and WebDAV, but no S3.
- There is no public address per file. Every access is authenticated, so there can be no link that the visitor's browser calls up directly.
There are individual plugins that work with FTP, but none with noteworthy adoption and current maintenance that moves the media library off completely over SFTP or WebDAV. If you find one, look at the date of its last update and the number of active installations before putting it to work.
The way that works: mount instead of offload
On your own server with root rights you turn the whole thing around. Instead of teaching WordPress to talk to foreign storage, you bring the storage to the place WordPress writes to anyway:
apt install -y cifs-utils
mkdir -p /mnt/storage
printf 'username=u123456-sub1\npassword=YOUR_PASSWORD\n' > /etc/samba/storage.cred
chmod 600 /etc/samba/storage.cred
Entry in /etc/fstab:
//u123456.storage.kernelhost.net/backup /mnt/storage cifs credentials=/etc/samba/storage.cred,uid=www-data,gid=www-data,file_mode=0660,dir_mode=0770,seal,_netdev,nofail 0 0
Then move the existing files over and replace the directory:
mount -a
mkdir -p /mnt/storage/uploads
rsync -a /var/www/example.com/wp-content/uploads/ /mnt/storage/uploads/
mv /var/www/example.com/wp-content/uploads /var/www/example.com/wp-content/uploads.alt
ln -s /mnt/storage/uploads /var/www/example.com/wp-content/uploads
WordPress notices nothing of this, for the application it is a perfectly normal path. The old directory stays behind as uploads.alt until you have checked that everything works. Only delete it then, not before.
The trap along the way: thumbnails
WordPress generates several sizes of every image and loads them on every page view. If those small files live on network storage, the network latency is added per file, and a gallery with forty images waits forty times.
Two solutions, both good:
- Put a cache in front, for example a cache in the web server that keeps the delivered files locally.
- Put only the originals on the storage and leave the generated sizes local. That is a bit more work, but it is the cleanest way for sites with many images.
Backups: the fastest benefit
If you only do one thing, do this one. A backup on the same server is not a backup: if the disk is wiped or the website is encrypted, the backup is gone with it. On separate storage it survives.
The free plugin WPvivid can back up to the storage over SFTP in its basic version, with a schedule and a retention rule. The complete guide for that is in WordPress backups to the Storage Server.
On your own server it gets even better, namely with rsync or BorgBackup straight out of a scheduled job. Then you transfer only the changes, and BorgBackup deduplicates on top of that.
Delivering large downloads
For files that visitors are meant to download, the storage is ideal: they are read rarely, they are large, and they do not have to be fast, they just have to arrive. Access runs through a small script that checks the permission first:
<?php
// in functions.php or as a plugin of its own
add_action('template_redirect', function () {
if (!isset($_GET['kh_download'])) {
return;
}
if (!is_user_logged_in()) {
wp_die('Please sign in', '', ['response' => 403]);
}
$pfad = '/mnt/storage/downloads/' . basename($_GET['kh_download']);
if (!is_readable($pfad)) {
wp_die('File not found', '', ['response' => 404]);
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($pfad) . '"');
header('Content-Length: ' . filesize($pfad));
readfile($pfad);
exit;
});
The example assumes mounted storage. Without mounting, you replace readfile() with an SFTP or WebDAV request as described in Use a Storage Server for your website.
The side effect is a pleasant one: because the file never has a public address, nobody can pass the link around. The permission check cannot be bypassed.
What is left on shared hosting
| Goal | Shared hosting | Your own server |
|---|---|---|
| Backup through a plugin | yes | yes |
| Delivering downloads through PHP | yes, over WebDAV or SFTP | yes |
| Moving the media library off | no | yes, by mounting |
| rsync or BorgBackup | mostly no | yes |
On shared hosting, WebDAV over HTTPS is the most reliable route, because port 443 is practically never blocked. SFTP works as well, but runs on port 23 with us, and not every provider allows outgoing connections on ports like that. It is worth a quick check before you order.
One sub-account per purpose
Every Storage Server allows up to 100 sub-accounts, each with its own home directory, its own password and its own protocol permissions. For WordPress that means at least two:
- One account for the website, which only sees
/uploads. - One account for the backups, which only sees
/backup.
If the website is ever taken over, the attacker finds the credentials of the first account in wp-config.php. The backups stay untouched, because that account does not even know about them. With a single main account, everything would be gone at that point.
When several users need space of their own
A Storage Server has no quota per sub-account. An account stays inside its directory, but can fill the entire plan from there. If you want to give customers, photographers or editors a limited allowance each, put an application in front that takes care of it. Nextcloud is the obvious choice, because it comes with users, quotas and share links: Connect Nextcloud to the Storage Server.
Which plan fits
| Plan | Space | Sub-accounts | Price |
|---|---|---|---|
| Storage-1 | 1 TB | 100 | 9.99 EUR |
| Storage-2 | 5 TB | 100 | 29.99 EUR |
| Storage-3 | 10 TB | 100 | 39.99 EUR |
| Storage-4 | 20 TB | 100 | 69.99 EUR |
For a single WordPress site with backups, Storage-1 is usually enough for a long time. If you move the media libraries of several sites off or work with video, you quickly end up at Storage-2 or Storage-3. All plans are located in Germany, come without a setup fee, are billed PrePaid and have no minimum term. Switching to the next larger plan is possible at any time, without touching the data.
Frequently asked questions
Can I move the WordPress media library to a Storage Server with a plugin?
So how does it work after all?
What is the easiest benefit?
Will my images load more slowly because of this?
Can I link downloads directly from the storage?
Which protocol do I use on shared hosting?
Do I need a separate sub-account for every purpose?
What about several users who each need their own space?
Is it worth it for a small website?
What does it cost?
2026 KernelHost GmbH. All rights reserved. This guide is protected by copyright. Republishing it on other websites, in whole, in part or in edited form, is not permitted without our written consent. Quoting with a source credit and a link is expressly welcome.

