Title: Atlas Media Offloader
Author: Atlas Gondal
Published: <strong>August 16, 2026</strong>
Last modified: August 16, 2026

---

Search plugins

![](https://ps.w.org/atlas-media-offloader/assets/banner-772x250.png?rev=3649468)

![](https://ps.w.org/atlas-media-offloader/assets/icon.svg?rev=3649468)

# Atlas Media Offloader

 By [Atlas Gondal](https://profiles.wordpress.org/atlas_gondal/)

[Download](https://downloads.wordpress.org/plugin/atlas-media-offloader.1.0.zip)

 * [Details](https://wordpress.org/plugins/atlas-media-offloader/#description)
 * [Reviews](https://wordpress.org/plugins/atlas-media-offloader/#reviews)
 *  [Installation](https://wordpress.org/plugins/atlas-media-offloader/#installation)
 * [Development](https://wordpress.org/plugins/atlas-media-offloader/#developers)

 [Support](https://wordpress.org/support/plugin/atlas-media-offloader/)

## Description

Atlas Media Offloader moves your WordPress uploads to S3-compatible object storage,
rewrites the URLs so visitors are served from the bucket (or a CDN in front of it),
and can pull everything back to local disk on demand.

It was written for libraries measured in gigabytes, where the interesting question
is not “can it upload a file” but “what happens when the upload is interrupted”.
Every transfer is resumable, every deletion is preceded by a verification, and the
whole thing is safe to interrupt at any point.

#### What it does

 * **Move media to the bucket.** In bulk, or automatically as each new file is uploaded.
 * **Bring media back.** In bulk, or per attachment. Files are restored byte-for-
   byte.
 * **Serve from the bucket or your CDN.** Attachment URLs, responsive `srcset` entries,
   image sizes, and the media modal are all rewritten.
 * **Optionally delete local copies.** Only after every single file has been re-
   checked in the bucket and its byte count matches.
 * **Private buckets.** Media URLs are signed, with a configurable lifetime.
 * **See the state of every image.** The Media tab lists each attachment with its
   offload status and, when something was skipped, exactly why — with per-image “
   offload now”, “re-check” and “download” buttons.
 * **Know what happened.** An activity log records every bulk transfer and every
   automatic offload, in plain English.
 * **Clean up after itself.** Deleting an attachment deletes its objects; cropping
   an image removes the objects the old crop left behind.
 * **Check your own work.** `wp atlasmo verify` re-reads every recorded object out
   of the bucket and compares its size; `--repair` re-uploads anything missing or
   truncated.
 * **WP-CLI.** `wp atlasmo offload`, `wp atlasmo download`, `wp atlasmo verify`,`
   wp atlasmo status`, `wp atlasmo test`.

#### Providers

 * Amazon S3
 * DigitalOcean Spaces
 * Any other S3-compatible endpoint (Cloudflare R2, Wasabi, Backblaze B2, MinIO,…)
   via a custom endpoint URL

#### Languages

Fully translation-ready, and ships with Spanish, French and German translations 
of the main interface. Anything not yet translated falls back to English.

#### Built for large libraries

Moving a lot of media through PHP means the work _will_ be interrupted and this 
plugin is designed around that rather than in spite of it:

 * **Large files upload in parts and resume from the last completed part.** A 2 
   GB file that runs out of time picks up where it stopped instead of starting over.
   The worst case for a hard crash is re-sending 32 MB.
 * **Local files are never deleted before the copy in the bucket has been verified.**
   Uploading, verifying, recording and deleting happen strictly in that order. A
   crash between any two of them leaves you with a redundant local file, never a
   missing one.
 * **The transfer keeps running with the tab closed.** Three independent triggers
   drive it, so it does not depend on WP-Cron — which most managed hosts disable.
 * **Only one worker ever runs at a time**, so nothing is ever uploaded twice, even
   when a cron run, a browser tab, and WP-CLI all try at once.
 * **A wrong secret key pauses the transfer** rather than failing your entire library
   one file at a time.
 * Progress, failures and their reasons are all shown, and failed items can be retried.

#### No third-party libraries

The plugin talks to S3 directly. It implements AWS Signature V4 itself, uses the
WordPress HTTP API for transport, and `WP_Filesystem` for file access. There is 
no AWS SDK, no Guzzle, no Action Scheduler, and no build step. The whole plugin 
is plain PHP and a little vanilla JavaScript.

### When we need this plugin?

 * Your uploads folder has outgrown your hosting plan.
 * You are moving to a container or serverless host where local disk is not persistent.
 * You want media served from a CDN without a caching plugin in the middle.
 * You are migrating hosts and want the media somewhere neutral first.
 * You need media behind signed, expiring URLs.

### Customizable Features

 * Provider preset (Amazon S3, DigitalOcean Spaces, or a custom endpoint)
 * Path-style vs. virtual-hosted addressing
 * A key prefix, so media can live in a folder inside the bucket
 * A CDN domain to serve from
 * Public bucket, or private with signed URLs and a configurable lifetime
 * Automatic offload of new uploads, on or off
 * Deletion of local copies after verification, on or off
 * Multipart part size (5–16 MiB)
 * Rewriting of hard-coded upload URLs in old post content

#### Storing credentials in wp-config.php

This is the recommended setup. Anything defined here overrides the settings screen,
is shown read-only, and never touches the database:

    ```
    define( 'ATLASMO_PROVIDER',   'aws' );
    define( 'ATLASMO_ACCESS_KEY', '...' );
    define( 'ATLASMO_SECRET_KEY', '...' );
    define( 'ATLASMO_BUCKET',     'my-bucket' );
    define( 'ATLASMO_REGION',     'us-east-1' );
    ```

Optional: `ATLASMO_ENDPOINT`, `ATLASMO_PATH_STYLE`, `ATLASMO_CDN_DOMAIN`, `ATLASMO_PRIVATE`.

If you enter the secret key in the settings screen instead, it is encrypted with
AES-256-GCM using your site’s security salts before being stored, and is never rendered
back to the page. Rotating `AUTH_KEY` or `SECURE_AUTH_KEY` will invalidate it, and
the plugin will tell you so rather than silently failing.

#### Bucket permissions

The plugin needs exactly five actions. Do not grant it more:

    ```
    s3:PutObject, `s3:GetObject`, `s3:DeleteObject`, `s3:ListBucket`, `s3:AbortMultipartUpload`
    ```

#### Hooks for developers

 * `atlasmo_extra_files` — add sibling files (WebP/AVIF conversions, etc.) to an
   attachment’s upload set.
 * `atlasmo_skip_auto_offload` — skip automatic offload for a particular attachment.
 * `atlasmo_keep_remote_on_delete` — keep the objects in the bucket when an attachment
   is deleted.

#### System requirements

 * PHP 7.4 or newer, with the `openssl` extension (only needed if you store the 
   secret key in the database rather than in `wp-config.php`).
 * WordPress 6.0 or newer.
 * Outbound HTTPS from your web server to the storage endpoint.

### External services

This plugin is a client for third-party object storage. Its entire purpose is to
transfer your media to a storage provider that **you** choose and configure. It 
does not contact any service until you enter your own storage credentials, and it
never sends anything to the plugin author. There is no telemetry, tracking, or analytics
of any kind.

Which service is contacted depends entirely on the provider you select on the Connection
screen.

#### Amazon S3

Used only if you select “Amazon S3” as your provider. The plugin connects to the
Amazon S3 REST API at your chosen region’s endpoint (for example, `s3.eu-west-1.
amazonaws.com`) in order to store, read, verify and delete your media files.

What is sent, and when:

 * **Your media files** (the original plus every generated image size) — when you
   run a bulk transfer, when a new file is uploaded and automatic offload is enabled,
   or when you offload a single attachment.
 * **Object names and file sizes** — on every request, so the plugin can verify 
   that what was stored matches what was on disk.
 * **Your AWS access key ID and a request signature** derived from your secret key—
   on every request, as required by AWS Signature Version 4. Your secret key itself
   is never transmitted.
 * **A small test file** — only when you press “Test connection”. It is written,
   read back, and immediately deleted.
 * **Delete requests** — when you delete an attachment in WordPress, or bring media
   back to local disk and choose to remove the remote copies.

Service provided by Amazon Web Services, Inc.
 Terms: https://aws.amazon.com/service-
terms/ Privacy policy: https://aws.amazon.com/privacy/

#### DigitalOcean Spaces

Used only if you select “DigitalOcean Spaces” as your provider. The plugin connects
to the Spaces API at your chosen datacenter endpoint (for example, `nyc3.digitaloceanspaces.
com`). The data sent, and the circumstances under which it is sent, are identical
to the Amazon S3 list above, using your Spaces access key and signature.

Service provided by DigitalOcean, LLC.
 Terms: https://www.digitalocean.com/legal/
terms-of-service-agreement Privacy policy: https://www.digitalocean.com/legal/privacy-
policy

#### Other S3-compatible storage

If you select “Other S3-compatible” you supply the endpoint URL yourself, and the
plugin talks only to that host. This is intended for providers such as Cloudflare
R2, Wasabi, Backblaze B2, or a self-hosted MinIO server. The data sent is the same
as above. Because you choose the host, you are responsible for reviewing that provider’s
own terms and privacy policy.

#### Serving media

Once media is offloaded, the URLs on your site point at your storage bucket (or 
at a CDN hostname, if you configure one). Visitors’ browsers therefore request those
files directly from your chosen provider, and that provider will see the visitor’s
IP address and user agent, as it would for any file hosted there.

### Contact

Found a bug, or something behaved in a way this readme did not predict? Get in touch
at https://AtlasGondal.com/contact-me/?utm_source=self&utm_medium=wp&utm_campaign
=atlas-media-offloader&utm_term=plugin-description

## Installation

 1. Upload the `atlas-media-offloader` folder to `/wp-content/plugins/`, or install
    it through the Plugins screen.
 2. Activate it.
 3. Go to **Media  Cloud Offload**, enter your provider details, and press **Test connection**.
 4. Open the **Offload** tab and start a transfer.

Local copies are kept by default. Deleting them is opt-in, behind a confirmation,
on the Advanced tab.

## FAQ

### Is it safe to deactivate the plugin?

Yes, as long as your local files are still there. Deactivating removes the URL filters
and WordPress goes back to serving media from `wp-content/uploads`. Nothing in `
_wp_attached_file` or `_wp_attachment_metadata` is ever modified, so reactivating
restores everything.

If you enabled “delete local files”, the bucket is the only copy, and deactivating
will leave those images broken until you run `wp atlasmo download` (or use the Download
option on the Offload tab).

### What happens when I uninstall?

The plugin’s own data — its two database tables, its options, and the record it 
keeps against each attachment — is removed. **Your bucket is never touched.** Uninstalling
a plugin is not consent to delete your media.

If you deleted your local files, download them back _before_ uninstalling. Otherwise
WordPress will no longer know where those files went.

### The transfer seems to have stopped.

Open the Status tab. If it says the worker has not reported in, your host has WP-
Cron disabled _and_ blocks loopback requests to itself. Either leave the Offload
tab open in a browser, or run `wp atlasmo offload` from the command line.

### Can I use it with Cloudflare R2 / Wasabi / Backblaze B2 / MinIO?

Yes — choose “Other S3-compatible” and enter the endpoint URL. A few notes:

 * **R2** uses the region string `auto`, does not support ACLs, and needs path-style
   addressing.
 * **Backblaze B2** wants its cluster id (`us-west-004`) as the region, not a geographic
   name.
 * **MinIO** and most self-hosted endpoints need path-style addressing.

Use the “Test connection” button — it uploads, verifies, reads and deletes a small
file, so a pass means the credentials really can do everything the plugin needs.

### One of my images was skipped. Why?

Open the **Media** tab and use the **Problems** filter, or find the image in the
list. The status column says exactly what happened. The most common cause is **“
Source file missing”**: WordPress has a record of the file but it is not actually
on disk — usually a leftover from an earlier migration — so there is nothing to 
upload. That is a skip, not a failure, and nothing is wrong with the plugin. Every
bulk run also records its outcome on the **Status & activity** tab.

### Does it handle image editing?

Yes. Cropping or rotating an image in WordPress writes new files; the plugin uploads
them and removes the objects belonging to the old version. Running `wp media regenerate`
does _not_ re-upload anything, because nothing has actually changed.

### Multisite?

Yes. Each site in the network keeps its own settings, its own queue, and its own
key prefix, and uninstall cleans up every site.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Atlas Media Offloader” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ Atlas Gondal ](https://profiles.wordpress.org/atlas_gondal/)

[Translate “Atlas Media Offloader” into your language.](https://translate.wordpress.org/projects/wp-plugins/atlas-media-offloader)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/atlas-media-offloader/),
check out the [SVN repository](https://plugins.svn.wordpress.org/atlas-media-offloader/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/atlas-media-offloader/)
by [RSS](https://plugins.trac.wordpress.org/log/atlas-media-offloader/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.0

 * Initial release.

## Meta

 *  Version **1.0**
 *  Last updated **19 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.2 or higher **
 *  Tested up to **7.1**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [cdn](https://wordpress.org/plugins/tags/cdn/)[cloud storage](https://wordpress.org/plugins/tags/cloud-storage/)
   [media library](https://wordpress.org/plugins/tags/media-library/)[media offload](https://wordpress.org/plugins/tags/media-offload/)
   [object storage](https://wordpress.org/plugins/tags/object-storage/)
 *  [Advanced View](https://wordpress.org/plugins/atlas-media-offloader/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/atlas-media-offloader/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/atlas-media-offloader/reviews/)

## Contributors

 *   [ Atlas Gondal ](https://profiles.wordpress.org/atlas_gondal/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/atlas-media-offloader/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YWT3BFURG6SGS&source=url)