Vyso Guides
How to Offload WordPress Media to Cloud Storage
To offload WordPress media, use a compatible plugin to copy attachment files to object storage and configure the website to deliver them through the intended remote URLs. Keep local copies during the trial. Migrate existing attachments, generated image sizes, and their storage mappings before considering local removal, and prove that you can restore them first.
Offloading changes the storage and delivery architecture. It does not automatically compress images, create an independent backup, or turn a storage bucket into a digital asset management system.
Separate the jobs before choosing a service
With local media, WordPress keeps attachment records in the database and files on the web server or a shared filesystem. An offload integration copies or manages those files in remote storage and maintains the information needed to deliver them. Whether local copies remain is a separate decision.
A CDN sits in the delivery path, caching responses obtained from an origin such as the web server, an object bucket, or another service. A backup has a different responsibility: it must remain independently recoverable after deletion, corruption, or loss, under its retention policy.
A DAM manages reusable assets and the context needed to organize, discover, and work with them, together with its supported delivery workflows. An external media URL alone does not tell you whether the service behind it provides storage, caching, or asset management.
A CDN can cache local uploads without moving their storage origin. An offload plugin can deliver directly from a bucket without providing the CDN configuration you need. A bucket containing the only remaining copy is production storage, not an independent backup.
For cache and delivery-service selection, use the WordPress image CDN guide. Keep that question separate from deciding which system owns the attachment files.
Decide whether offloading solves the actual problem
Offloading can be appropriate when local disk space is constrained, media growth is difficult to accommodate, or several application servers need access to a common media origin. A small site with ample storage and a reliable backup may gain little from another integration to operate.
Remote storage is not automatically cheaper or faster. Include storage, request charges, download traffic, CDN service, plugin licensing, backup retention, and administration. A migration can temporarily require both local and remote copies. Generated sizes and retained object versions can make storage substantially different from the number of attachment rows.
For a multi-server installation, remote objects solve only part of the problem. The database, upload processing, temporary working files, background jobs, and any plugin that expects local filesystem access still need a coherent architecture. Do not infer a fully stateless WordPress deployment from an offload setting.
For several WordPress sites or a Multisite network, verify the plugin's network support and licensing, the bucket or prefix assigned to each site, and the effect of deleting one site's attachments. Shared object storage does not automatically provide a shared media catalog or safe cross-site reuse.
Understand the attachment-to-object workflow
In a common plugin-based flow, an editor uploads through WordPress, which creates the attachment record and generates the image sizes required by its configuration and active components. The offload integration then copies the source and supported derivatives to the configured bucket. Other implementations can use different upload or processing paths.
The integration records the provider, bucket, object path, and offloaded files alongside normal attachment metadata. Its delivery layer supplies remote URLs, either from storage directly or through a CDN or custom domain. Only a separately enabled, supported operation should remove local copies, preserving the remote sources and the mapping needed to find them.
An object key is the file's identity within its bucket. The public delivery URL may add a hostname, a path prefix, or another layer of routing. Keeping the object does not preserve a website reference if the generated URL points at the wrong key or domain.
WordPress's attachment metadata documentation shows why the source and generated sizes belong to the migration plan. Copying the uploads directory without establishing the plugin's mapping is not necessarily a completed offload migration.
Compare providers and exact plugin compatibility
Choose a supported provider/plugin pairing before creating the migration. S3-compatible describes an API relationship; it does not guarantee that a particular WordPress plugin accepts the endpoint, authentication scheme, region, or delivery configuration.
Amazon S3
S3 is a documented storage provider for WP Offload Media. Evaluate the selected region, storage class, request volume, transfer paths, and delivery service. The official S3 pricing page separates these cost components. Price the actual architecture instead of comparing only a per-storage-unit headline.
Cloudflare R2
R2's pricing documentation describes storage and operation charges and no Internet-egress bandwidth charge. That does not make every workload free: requests, storage classes, retrieval where applicable, and connected services still matter.
R2 requires an appropriate endpoint and a separate delivery configuration. For public production delivery, review its custom-domain guidance. The r2.dev address is a development surface with limitations, not an interchangeable production CDN domain.
Backblaze B2
B2 provides an S3-compatible API with its own endpoint and application-key requirements. Review the current B2 pricing, including the download allowance and transfer conditions relevant to your delivery path. Do not assume that every CDN route has the same billing outcome.
WP Offload Media Lite's official listing identifies Amazon S3, DigitalOcean Spaces, and Google Cloud Storage. Do not infer native R2 or B2 support from its S3 support. By contrast, Advanced Media Offloader's listing explicitly names R2 and B2, as well as S3 and other providers. Its documented support makes it a candidate for a staging evaluation, not a guarantee for every custom endpoint or plugin combination.
No numerical price comparison or independent performance benchmark is asserted here. Check the current provider rates, data-location requirements, plugin edition, and supported restore behavior before committing the library.
Set up a documented S3 offload workflow
The example below uses WP Offload Media with Amazon S3. Its Lite listing describes copying new uploads and thumbnails, then supplying storage or CDN URLs. Existing-media bulk upload is a Pro feature. Keep that edition distinction in the plan for a populated website.
Prepare storage and permissions
Prepare a staging copy with the active theme, editor, shop, optimization, and media plugins. Back up its database and files independently of the future offload destination. Create a dedicated S3 bucket in the intended region, agree on the object-prefix convention, and assign responsibility for lifecycle rules, backups, billing alerts, and access changes.
Decide how visitors will receive files before changing public access. Assets can be intentionally public under an appropriate policy, or the bucket can remain a private origin behind a configured delivery service. Keep private material outside any public delivery path.
Scope the integration's permissions to its chosen operations and intended bucket, following the vendor's custom IAM policy documentation. Supply credentials through the documented server-side configuration; on supported AWS hosts the vendor also documents IAM-role use. Keep access keys out of public code, screenshots, browser scripts, committed configuration, and published examples.
The minimum policy depends on whether the plugin must create buckets, manage access settings, delete objects, or just use an existing bucket. The vendor explains that a bucket-scoped account can legitimately fail to list all account buckets; entering the known bucket name can avoid broadening permissions solely for that convenience.
Upload credentials and visitor-read access are different. A successful authenticated copy does not prove that a browser can read the result. Likewise, a publicly readable object does not establish that the upload identity is appropriately restricted.
Configure new uploads and delivery
Install the required WP Offload Media edition on staging and open Settings > Offload Media. Select Amazon S3, provide the documented credentials or role configuration, and select the prepared bucket. A deliberately restricted identity may require entering the known bucket name.
Configure the storage path and delivery choices with the S3 setup guide, leaving automatic local-file removal disabled. Upload a representative photo and any document or video types the site uses. Check that the expected source and generated image sizes exist at the recorded remote keys.
Insert the test media into a staging page and inspect its rendered URLs and browser Network responses while logged out. Check responsive image candidates and linked full-size files as well. Exercise normal editing and image-processing operations: if a builder, optimizer, or thumbnail job needs a local source, establish its supported retrieval behavior before removing local files.
The plugin's documented flow uploads through WordPress first, then copies to storage. It should not be described as a generic browser-to-bucket upload service. Also test whether custom HTML, CSS backgrounds, or external integrations bypass the WordPress functions that the plugin rewrites.
Use a private bucket with an intentional delivery layer
CloudFront can read an S3 origin without exposing the bucket directly. AWS recommends Origin Access Control for supported S3 origins. Configure the bucket policy and distribution according to that guidance, then set the plugin's delivery domain using its supported CDN configuration.
The vendor's CloudFront setup documentation explains the plugin's delivery side. Some vendor instructions still describe legacy Origin Access Identity; do not confuse that with AWS's current OAC recommendation or mix the two policies blindly.
A private origin does not make every CloudFront URL private to viewers. Public CDN delivery can still expose an object whose bucket rejects direct reads. Restricted user downloads require a deliberate viewer-authorization design, not merely a private-bucket checkbox.
For a custom media domain, configure DNS and an appropriate TLS certificate before using it in page output. Confirm both the hostname and object path. A working bucket with an incorrect delivery hostname still produces broken images.
Offload existing WordPress media with an audit trail
New-upload success is only the first acceptance check. Existing attachments can include years of thumbnails, edited originals, optimizers' alternative files, and manually embedded URLs.
- Record a migration baseline. Inventory attachment IDs, local source paths, known derivatives, current URLs, and expected remote keys. Include representative old pages, product media, galleries, and downloads in the verification set.
- Select a supported existing-media tool. In WP Offload Media Pro, the documented Tools area provides the Offload Tool. Lite's new-upload behavior does not migrate an existing library automatically. For another plugin, verify its exact bulk and edition capabilities.
- Run a small representative batch. Compare expected keys and object sizes, inspect attachment mappings, and verify that the delivery path returns the intended files. Include a generated-size URL rather than checking only the original.
- Investigate failures before continuing. Keep failed and completed attachments distinguishable. Check permissions, missing local sources, region/endpoint configuration, processing timeouts, and plugin logs. Do not treat an interrupted transfer as a complete migration.
- Process the remainder in supported batches. Retain local files and the migration record. If editors continue uploading during the transfer, account for those changes with a final synchronization or supported catch-up process.
- Verify application behavior. Open existing pages, product galleries, downloads, and important mobile layouts. Inspect
src,srcset, backgrounds, and links that do not pass through normal attachment rendering.
A storage copy alone does not update attachment mappings, database references, or custom URLs. Some integrations rewrite delivery at runtime; others also change stored values. Identify the selected plugin's model before performing a global search-and-replace. Raw replacement can damage serialized values and still miss ID-based references.
When using caches, distinguish the WordPress page cache from CDN object caches. Purging one does not necessarily refresh the other. An old cached page can continue requesting the original local path after newly rendered pages have switched to the remote domain.
Keep local files until recovery has been demonstrated
Only consider local removal after the migrated objects, delivery requests, attachment records, and editing workflows pass their checks. Use the plugin's supported retention/removal operation, not a manual directory deletion.
Check how image editing, thumbnail regeneration, and optimization recover their source after local removal. A media URL that works for visitors does not establish that a server-side process can obtain the file it needs. Generated variants should also remain available after a theme or size change.
Before making remote storage authoritative, test a return path for representative attachments. Restore or download their source files and their required derivatives through a supported operation, preserving the attachment IDs and metadata. Verify that the expected data exists at the local paths before switching delivery back to local. Then check page output and direct links, accounting for cached remote URLs.
Keep enough recovery information to reproduce the working system: the database, offload configuration and mappings, bucket data, and required domain settings. The return path is incomplete if any of those dependencies cannot be restored.
Deactivating an offload plugin while local files are absent can expose missing local URLs. Reuploading every source as a new attachment is not equivalent to restoring the original IDs. Budget for the time, requests, download traffic, and disk space required by a full restore.
Review deletion hooks and storage lifecycle rules. A WordPress deletion can propagate to remote objects through the integration. Versioning or retained backups can help only under their configured retention and restoration behavior; neither should be assumed to create a complete application backup automatically.
Troubleshoot the layer that failed
For a 403 or Access Denied response, separate upload credentials from visitor-read policies, CDN origin access, and encryption permissions. Making private files public does not fix an upload-policy error. If the provider connection works but delivery fails, verify support for the exact endpoint and public or CDN domain; API connectivity alone is not a completed delivery test.
A 404 calls for a comparison between the requested URL and its exact bucket key, prefix, filename case, and migrated derivative. Check whether that attachment completed offloading. When the original loads but its thumbnail fails, inspect generated-size metadata and remote objects, then confirm regeneration compatibility before creating or removing more files.
If only some images retain the old domain, inspect stored HTML, builder CSS, direct links, and page caches for references outside the selected rewrite mechanism. When a replacement still shows an old picture, check page and object caches, URL versioning, and the provider's invalidation procedure.
For a browser CORS error, identify the operation first. A JavaScript fetch or canvas operation has different cross-origin requirements from displaying an ordinary image. Check the required origins, methods, and headers against S3 CORS configuration. CORS does not grant object-read permission.
An unexpected bill needs a workload check: request volume, origin fetches, restored files, retained versions, storage class, and traffic paths can all affect costs. The storage rate by itself does not describe the total bill.
When the requirement is DAM rather than offloading
Object storage answers where bytes live and how they are addressed. A DAM adds an asset application: descriptions, collections, discovery, and the supported ways to reuse or deliver a source. Those roles can coexist in one architecture without becoming interchangeable.
Vyso currently provides a centralized asset library, collections, generated and user-managed metadata, hybrid search, duplicate-review tools, and image delivery. Its delivery documentation describes requested representations from source assets. That is different from managing WordPress attachment offload mappings.
For a broader comparison of application-level responsibilities, see DAM versus cloud storage. If several projects need to discover and select the same sources, define that asset handoff explicitly. Copying a file into WordPress does not establish ongoing synchronization with the DAM.
Vyso's WordPress integration remains in development. It is not a verified drop-in S3 offload plugin, and automatic WordPress media offloading is not an available capability established by that landing page.
Choose local storage when it adequately serves the site. Choose an offload integration when external attachment storage solves an operational need and recovery is understood. Add DAM workflows when asset identity, discovery, and reuse across projects require them. Each choice should pass its own upload, delivery, and recovery checks.
Keep going
Make the media library less work.
See how Vyso brings search, enrichment, cleanup, and delivery into one product.
Start free