Self-Hosting Immich: How iCloud 'Optimize Storage' Silently Wrecks Your Photo Backup
Running Immich for photo backup? iCloud Optimize Storage can quietly back up 3MP thumbnails instead of originals. How to audit your library and fix it.
I finally got off Google Photos. Immich is running on the homelab box, the mobile app is installed, and the app says “backup complete.” That’s a pretty good feeling the first time it happens.
It’s also, potentially, a lie.
Not a malicious lie. More like a lie of omission that lives in the gap between “what the backup app thinks is on your phone” and “what is actually on your phone.” If your iPhone is set to iCloud “Optimize Storage,” those two things aren’t the same. And that gap can silently fill your shiny self-hosted backup with 3-megapixel thumbnails instead of the 12MP originals your camera actually shot.
I found this out the hard way, by actually auditing my library.
What Immich Is and Why You Should Run It
Quick context if you’re new to this: Immich is a self-hosted photo and video library, open source, actively maintained, and genuinely good. It looks like Google Photos. It has a timeline view, facial recognition, smart search, and mobile apps for iOS and Android. The mobile app backs up your camera roll automatically, just like Google Photos or iCloud would, except the photos go to your server.
It runs well on modest hardware. A mini PC, a spare NUC, a Proxmox VM with a few cores and a couple gigs of RAM: any of those will handle a household library without breaking a sweat. The storage goes on whatever you have pointed at it (local disk, a NAS mount, whatever). It’s the kind of service that costs you an afternoon to set up and then runs unattended for years.
I’ve been running it for a while now. No complaints. The catch I’m describing here isn’t an Immich bug. It’s a systemic mismatch between how iCloud handles photos and how any mobile backup app has to work.
The Trap: iCloud Optimize Storage
Here’s what happens on a modern iPhone by default, or any iPhone that has run out of local storage at some point.
When you enable “Optimize iPhone Storage” in Photos settings, iCloud keeps your full-resolution originals in the cloud. On the device itself, iOS stores a reduced version: a thumbnail sized down to something around 1536x2048 pixels for most modern hardware. Roughly 3.1 megapixels. Your iPhone 14 or 15 or 16 shoots at 12 megapixels (or 24.5MP in ProRaw). The on-device copy is less than a quarter of that.
The iOS Photos API is supposed to let a backup app request the full-resolution original. When it works, iCloud downloads the original to the device before the backup app reads the file. When it doesn’t work (because iCloud is throttling downloads, or the backup triggered before the download completed, or the library is large and the app is running through assets faster than iCloud can respond) the backup app reads whatever is on disk. Which is the 3MP thumbnail.
Immich’s mobile app does try to pull originals. But on a large initial backup (especially a first-sync situation where hundreds or thousands of assets are moving fast) it can get ahead of iCloud’s delivery pace. The result is that a batch of photos uploads at 1536x2048 instead of 4032x3024. Immich stores them as originals, labels them “backed up,” and moves on. You never see an error.
Your backup says it’s complete. Technically it is complete. It just backed up reduced copies.
How Bad Can It Actually Be?
I ran a proper database audit of my library after getting suspicious about a batch of recent photos. Queried the Immich asset tables directly, joined against EXIF data, pulled dimensions for everything.
Here’s what turned up: 29,907 images in the library. Of the photos from modern rear-facing iPhone cameras (the hardware that should be shooting at 12MP or better), about 7.9% came in at 2048px max edge or below. That’s the resolution signature of an iCloud-optimized copy.
The most striking cluster: roughly 600 photos from a current-generation iPhone, all shot within a single week, all uploaded on the exact same day (the day the Immich server went live). Every single one at 1536x2048, averaging about 0.89 MB per file. Full-res from that camera should be 4032x3024 and averaging 1.37 MB or more. These weren’t low-light shots, not portrait mode crops, not anything that would explain the reduction. They were normal camera shots that arrived from iCloud as thumbnails because the initial sync ran faster than iCloud’s download queue.
The rest of the affected photos were a scatter of older hardware and multiple years, probably the same cause (iCloud optimize mode at various points in the phone’s history). Harder to remediate in bulk, lower stakes because some of those originals may no longer exist at full resolution in iCloud anyway.
But the 600 recent ones? Those should be 12MP. They’re not.
What It Looks Like in Your Library
This is the insidious part. In the Immich UI, these photos look fine. They display at normal size on screen. The faces are sharp. The metadata says “iPhone back camera.” There’s nothing obviously wrong unless you pull up the file info and see dimensions of 1536x2048 when you were expecting 4032x3024.
Most people never do that. Most people assume “backup complete” means “full-resolution backup complete.” The two things aren’t the same and nothing in the app tells you otherwise.
The tell-tale signs in an audit:
- Modern rear-camera iPhone photos (iPhone 5s and later) sitting at exactly 1536x2048
- Average file size around 0.89 MB for photos that should be 1.4 to 3.7 MB
- A cluster of affected uploads all landing on the same date: your initial sync day
- HEIC format but wrong dimensions (the optimized copy is HEIC too, not a JPEG thumbnail, so format alone doesn’t help you here)
If you see a batch of recent phone photos at exactly 1536x2048 and they all uploaded on your Immich deploy day, you hit the same trap.
How to Audit Your Own Library
You don’t need to do a full database query if you don’t want to. A few spot checks in the Immich UI will tell you something.
Pick 10 to 15 recent photos from your phone. Photos you know were shot on the main rear camera in the last year or two. Open each one in Immich, pull up the info panel, and look at the dimensions. If you have a current iPhone and those photos are showing 1536x2048, you have a problem. If they’re showing 4032x3024 or similar, you’re fine.
For a more systematic check, you can query the Immich database directly if you’re comfortable with Postgres. The asset_exif table has exif_image_width and exif_image_height columns. Filter for Apple-origin assets from recent years with a max edge at or below 2048px. Group by capture date and upload date: the signature is a cluster of recent captures that all uploaded on the same day as your initial Immich deployment.
The point is: actually check. Don’t count on the app to tell you.
The Fix for Photos Already Affected
The short version: the affected photos need to be re-pulled from iCloud at full resolution and re-uploaded to Immich.
On iPhone, go to Settings > Photos > set it to “Download and Keep Originals.” Wait for iCloud to finish syncing originals to the device. This can take a while on a large library: watch the sync indicator in the Photos app. Once it’s done, delete the reduced copies from Immich (filter by the date range of the affected batch), then re-upload from the Immich iOS app.
On Mac, there’s a cleaner workflow that doesn’t require the phone. Use osxphotos to export originals from your Mac Photos library (with --download-missing to pull from iCloud on demand) and immich-go to upload the resulting folder to Immich. This lets you verify dimensions on disk before anything touches your server. Export a batch, run sips -g pixelWidth -g pixelHeight on a few files to confirm you got 4032x3024 back, then upload. Evict the batch folder when done to keep disk usage in check.
The important sequencing note: re-upload the full-res copies first, verify they’re in Immich, then clean up the old reduced copies. Don’t delete the reduced assets until the replacements are confirmed. Run the operations in that order.
The Right Architecture Going Forward
Here’s the reliable approach, once you’ve dealt with the initial sync problem.
For phone-native shots (photos you take with your phone camera, transferred to nowhere else), the Immich mobile app works fine. As long as the photo is freshly shot and lives on the device, not yet offloaded to iCloud optimization, the app reads the original. Shoot a photo, let the app back it up that day or that week, and you’re fine. The iCloud optimize trap mainly bites on bulk initial syncs and on older photos that iCloud has already offloaded.
For real cameras (DSLR, mirrorless, dedicated action cameras) treat the memory card as your source of truth and go to Immich directly. Pull the card, drag the files into Immich via the web UI or the desktop client, done. Don’t import to Apple Photos first and then let Immich source from Photos. That path goes through iCloud and you get the same optimize-storage risk.
Same principle applies if you have old photo libraries sitting in iCloud. Exporting from iCloud to local files first, then uploading to Immich, is safer than using any intermediary that reads from the Photos library on an optimized Mac. You want the path from original-file-on-disk to Immich to be as direct as possible.
The general rule: Immich should read from files on a local disk, not from an app that may or may not have the original loaded. When in doubt, go disk-to-server.
What This Means for Your Homelab Setup
I’m not saying Immich is bad. It’s genuinely good software and the correct choice if you want off Google Photos. I’m saying that “backup complete” isn’t the same as “backup verified.”
Every backup system requires periodic spot-checks. Immich is no different. After your initial sync, pull up 20 or 30 recent phone photos and check their dimensions. If everything is 12MP where you expect 12MP, you’re probably fine. If you find a cluster of 3MP shots from your initial sync date, you have some cleanup to do: but it’s fixable.
The iCloud optimize-storage setting is convenient. It keeps your phone from filling up. But it creates a gap between “what the phone knows about your photos” and “what the phone actually has on disk,” and that gap can quietly propagate into any backup system that reads from the device. Including your self-hosted one.
Build the habit of checking resolution on a sample. It takes two minutes. It’s the difference between a backup and a false sense of security.
If you haven’t set up Immich yet, the Immich Docker setup guide covers the full install from scratch.