Skip to content

Repository files navigation

iCloud Offload

Free up iCloud storage without losing a single photo.

iCloud Offload moves your iCloud Photos library to your own computer, in a way that is designed to be boring and safe:

  1. Download everything created on or before a cutoff date you choose.
  2. Verify that every one of those items really exists on disk (filename and exact byte size, checked against iCloud).
  3. Only then delete them from iCloud. Deleted items land in iCloud's Recently Deleted album, where they stay recoverable for about 30 days.

Move the cutoff forward whenever you like and repeat. Photos newer than the cutoff stay in iCloud and on your phone, untouched.

It is a friendly terminal app around the excellent icloudpd, which does the actual talking to Apple. Works on Linux, macOS and Windows.

Warning: the whole point of this tool is to delete photos from iCloud. It tries very hard to only do so after proving the local copy is complete, but you are responsible for your own backups. Read the safety section before you use the offload step, and keep a second copy of the backup folder somewhere.

Install

Linux / macOS (Terminal):

curl -fsSL https://raw.githubusercontent.com/hacktisch/icloud-offload/main/install.sh | bash

Windows (PowerShell):

irm https://raw.githubusercontent.com/hacktisch/icloud-offload/main/install.ps1 | iex

The installer makes sure Python 3.10+ and pipx are present (installing them with your system's package manager / winget if not), then installs icloud-offload together with icloudpd into an isolated environment. Nothing else on your system is touched.

Already have pipx? Then simply:

pipx install https://github.com/hacktisch/icloud-offload/archive/refs/heads/main.tar.gz

To uninstall: pipx uninstall icloud-offload.

Use

icloud-offload

The first run walks you through setup: your Apple ID, where to store the backup (default: a folder called iCloud Offload in your Pictures folder), and the cutoff date. Then you get a menu:

   1  Set cutoff date     everything on or before this date is in scope
   2  Preview download    list what would be downloaded, changes nothing
   3  Download            back up everything up to the cutoff
   4  Verify              confirm every item up to the cutoff is on disk
   5  Preview deletion    count what would be removed from iCloud, changes nothing
   6  Offload             download + verify + DELETE from iCloud
   7  Test on one album   the full offload flow, scoped to a small album
   8  Settings            Apple ID, backup folder, folder layout
   q  Quit

A sensible first session:

  1. Pick a cutoff a year or two back, so the first batch is manageable.
  2. Download (option 3). The first time, iCloud asks you to sign in and enter a two-factor code right there in the terminal. Downloads are resumable: run it again and it skips what it already has.
  3. Test on one album (option 7): make a small album in the Photos app with two old photos, and run the whole download-verify-delete flow on just that album. It takes seconds and shows you exactly what will happen to the full library.
  4. Offload (option 6). Confirm by typing delete. Go make coffee.
  5. Check your phone: the old photos are gone from iCloud, still on disk, and in Recently Deleted for 30 days just in case.

Later, move the cutoff forward and repeat.

Command line

Everything in the menu is also a sub-command, for scripts and cron jobs:

icloud-offload status
icloud-offload set-cutoff 2024-01-01
icloud-offload download [--dry-run] [--album NAME]
icloud-offload verify [--album NAME]
icloud-offload preview-delete
icloud-offload offload [--album NAME] [--yes]
icloud-offload albums
icloud-offload paths          # where the config file and logs live

Every icloudpd run is logged in full to the logs folder shown by icloud-offload paths.

Photos are backed up, now what?

The backup folder holds your originals in YYYY/MM/ sub-folders (HEIC, JPEG, MOV, Live Photo pairs...). Any photo manager can index it. If you want the Apple-Photos-like experience (faces, map, semantic search) on your own machine, Immich pointed at the backup folder as an external library works very well. Mount the backup folder read-only in Immich: those files are the only copy you have left.

How it keeps your photos safe

  • Verify before delete, always. The offload step first asks iCloud to list every item up to the cutoff that is not on disk (icloudpd matches on filename plus exact byte size). Anything missing is downloaded and the check repeats. Deletion only starts once that list is empty. If a run fails or the list is not empty, nothing is deleted.
  • Two independent bounds on what gets deleted. The delete run tells icloudpd both "skip anything created after the cutoff" and "keep anything more recent than N days", where N is the age of the cutoff. Either alone would already protect everything newer than the cutoff.
  • Nothing recent. The cutoff must be at least one full day in the past.
  • Recently Deleted. Deleting through the iCloud API is the same as deleting in the Photos app: items go to Recently Deleted and can be restored from any device for about 30 days.
  • Explicit confirmation. The offload step shows exactly what it is about to do and requires you to type delete.
  • Dry runs for everything. Preview download and preview deletion change nothing, and a scoped test on a throwaway album exercises the real flow on two photos.
  • Full logs. Every icloudpd invocation, with its full output, is saved to a timestamped log file.

What it does not protect against: a broken disk holding the only copy. Keep a second backup of the backup folder.

Good to know

  • Two-factor authentication prompts come from icloudpd and appear in the terminal. The session is cached for a while (in icloudpd's cookie folder, ~/.pyicloud by default), so you are not asked every run.
  • Advanced Data Protection (end-to-end encrypted iCloud) is not supported by icloudpd, and therefore not by this tool. Apple also requires "Access iCloud Data on the Web" to be enabled in iCloud settings.
  • Runs are slow on big libraries. Apple's API only lists a library newest-first, with no way to stop early, so every step walks the whole library (about one request per 100 items). Verify on a 50,000-item library takes a few minutes; the download of course depends on how much there is. The tool is careful to walk the library as few times as possible.
  • Endless deletion runs. Apple's API has a bug where the last page of a listing is served forever. The tool detects this, stops the run, and continues correctly. See docs/HOW_IT_WORKS.md for this and the other icloudpd quirks it works around.
  • Folder layout defaults to YYYY/MM; change it under Settings (any icloudpd --folder-structure value works). Don't change it after the first download, or verification will report everything as missing.
  • Config file: icloud-offload paths shows where it is. It is plain JSON; ICLOUD_OFFLOAD_CONFIG or --config point the tool at a different one (handy for two Apple IDs).

Troubleshooting

  • "icloudpd was not found": reinstall with pipx reinstall icloud-offload.
  • Verify says files are missing but they are on disk: the filename or the size differs from what iCloud has. Usually the folder layout changed, or a download was interrupted mid-file. Run Download again; it re-fetches mismatched files.
  • "passes stopped making progress": iCloud is lagging behind its own deletions. Wait a bit and run the offload again.
  • Stuck at sign-in / 2FA: run icloudpd --username you@example.com --auth-only once by hand to refresh the session, then try again.
  • Anything else: look at the newest file in the logs folder and open an issue with the relevant lines.

Development

git clone https://github.com/hacktisch/icloud-offload
cd icloud-offload
python3 -m venv .venv && . .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
pytest
ruff check .

The tests never talk to iCloud: they run the workflow against a scripted fake icloudpd (tests/fake_icloudpd.py). See CONTRIBUTING.md.

License

MIT. Not affiliated with Apple. Built on icloudpd, thank you to its maintainers.

About

Backup media to a cutoff date to your machine and delete them from your iCloud to take back control over your storage use.

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages