Like most, the majority of files (project files, photos, videos, etc.) are all backed up to the cloud each day because, you know, just in case. But I treat my photos and videos a bit different. Yes, I have daily backups, but I handle my monthly backups a little bit differently.
Roughly 20 years ago, I lost all digital photos and videos that I’d had taken since digital cameras and cell phones with cameras became mainstream. The short of it is that I had all of that data backed up on two external hard drives. One was always connected to my machine, the other was sync’d periodically, because redundancy is important, right?
But fires don’t care about redundancy.
Since then, it would be an understatement to say I’m extremely particular with my backup process especially as it relates to photos and videos. And even more so since we’ve had kids.
Anyway, the gist of my process for backing up photos and videos from Apple Photos roughly follows this process:
- Export all images and videos from the last month
- Convert all
HEIC
to losslessJPEG
- Separate
HEIC
,JPEG
, video, screenshots, AI generated images, etc. in separate directories - Name the files based on the date contained in the
EXIF
data (or the closest approximation from file creation or modification) - Rsync this both with a local, external drive and a cloud backup service.
The most time-consuming part of the process are steps two through four. The rest are ideal for automation via local scripts and programs.
So to make the process a bit easier, I have a Monthly Backup utility I use help take care of the entire export. And maybe it’s something useful for others, too.
Backup and Sort Photos, Videos, Media, and AI Content

As the repository states:
A utility for easily backing up photos, videos, and screenshots from Apple Photos library.
When you export unmodified photos from your Apple Photo library, you place them in an export
directory in the root of the project. Then, after setting up the Python virtual environment and installing the dependencies, run python -m src.main
and you’ll have all of the files organized into subdirectories:
photos/
– actual photos with proper EXIF timestampsvideos/
–MOV
,MP4
, and other video filesscreenshots/
– iOS and macOS screenshots automatically detectedgenerated/
– AI-generated images and heavily edited contentunknown/
– anything that doesn’t fit the other categories
They’ll also be renamed based on the EXIF or metadata timestamps for ease of organization. The format is simple: YYYY.MM.DD.HH.MM.SS
, which makes chronological sorting trivial.
And if you’re curious to see how your content will be processed, you can run python -m src.main --dry-run
to see what will be processed and how it will be organized. This way, you’ll know if this is – or isn’t – the right program for you before making any changes to your files.
Installation
Three steps: clone the repository, create the virtual environment, install the dependencies.
Or, in other words:
# Clone the repository
git clone https://github.com/tommcfarlin/tm-monthly-backup.git
cd tm-monthly-backup
# Create the virtual environment.
python3 -m venv tm-backup-env
source tm-backup-env/bin/activate
# Install the dependencies.
pip install -r requirements.txt
Then you can run the program. I typically use it once a month, as stated, after exporting that month’s photos and videos from iCloud, but you can run it as frequently or infrequently as you want.

More Technical Details
The remainder of this this article covers how the program actually works, how to use it, and how you can fork it, report bugs, or add features.
Sorting Types of Files
The program does more than just move files around. It actually looks at the content and makes intelligent decisions about how to handle it.
Images
For HEIC
files, it converts them to high-quality JPEG
while preserving all the EXIF data. Apple’s sidecar files (those .aae
files that come along for the, ahem, ride) get cleaned up automatically since they aren’t needed when the conversion is done.
Videos
Video timestamps are extracted from the actual video metadata, not just the file creation date. This matters because if the file has been copied or moved, the filesystem date might be wrong, but the embedded metadata in the video file itself is usually accurate.
AI Content
The AI content detection is particularly useful (and something I didn’t really need until recently, for obvious reasons). Images from ChatGPT or other AI tools are automatically separated into the generated folder. It looks for C2PA metadata, UUID-style filenames, and other signals that something was generated rather than captured with a camera.
Screenshot detection works by recognizing iOS and macOS patterns. Those IMG_3XXX.PNG
files or anything with “Screenshot” in the name gets sorted appropriately.
When there are duplicate timestamps, which happens especially when burst mode has been used, the tool increments the seconds to keep everything unique. And if a file is missing EXIF
data entirely, it falls back to filesystem timestamps and will generate a note about this in its output.
Usage
Assuming you’ve already installed the program, here’s a few notes on how to use it.
The utility expects your exported files to be in an export/
directory and will create a backup/
directory with all your organized content. If you want to see what it’ll do before committing, that dry-run flag is your friend.
For debugging or if you’re just curious about what’s happening under the hood, there’s a verbose mode: python -m src.main --verbose
. It’ll show you all the processing details, which is helpful if something isn’t working quite right or if you want to understand how a particular file got categorized.
The whole thing is built with proper CLI conventions, so python -m src.main --help
will give you all the options if you need a reference.
Obligatory Contribution Note
If you’re backing up Apple Photos and related media on a regular basis and find the manual organization tedious, feel free to check it out on GitHub.
The code is MIT licensed, so you can use it, modify it, or ignore parts you don’t need. And if you find issues or have suggestions, pull requests are always welcome.