· Emmanuel ADEKPLOVI · Tutorials · 18 min read
WordPress Media to S3: A Practical Guide

WordPress has traditionally followed a simple architecture: the application, its themes and plugins, the database, and uploaded files all live within the same hosting environment.
For a small website, this is usually more than enough.
You install WordPress on a server, upload an image, and WordPress stores that image inside the wp-content/uploads directory. The same happens with PDFs, videos, audio files, downloadable resources, and other media.
This simplicity is one of WordPress’s strengths.
But as a website grows, this architecture can become less convenient.
A website selling online courses may have thousands of videos and PDFs. A membership website may need to serve private documents to authenticated users. An enterprise may need to store large amounts of business documents. An e-commerce website may accumulate years of product images and downloadable files.
At that point, it becomes worth asking a different question:
Does the WordPress server really need to store all of these files?
The answer is often no.
This is where object storage comes into the picture.
Services such as Amazon S3 and other S3-compatible storage providers allow you to separate file storage from your WordPress application. Instead of keeping every file on the same server as WordPress, the application can store those files in an object-storage bucket and retrieve them when needed.
This architecture is widely used outside WordPress, particularly by SaaS platforms, startups, enterprises, and applications that handle significant amounts of user-generated content.
In this article, we will look at why you might want to use object storage with WordPress, how S3 works, the benefits and disadvantages, how private files can be handled, and what alternatives are available.
1. How WordPress traditionally stores media
When you upload a file through the WordPress Media Library, WordPress normally stores the physical file on the same filesystem where WordPress is installed.
For example:
wp-content/
└── uploads/
└── 2026/
└── 09/
├── image.jpg
├── document.pdf
└── audio.mp3
The database contains information about the media, while the actual file exists on the server.
This distinction is important.
WordPress does not normally store the entire image or PDF inside the database. Instead, the database stores metadata and references to the file, while the file itself lives in the filesystem.
This architecture works well because it is simple.
Your application server has everything it needs:
WordPress Server
┌─────────────────┐
│ WordPress │
│ Plugins │
│ Themes │
│ Database │
│ │
│ /uploads │
│ ├── images │
│ ├── documents │
│ └── videos │
└─────────────────┘
For a small blog, portfolio, company website, or simple store, there may be little reason to change this.
The problem starts when the amount of stored data becomes significant.
2. Where local storage starts becoming a problem
The first problem is usually disk space.
Imagine a WordPress website with:
- 100 GB of images
- 50 GB of PDFs
- 200 GB of videos
- 20 GB of audio
- 30 GB of backups
The application server may now need hundreds of gigabytes of storage.
Increasing the disk size can solve the immediate problem, but it also means that your application server is becoming your storage server.
That creates a tighter relationship between two things that do not necessarily need to live together:
application compute and file storage.
There are other problems too.
Backups become larger
If your WordPress server contains hundreds of gigabytes of media, backing up the entire server can become expensive and slow.
You may also end up transferring the same large files repeatedly during backup operations.
Server migrations become harder
Moving a WordPress installation from one server to another is relatively straightforward when the site contains a few gigabytes of data.
It becomes a different problem when you have hundreds of gigabytes of uploads.
You need to transfer all those files before the new server can become fully operational.
Scaling becomes more complicated
Suppose you eventually want to run WordPress behind multiple application servers:
Load Balancer
│
┌─────────┴─────────┐
│ │
WordPress #1 WordPress #2
│ │
└─────────┬─────────┘
│
Shared Files
Now both servers need access to the same media.
A local filesystem is no longer enough.
You need shared storage, synchronization, or another architecture.
This is one of the situations where object storage becomes particularly attractive.
3. What is object storage?
Object storage is a way of storing data as objects rather than treating everything as files inside a traditional filesystem.
The most famous example is Amazon S3.
Instead of thinking:
/server/uploads/2026/09/image.jpg
you can think in terms of:
bucket: my-wordpress-media
object: 2026/09/image.jpg
The object itself contains the data, while the storage system maintains information such as:
- the object’s name
- metadata
- size
- content type
- creation information
- access configuration
The storage is accessed through APIs, usually over HTTP.
A simplified architecture looks like this:
WordPress
│
│ API
▼
Object Storage
┌─────────────────┐
│ Bucket │
│ │
│ images/ │
│ documents/ │
│ audio/ │
│ videos/ │
└─────────────────┘
The WordPress server no longer needs to physically store every uploaded file.
4. What is an S3 bucket?
An S3 bucket is essentially a logical container for objects.
For example:
my-company-media
could contain:
my-company-media/
├── images/
│ ├── logo.png
│ ├── products/
│ └── blog/
│
├── documents/
│ ├── invoices/
│ └── manuals/
│
├── audio/
│
└── videos/
One important detail is that S3 does not behave exactly like a traditional filesystem.
The paths you see are generally object keys rather than real directories.
For example:
images/products/product-123.jpg
is an object key.
This distinction becomes useful when designing applications because object storage is optimized for storing and retrieving objects at scale rather than behaving like a conventional server disk.
5. Why use S3 with WordPress?
The most obvious advantage is that your WordPress server no longer needs to carry the entire media library.
Instead:
Users
│
▼
WordPress
│
┌──────┴──────┐
│ │
Database Object Storage
│
├── Images
├── PDFs
├── Audio
└── Videos
This separation gives you more flexibility.
Your WordPress server can focus on running:
- PHP
- WordPress
- plugins
- themes
- APIs
- business logic
while object storage focuses on:
- storing files
- retrieving files
- durability
- access control
- lifecycle management
This is a much cleaner separation of responsibilities.
6. The biggest advantage: separating storage from compute
One of the most useful concepts here is separation of compute and storage.
Your WordPress server is compute.
Your object-storage bucket is storage.
They can scale independently.
Suppose your website suddenly receives more traffic.
You might need a larger application server:
2 CPU → 4 CPU → 8 CPU
But your media storage does not necessarily need to change.
Conversely, your media library might grow from:
20 GB → 200 GB → 2 TB
without requiring you to redesign your WordPress application server.
This separation is one of the reasons object storage has become so common in modern application architectures.
7. Reducing pressure on the WordPress server
Media can consume significant disk space and bandwidth.
Consider a website selling online courses.
A single course could contain:
- 30 videos
- 50 PDF documents
- 100 images
- audio files
- downloadable resources
If all of these files are served directly by the WordPress server, the server has to handle both the application workload and the file delivery workload.
With object storage, the architecture can instead look like:
User
│
▼
WordPress
│
Authentication
Business Logic
│
▼
Object Storage
│
▼
File
Even better, a CDN can often sit in front of the object storage:
User
│
▼
CDN
│
▼
Object Storage
│
▼
File
This can significantly reduce the amount of work performed by the WordPress server.
8. Private files are where things become particularly interesting
Public images are relatively simple.
For example:
https://example.com/uploads/logo.png
There is usually no reason to protect a public logo.
But imagine a platform selling paid courses.
You might have:
courses/
└── private/
├── lesson-01.pdf
├── lesson-02.pdf
└── bonus.zip
You probably don’t want someone to discover the URL and share it publicly.
This is where object storage can become more powerful.
Instead of making the bucket publicly accessible, you can keep it private and allow the application to authorize access.
A simplified flow could be:
User
│
│ Requests lesson
▼
WordPress
│
│ Check:
│ "Does this user own the course?"
▼
Access granted
│
│ Generate temporary URL
▼
Object Storage
│
▼
File
The user receives a URL that is valid only for a limited period.
This concept is commonly implemented using signed URLs or presigned URLs.
For example, instead of giving the user permanent access to:
/files/course.pdf
your application can generate a temporary URL that expires after a defined period.
This is particularly useful for:
- paid courses
- membership platforms
- private documents
- invoices
- reports
- customer downloads
- enterprise documents
- premium content
9. Do not confuse WordPress permissions with storage permissions
This is an important security consideration.
WordPress might know:
User A purchased Course B.
But object storage does not automatically understand your WordPress business logic.
You therefore need to design the access flow carefully.
A common mistake is to make the entire bucket public because it makes integration easier.
That may be acceptable for public website images, but it is a poor approach for sensitive or paid content.
For private content, a better architecture is:
User
│
▼
WordPress
│
Authentication
│
Authorization
│
▼
Temporary access
│
▼
Private bucket
The storage credentials should also never be exposed to the browser.
Your secret access keys belong on the server side.
10. S3 is not only Amazon S3
When developers hear “S3”, they often immediately think about Amazon Web Services.
But S3 has become much more than a single product.
The S3 API has become a widely adopted interface for object storage.
Many providers offer S3-compatible storage.
This means that software designed to communicate with S3 can often work with another provider by changing configuration such as:
- endpoint
- access key
- secret key
- bucket
- region
This has created a large ecosystem of object-storage providers.
Depending on your requirements, you might consider:
- Amazon S3
- Cloudflare R2
- Backblaze B2
- Wasabi
- DigitalOcean Spaces
- other S3-compatible providers
- self-hosted solutions such as MinIO
The important point is that you are not necessarily locked into Amazon simply because you choose the S3 API.
11. The downside: object storage adds complexity
Object storage is not automatically better.
You are trading simplicity for flexibility.
A traditional WordPress installation is straightforward:
WordPress → Local Filesystem
An object-storage architecture introduces another service:
WordPress → Object Storage
And potentially:
WordPress → CDN → Object Storage
There are now more components to configure and monitor.
You have to think about:
- credentials
- permissions
- bucket policies
- URLs
- CORS
- caching
- CDN configuration
- backups
- migrations
- lifecycle policies
- access control
- plugin compatibility
For a small WordPress blog with 500 MB of images, this might be unnecessary complexity.
For a platform storing hundreds of gigabytes of customer files, it can be a very reasonable trade-off.
12. Performance is not automatically better
Another common misconception is:
“S3 is faster than my server.”
Not necessarily.
Object storage introduces network communication.
If WordPress needs a file from object storage, the request has to travel over the network.
A local filesystem can be extremely fast because the application is accessing storage directly.
The advantage of object storage is therefore not simply raw disk performance.
The real benefits are more about:
- scalability
- durability
- separation
- accessibility
- operational flexibility
- integration with CDNs
- storage capacity
- lifecycle management
When combined with a CDN, object storage can become very effective for delivering frequently accessed public content.
13. Object storage and CDN: a powerful combination
For public media, one of the most useful architectures is:
User
│
▼
CDN
│
┌───────┴───────┐
│ │
Cache Hit Cache Miss
│ │
▼ ▼
File Object Storage
The first user may cause the CDN to retrieve the file from object storage.
Subsequent users can potentially receive the cached version directly from the CDN.
This means your WordPress server may never see those media requests.
For websites with large amounts of traffic, this architecture can dramatically change the role of the WordPress server.
WordPress becomes primarily the application layer rather than the media-delivery layer.
14. What about WordPress image optimization?
Moving images to object storage does not eliminate WordPress’s image-processing requirements.
WordPress may still generate multiple image sizes:
image.jpg
image-150x150.jpg
image-300x200.jpg
image-768x512.jpg
image-1536x1024.jpg
Depending on the plugin and architecture you choose, those files can also be stored in object storage.
You therefore need to ensure that your media-storage integration works correctly with:
- image resizing
- thumbnails
- WebP
- AVIF
- responsive images
- media metadata
- image regeneration
The storage layer should remain transparent to WordPress as much as possible.
15. What about backups?
Object storage should not automatically be treated as your only backup.
This is an important distinction.
Having your WordPress media stored in S3 does not mean you have a complete disaster-recovery strategy.
You still need to consider:
WordPress Database
+
WordPress Code
+
Media
+
Configuration
Your database contains important information such as:
- posts
- users
- orders
- WooCommerce data
- media metadata
- plugin configuration
Object storage contains the physical files.
You therefore need a backup strategy covering both sides.
Depending on your requirements, you might also use:
- object versioning
- lifecycle policies
- replication
- separate backup buckets
- off-site backups
- database backups
The architecture should be designed around the recovery scenario you actually care about.
16. Object storage can also help with server migrations
One of the less obvious advantages is portability.
Suppose your WordPress application currently runs on Server A.
Later, you move to Server B.
If all of your media is stored locally, you may need to move:
Server A
│
├── WordPress
├── Database
└── 500 GB media
│
▼
Server B
With object storage:
Object Storage
▲
│
┌─────────┴─────────┐
│ │
Server A Server B
WordPress WordPress
You can move the application without necessarily moving the entire media library.
This can make migrations considerably easier.
17. It can also make horizontal scaling easier
Suppose you eventually want to run several WordPress application instances.
Instead of:
WordPress #1 → Local Media
WordPress #2 → Local Media
WordPress #3 → Local Media
you can have:
Load Balancer
│
┌────────────┼────────────┐
▼ ▼ ▼
WordPress #1 WordPress #2 WordPress #3
│ │ │
└────────────┼────────────┘
▼
Object Storage
All application instances can access the same storage backend.
This removes one of the common challenges of scaling applications that rely heavily on local files.
18. What WordPress plugins can be used?
You do not necessarily need to build your own S3 integration.
There are WordPress plugins that can redirect media storage to object-storage providers.
Depending on the provider and requirements, these plugins can handle things such as:
- uploading media to S3-compatible storage
- rewriting media URLs
- synchronizing existing media
- integrating with CDNs
- serving media from another domain
- managing private files
However, plugin quality and compatibility vary.
Before choosing one, check whether it supports the exact workflow you need.
For example:
Public media
WordPress → S3 → CDN → Visitor
is relatively straightforward.
Private paid content
WordPress
↓
Check user permissions
↓
Generate temporary access
↓
Private S3 object
requires more careful validation.
If your business depends heavily on protected downloads, do not select a plugin solely because it can upload images to S3.
Verify how it handles authorization and private objects.
19. Should everything go into S3?
No.
This is an important architectural decision.
Not every file needs to be moved to object storage.
For example, you may decide to keep:
WordPress
├── Core
├── Plugins
├── Themes
└── Temporary files
on the application server while storing:
Object Storage
├── Images
├── Videos
├── Documents
└── Downloads
remotely.
The right architecture depends on your workload.
You should ask:
What type of data am I storing?
How large is it?
How frequently is it accessed?
Does it need to be public or private?
How important is it?
Does it need a CDN?
How often does it change?
These questions are more important than simply asking whether S3 is “better”.
20. When should you consider object storage?
Object storage starts becoming particularly attractive when your website has one or more of the following characteristics:
You have a large media library
If your WordPress server is filling up primarily because of uploads, separating media storage can make sense.
You sell digital products
Courses, ebooks, templates, software, reports, and other downloadable products can generate significant amounts of storage.
You have private customer files
If customers upload or access invoices, documents, reports, contracts, or other files, object storage can provide a useful foundation for controlled access.
You expect significant growth
If you know that your media library will grow from tens of gigabytes to hundreds of gigabytes or more, planning the architecture early can prevent painful migrations later.
You want to scale WordPress
If you want multiple application servers, shared object storage can simplify the architecture.
You want to separate backups and application infrastructure
Keeping your files outside the application server can make disaster recovery and migrations easier to manage.
21. When should you keep local storage?
For many websites, local storage is still the right answer.
For example:
Company website
100 pages
500 images
2 GB total media
There may be little reason to introduce S3.
If your hosting provider already gives you:
- sufficient storage
- reliable backups
- good bandwidth
- good performance
then local storage may be simpler and cheaper.
Remember:
simplicity is also an architectural advantage.
Adding another external service introduces another dependency.
Don’t introduce object storage simply because modern architectures use it.
Introduce it because it solves a problem you actually have.
22. What about the cost?
Cost is another reason to evaluate your options carefully.
Object-storage pricing can involve several components:
- storage
- requests
- data transfer
- retrieval
- replication
- CDN
- minimum storage durations
The cheapest provider based on storage price is not necessarily the cheapest provider for your workload.
For example, imagine a website storing 500 GB but serving several terabytes of downloads every month.
Storage might be inexpensive while data transfer becomes the dominant cost.
Conversely, a website may store a large amount of data but rarely access it.
In that case, storage pricing and lifecycle policies may matter more.
You should therefore calculate the complete workload rather than comparing only:
”$/GB/month”
23. S3-compatible alternatives
Amazon S3 is the most recognized option, but it is not the only one.
Depending on your requirements, you might evaluate different providers.
Amazon S3
A mature and highly integrated object-storage service.
It offers a very broad ecosystem and many advanced capabilities, but the pricing model can become complex.
Cloudflare R2
An S3-compatible object-storage service that is particularly interesting when paired with Cloudflare’s ecosystem.
It can be attractive for applications where data-transfer economics are important.
Backblaze B2
Another popular object-storage option, often considered for its relatively straightforward storage economics.
Wasabi
Focused heavily on object storage and commonly considered for workloads where predictable storage pricing is important.
DigitalOcean Spaces
A relatively simple option for teams already using DigitalOcean.
MinIO
MinIO takes a different approach.
Instead of using a managed cloud service, you can run an S3-compatible object-storage system yourself.
For example:
Your infrastructure
│
▼
MinIO
│
├── Bucket A
├── Bucket B
└── Bucket C
This gives you much more control, but you also become responsible for:
- disks
- replication
- availability
- upgrades
- monitoring
- security
- backups
- disaster recovery
Self-hosting object storage can therefore be powerful, but it is not automatically simpler or cheaper.
24. A practical WordPress architecture
For a modern WordPress website, a possible architecture could look like this:
Internet
│
▼
Cloudflare/CDN
│
┌─────────────┴─────────────┐
│ │
▼ ▼
WordPress Media
Application Requests
│ │
▼ ▼
PostgreSQL/MySQL Object Storage
│
▼
Files
The exact implementation will depend on your infrastructure.
For a simple website, you might have:
WordPress → Object Storage
For a larger platform:
User
│
▼
CDN
│
├──────────────► WordPress
│ │
│ ▼
│ Database
│
└──────────────► Object Storage
And for private files:
User
│
▼
WordPress
│
├── Authenticate user
├── Check authorization
└── Generate temporary access
│
▼
Private Object
Storage
This separation gives you a much clearer architecture.
25. Security considerations
Moving files to object storage does not automatically make them secure.
You still need to configure the system properly.
At minimum, consider:
Keep private buckets private
Do not make an entire bucket public just because some files need to be accessible.
Protect access credentials
Never expose your secret access key in frontend JavaScript.
Use least privilege
The credentials used by WordPress should have only the permissions they actually require.
Separate public and private content
You might use:
public-media/
private-files/
with different access policies.
Use HTTPS
File transfers should be encrypted in transit.
Consider signed URLs
For private resources, temporary URLs can prevent permanent public access.
Monitor access
Depending on the provider, access logs and audit capabilities can help you understand how files are being accessed.
26. A common mistake: treating S3 as another hard drive
One of the easiest mistakes is to think:
“I’m just replacing
/uploadswith another disk.”
That is not quite the right mental model.
Object storage is an API-based storage system with different characteristics from a local filesystem.
You should design around:
Store object
Retrieve object
Delete object
Authorize access
Cache object
Expire object
rather than assuming every filesystem operation will behave identically.
This becomes especially important for applications that frequently modify files.
27. The bigger architectural idea
The real lesson is not:
“Everyone should move WordPress to S3.”
The more important lesson is:
Your application and your data do not always need to live on the same server.
WordPress is an application.
The database is a data store.
Object storage is a file-storage system.
A CDN is a delivery layer.
Each component can have a specific responsibility.
A more mature architecture might therefore look like:
┌──────────────┐
│ Users │
└──────┬───────┘
│
▼
┌──────────────┐
│ CDN / Proxy │
└──────┬───────┘
│
┌─────────┴─────────┐
│ │
▼ ▼
┌─────────────┐ ┌───────────────┐
│ WordPress │ │ Object Storage│
│ Application │ │ Media │
└──────┬──────┘ └───────────────┘
│
▼
┌─────────────┐
│ Database │
└─────────────┘
This architecture is much easier to reason about because every component has a clear role.
28. Final thoughts
WordPress’s traditional filesystem-based media storage is not bad architecture.
In fact, it is one of the reasons WordPress is so easy to install and operate.
But as your website becomes more demanding, the limitations of keeping everything on one server become more apparent.
Object storage gives you another option.
You can move large media libraries away from your application server, simplify migrations, support multiple application instances, integrate with CDNs, manage private files, and build a storage layer that can grow independently from your WordPress installation.
S3 is only one implementation of this idea. S3-compatible services give you even more choices, while self-hosted solutions such as MinIO can provide greater control when you are willing to operate the infrastructure yourself.
The important thing is not to adopt object storage because it is fashionable.
Instead, look at your business requirements.
If your website is primarily a small blog with a few images, local storage may be the best solution.
If you are building a platform that sells courses, distributes digital products, stores customer documents, manages large media libraries, or expects substantial growth, object storage can become a very valuable part of the architecture.
Ultimately, the goal is simple:
Keep your application focused on running the application, and let your storage infrastructure focus on storing and delivering your files.




