I Moved 54,000 Photos to a Self-Hosted Library and It Nearly Melted My Server

Migrating a decade of personal photos from Mylio to Immich: the full story — duplicate hell, thermal shutdowns, and a nightly rclone backup that would later save everything.

May 2026
Immich
Self-Hosted
Home Lab
Part 1 of 2
01

Why Mylio Had to Go

Mylio had been the photo solution for years. Decent sync, cross-device, handled a large library without too much friction. Then it started doing the thing subscription software does when it gets comfortable — degrading quietly.

The Samsung S23 Ultra became a recurring problem. The Mylio app would go offline, silently. The fix was to reinstall — which triggered a re-sync that created duplicates and ghost entries. Do that a few times and your library starts looking like a horror movie. The same photo appearing twice, three times, dated differently, no clear canonical version.

Add the subscription cost on top of that and the math was simple. A self-hosted solution with full control, no app reinstall loop, and no monthly invoice was the obvious next move. Immich was the answer.

The Samsung kept going offline. The reinstall created duplicates. The duplicates required cleanup. The cleanup created more problems. The subscription kept charging. Time to leave.

02

What the Library Actually Looked Like

Before touching anything, it helped to understand the scale of the problem. This wasn’t a casual camera roll — it was a structured library going back to the early 2000s, sourced from multiple devices, exports, and backup drives over the years.

54k+
Original Photos
379 GB
Passport Drive Source
145k
Final Assets in Immich
387 GB
Final Library Size
2 days
Migration Duration
2003–2026
Date Range

The source was a Western Digital My Passport drive containing Mylio’s original file structure — 102,645 files including photos and XMP sidecar files going back decades. OneDrive and Google Photos 2026 exports added another 14,000+ assets on top of that.

03

The Stack

Immich runs on a home lab server called Bunty — an Ubuntu machine running CasaOS with Docker. The photo library lives on an attached external USB drive mounted at /mnt/external/immich/. Everything is on the local network with Tailscale for remote access.

Photo Library
Immich v2.5.3
Self-hosted photo management. Docker, port 2283.
Server
Bunty
Ubuntu, CasaOS, Intel IdeaPad. Home lab workhorse.
Storage
External USB Drive
Dedicated external drive, ext4, mounted at /mnt/external/.
CLI Tool
Immich CLI
Node.js upload tool. Year-by-year controlled ingestion.
Backup
rclone + GDrive
Daily sync to Google Drive. The thing that saved everything.
Source
My Passport I
WD external drive. 102,645 Mylio originals with intact EXIF.
04

The Migration — What Actually Happened

The plan was straightforward: transfer the originals from the Passport drive to Bunty, then use the Immich CLI to upload year by year. The reality involved a few hard-learned detours before getting there.

Problem
Mylio exports stripped EXIF data

Exporting from Mylio re-encoded JPEGs and removed DateTimeOriginal. Every photo landed in Immich with today’s date. 5,491 assets had to be deleted and re-ingested from originals.

Fix
Bypass Mylio — use the Passport originals directly

The original files on the WD Passport had intact EXIF. SCP’d 379 GB directly from the Passport to Bunty. 11.5 hour transfer. EXIF verified clean before uploading to Immich.

Process
Year-by-year CLI upload

Used the Immich CLI to upload one year folder at a time, verifying counts between each run. Caught and cleaned duplicates as they appeared rather than doing a single bulk import and sorting out the mess later.

Problem
OneDrive files had stripped EXIF too

1,893 OneDrive assets arrived with wrong dates. Built a tiered Python recovery script: folder name parsing recovered 242, filename pattern matching recovered 281. 1,322 were unfixable scans and hash-named exports.

Result
145,143 assets across the full date range

Photos from 2003 through 2026, correctly dated, fully ingested. XMP sidecar files automatically skipped by the CLI. Library integrity confirmed.

05

The Thermal Problem

After the upload completed, Immich needed to generate thumbnails for 145,000 assets. This is CPU-intensive machine learning work — face detection, thumbnail generation at multiple resolutions, blurhash generation. On an Intel IdeaPad running 24/7 as a home server, this created a temperature problem.

Running thumbnail generation and video transcoding simultaneously pushed core temps to 80°C. The system shut down. The jobs are resumable, so no data was lost, but it required a more disciplined approach to job scheduling.

