21+ years in hosting · Jaipur, India · INR billing with 18% GST · 24/7 email support
Blog · WebJi® India

Offload the WordPress Media Library

Quick answer

Offloading moves uploads out of wp-content/uploads into an S3 or Cloudflare R2 bucket and serves them from a CDN hostname. Install WP Offload Media, add the bucket keys, run the bulk offload, and keep local copies until every image loads from the new URL. Most breakage is a URL still pointing at the old path.

For WordPress owners whose uploads folder outgrew the plan: the bucket choice, the exact plugin steps, the URL rewrite, and the checks that prove the CDN is serving.

✓ In business since 2005
✓ INR + GST billing
✓ 24/7 Email Support — avg reply < 60 min
GuideWebJi®
knowledge
Read time
6 min
Sections
8
Updated
14 Nov 2026
Written by
WebJi® team

What offloading the media library actually changes

Offloading keeps every attachment row in the WordPress database but moves the file behind it into an Amazon S3 or Cloudflare R2 bucket, which a CDN then serves from its own hostname. The library still lists the image, the post still references the attachment ID, and only the URL that reaches a browser changes.

  • wp-content/uploads stops growing on the hosting account.
  • Attachment URLs render from the CDN host, not from your domain.
  • The origin keeps serving HTML, PHP and MySQL.
  • Disk savings arrive only when local copies are deleted — until then storage is used twice.

A 2 GB uploads folder on a shared plan is the usual trigger, because every hosting backup and every migration copies it again. Offloading cuts that weight without touching the theme or the editor.

S3 or Cloudflare R2: which bucket should you use?

Choose R2 when traffic is unpredictable and the bill must stay flat, because R2 charges nothing for egress; choose S3 when the AWS account, IAM policies and CloudFront already exist. R2's published pricing is 10 GB free, then $0.015 per GB-month, with no egress fee (Cloudflare figures read 4 November 2026); S3 bills storage, requests and every GB delivered (AWS pricing page, read 4 November 2026).

Storage backends commonly used for WordPress media offload
BucketHow it billsFits
Amazon S3 + CloudFrontStorage, requests, and every GB deliveredAWS shops, lifecycle rules, multiple regions
Cloudflare R210 GB free, then $0.015/GB-month, no egress feeImage-heavy Indian sites with spiky traffic
DigitalOcean SpacesFlat monthly space with a bandwidth allowanceOne-region portfolios and brochure sites
Bunny StoragePer-GB storage plus per-GB deliveryTeams already on Bunny CDN

Put the bucket in the region closest to your readers — Mumbai (ap-south-1) for an Indian audience. One European bucket adds a round trip to every first view, whatever the CDN does afterwards.

How do you connect WP Offload Media to the bucket?

The plugin cannot move anything until the key, the bucket and the CDN hostname are saved, so work in this order and test one upload before any bulk run. The Lite build on WordPress.org connects Amazon S3 and DigitalOcean Spaces; Cloudflare R2, Google Cloud Storage and asset offload need the Pro licence (Media Cloud is a free plugin that speaks R2 if you want a trial run).

  1. Back up first: wp db export pre-offload.sql plus an FTP copy of wp-content/uploads. Both are needed if the switch goes wrong.
  2. Create the bucket. On S3 pick ap-south-1 and keep Block Public Access on; on R2 attach a custom domain so files get a stable hostname.
  3. Create a key scoped to that one bucket: an IAM user with PutObject, GetObject and DeleteObject on arn:aws:s3:::your-bucket/*, or an R2 API token with Object Read & Write scope.
  4. Install the plugin: wp plugin install amazon-s3-and-cloudfront --activate for the Lite build, or upload the Pro zip under Plugins → Add New.
  5. Configure: Settings → WP Offload Media — choose the provider, paste key and secret, set bucket and region, set the path to wp-content/uploads, and switch Force HTTPS on.
  6. Add the CDN hostname (the CloudFront distribution or the R2 custom domain) into the CDN field and save.

How do you rewrite the URLs already in the database?

Saving the settings only affects new uploads; old files keep local URLs until the bulk tool runs — Media → Library, list view, select all, Bulk actions → Offload. The counter under Settings shows how many attachments still wait. Large libraries time out in the browser, so run the action on about 200 files at a time, or use a plugin that ships a WP-CLI batch command and run its dry-run pass first.

What the bulk step changes is attachment metadata, not your prose. WordPress asks the plugin for the attachment URL at render time, so the database can still hold /wp-content/uploads/2026/10/photo.jpg while the page shows the CDN hostname. A URL typed into a paragraph, a widget or a page-builder background is not an attachment URL and stays on the old host.

Find those before launch, then replace the host with a dry run first:

wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%wp-content/uploads%' AND post_status='publish' LIMIT 30;"

wp search-replace 'https://example.com/wp-content/uploads' 'https://cdn.example.com/wp-content/uploads' --precise --dry-run

Repeat the search-replace without --dry-run only when the report lists the rows you expect.

What breaks after an offload, and how do you fix it?

Nearly every failure after a switch is one of six, and each has a screen or a command that clears it — check the counter under Settings first, because if it does not read "Offloaded all", nothing else is worth debugging.

Six post-offload failures and their fixes
SymptomCauseFix
Images still load from your domainThe bulk offload never ran on pre-plugin filesMedia → Library, select all, Bulk actions → Offload
Grey boxes instead of thumbnailsOnly the original reached the bucket, not resized versionsRegenerate thumbnails, then offload the missing sizes
Mixed content warningThe CDN field was saved with http://Change to https:// and purge the page cache
Fonts or CSS missingCDN response carries no Access-Control-Allow-OriginAdd that header at the CDN for font and CSS paths
WooCommerce gallery emptyAn imported CSV stored full image URLs, not attachment IDsRe-import the image column or run the scoped search-replace
Restored backup shows no imagesLocal files deleted; the hosting backup excludes the bucketKeep a bucket copy or a sync job alongside the account backup

The WordPress image editor also fails once a local file is gone, because cropping reads the file from disk. Leave "Remove Local Files" off for the first week and delete in one pass after the bucket copy is confirmed.

How do you verify the CDN is actually serving the files?

Ask the CDN directly with a HEAD request against the file's URL taken from the media library, not from the page source. One command answers whether the object, the cache and the headers are right.

curl -sI https://cdn.example.com/wp-content/uploads/2026/10/photo.jpg
  • 200 with content-type image/jpeg — the object is in the bucket.
  • cf-cache-status: HIT (Cloudflare, on the second request) or x-cache: Hit from cloudfront — the edge has it.
  • cache-control: public with a long max-age — the edge will keep it.

Then load the post, view source, and count img tags that start with the CDN host against those that start with your domain; the second count should be zero apart from deliberately local images. Upload one new image afterwards and confirm its URL already points at the CDN. For the next win after images — WebP conversion, lazy loading, resizing — follow the WordPress image optimisation guide.

Rollback, backups, and where hosting fits

Rollback is a plugin action, not a restore: while local copies exist, the plugin's Restore action in the media library puts URLs back to /wp-content/uploads, and you can then deactivate it. After local files are deleted, the bucket is the only copy — export it before cancelling storage.

Media offload does not shrink the database, and a database backup still decides whether a restore works. WebJi®'s WordPress website backup service covers files and MySQL on the account, which is why the first week should keep both copies. The hosting account still runs PHP, MySQL and the page cache: WebJi® WordPress hosting starts at ₹400 a month before 18% GST (Wordpress-Unlimited, read from WebJi® billing on 15 November 2026; checkout confirms current charges) and includes the WP install wizard, daily backups, staging tools and global CDN. Sites already serving images from a CDN get the most from the WordPress speed guide.

Competitor figures on this page were read from Amazon's S3 pricing page and Cloudflare's published R2 pricing on 4 November 2026; those pages change without notice. WebJi® is not affiliated with, and is not the support desk of, any company named on this page.

FAQ

Frequently asked questions

Do I need WP Offload Media Pro for Cloudflare R2?

Yes. The Lite build on WordPress.org connects Amazon S3 and DigitalOcean Spaces only. Cloudflare R2, Google Cloud Storage and the CSS/JS/font offload are sold in the Pro licence; Media Cloud is a free plugin with R2 support if you want to test the workflow first.

Will offloading break existing images?

No, if the bulk offload runs and local copies stay in place until you check. Attachment URLs switch at render time; images pasted into posts, widgets or builder backgrounds as full URLs keep the old host and need a scoped search-replace.

What happens if I deactivate the plugin?

WordPress falls back to /wp-content/uploads. If those files still exist, images load as before; if "Remove Local Files" already deleted them, every image 404s until you reactivate the plugin or restore the bucket files.

Does offloading free disk space straight away?

No. The database still holds every attachment and the files stay on disk until "Remove Local Files" runs. The space appears after that pass, and hosting backups shrink on the next run.

Can I keep local copies as a backup?

Yes — the offload plugins leave local files in place by default. That uses storage twice but keeps the rollback cheap, and it is the safer setting for the first month. Pair it with a scheduled account backup so files and database restore together.

Last editorial update: 15 November 2026. Prices follow the dated sources on this page; checkout confirms current charges.

WebJi® since 2005

Ready to get started with WebJi®?

Join 12,000+ businesses across India and overseas. INR pricing, 18% GST shown before payment and 24/7 email support in Hindi and English — average first reply under 60 minutes.