// WARNING
Thermal ceiling on IdeaPad hardware: Thumbnail generation at concurrency 3 sustains ~73°C. Concurrency 1 holds ~62°C. Video transcoding is the heaviest single job — run it alone, overnight. Never stack thumbnail generation with video transcoding simultaneously.

The solution was sequencing. Thumbnails at concurrency 1 overnight. Face detection after thumbnails completed. Video transcoding as a solo overnight job. Slow but stable — and the jobs resume cleanly after any interruption.

145,000 thumbnails don’t generate themselves. They generate slowly, in order, at concurrency 1, while you sleep, so the server doesn’t shut itself off.

06

Setting Up the Nightly Backup

Once the library was stable, the backup pipeline went in immediately. The lesson from years of home lab work: the backup you set up after the disaster is the one you wish you had before it. This time, it went in first.

The approach uses rclone to sync the Immich library to Google Drive daily. A dedicated Google Cloud OAuth client was created to avoid severe API throttling — the default shared rclone credentials cap out around 13 KiB/s. With a dedicated client, sustained transfer speeds hit 8–9 MiB/s.

Tool
rclone sync to Google Drive

Source: /mnt/external/immich/library/ → Destination: gdrive:LAWNET_NETWORK_BACKUP/IMMICH_BACKUP/

Excludes
Regeneratable files skipped

Thumbnails, encoded video, and upload staging directories are excluded. Originals only. Saves significant storage and transfer time — the things that can’t be regenerated are the only things that matter.

Schedule
Daily at 02:20 AM via cron

Runs nightly on Bunty. Uses rclone sync — destination matches source. ntfy.sh push notification on completion or failure.

DB Backup
Immich’s built-in database backup

Immich generates daily .sql.gz DB dumps automatically. These land in the backup folder and get swept up by the rclone sync. Up to 14 daily snapshots retained.

After the initial 387 GiB sync completed, subsequent nightly runs take minutes — only changed and new files transfer. The GDrive backup became the silent insurance policy running in the background every night at 2 AM.

// NOTE
Create a dedicated Google OAuth client. Using rclone’s default shared credentials against a large library will hit API rate limits immediately. A dedicated Desktop app OAuth client in Google Cloud Console resolves this — free, takes 10 minutes, and the speed difference is dramatic.
07

What Worked

01
Always use original files, never app exports. Mylio’s export re-encodes and strips EXIF. The originals on the backup drive had everything intact. Always go to the source.
02
Year-by-year ingestion beats bulk import. Uploading one year at a time made it easy to spot problems, verify counts, and clean duplicates incrementally. A single 145k-file bulk import would have been a debugging nightmare.
03
Sequence your jobs under thermal load. The IdeaPad is not a rack server. Running multiple ML-intensive jobs simultaneously causes thermal shutdown. Thumbnails first, face detection second, video transcoding alone overnight.
04
Set up the backup before you need it. The nightly rclone sync to GDrive was configured as soon as the library was stable. This decision matters more than any other in this story — as Part 2 will demonstrate.
05
Immich is the right call. Active development, clean UI, solid API, mobile app with deduplication. For a self-hosted photo library, nothing else comes close at this point.
08

End State

Two days of migration work. A couple of thermal incidents, a Python EXIF correction script, and one very slow overnight thumbnail generation run later — the library was live. 145,000 assets, correctly dated, fully indexed, backed up nightly to Google Drive.

Immich replaced Mylio entirely. No subscription. No app reinstall loop. No duplicate ghosts. The S23 Ultra backs up automatically over the local network. The library is searchable, face-tagged, and mapped.

The backup ran every night at 2 AM without incident. For a while.

Part 2 is about what happens when the external drive dies mid-write, takes the database with it, and why that nightly rclone sync is the only reason this story has a good ending.

TechnoCoco — technococo.com — May 2026
Immich
Self-Hosted
Home Lab
rclone
Google Drive
Photo Library

A technical journey exploring self-hosted infrastructure, home automation, and the ownership of personal data. My Posts on building systems that work for you, not against you. Check out my main site @ Life of Bryan. A project in proving privacy is a myth. An integration experiment of my life.

Leave a Reply