Immich is a self-hosted photo and video library that reproduces the Google Photos features you miss — timeline, face grouping, map view, smart search, and instant mobile upload. A full install idles around 3 GB of RAM, ingests tens of thousands of photos overnight, and gives you a library no one can reprice.
The reason Immich exists is that every other self-hosted photo option either treated photos as files — which misses the entire point — or stalled at a basic gallery with no search. Immich went the other way: it copied the Google Photos experience wholesale, including the machine-learning parts that make face search and natural-language “beach at sunset” queries work. That ambition is also why it is the one personal-cloud app you should size hardware for instead of assuming it will fit.
I migrated a decade of photos into it and I run it on the Proxmox host alongside the rest of the stack from the self-hosted personal cloud apps guide. This is the setup that actually works at household scale — the container stack, the storage split that keeps it fast, the migration path out of Google Photos, and the machine-learning tuning that turns a slug into something snappy. The official documentation at immich.app is the source of truth for version specifics; this is how I deploy and run it.
What Does Immich Actually Replace From Google Photos?
Immich replaces the timeline view, the people (face grouping) panel, the map view, the smart search box, shared albums, and the instant-upload mobile app — the five or six features that made Google Photos sticky. It does not replace Google’s printing service or its AI-powered “Memories” montages, but it covers the daily-use surface that keeps people locked in.
The mobile app is the keystone. Google Photos earned its dominance by backing up every photo the moment you took it, silently, so you never had to think about it. Immich ships a Flutter app for iOS and Android that does the same thing — background upload over Wi-Fi, cellular, or both, with a foreground notification so iOS does not kill it. Once that app is pointed at your server, the “did this photo back up” anxiety is gone, and you are using your own library exactly like the one you left. The web client gives you the timeline, the people panel, and the map; shared albums let a household see each other’s libraries with proper access controls.
What it does not try to be is a generic file sync. Photos are assets in a library, not files in a folder, which is why I do not recommend using a file-sync app like the ones in the Nextcloud vs Seafile vs OwnCloud comparison as a photo backend. A file sync sees a JPEG; a photo library sees a capture date, a location, faces, and a scene to index.

How Heavy Is Immich on Hardware?
Immich is the heaviest personal-cloud app in the stack by a comfortable margin, because the machine-learning container that powers face detection and smart search wants 2 to 4 GB of RAM on its own and pins a CPU core during a bulk ingest. A full stack idles around 3 GB and spikes higher when the ML container is processing a backlog; the database and thumbnail generation add their own load on top.
The honest sizing advice is to plan for the spike, not the idle. A four-core mini PC with 16 GB of RAM runs the whole stack including a 60,000-photo library without breaking a sweat day-to-day, but the first ingest after migration is a different animal — the ML container will work through every photo, extracting face embeddings and CLIP vectors for smart search, and that pass is CPU-bound and takes hours. A GPU accelerates it dramatically (the ML container supports CUDA), but Immich runs fine on CPU if you are patient and let the first pass run overnight.
Storage is where people underbuy and regret it. A family photo library passes a terabyte faster than you expect once you count phone photos, DSLR RAWs, and the 4K video clips modern phones produce. Immich also generates thumbnails and encoded preview versions of videos, which adds roughly 10 to 15 percent on top of the original library size. My rule is the originals on the NAS over a wired link, and the database plus thumbnails on SSD on the host — the originals are big and sequential, the database is small and latency-sensitive, and splitting them gives you the best of both. A large NAS-rated hard drive for the library is the one upgrade I tell people not to defer.
As an Amazon Associate I earn from qualifying purchases.
The Containers Behind an Immich Install
An Immich install is not one program — it is a portfolio of containers coordinated by a Docker Compose file: the server (the API), the web frontend, the machine-learning service, a PostgreSQL database with the pgvector extension for vector search, a Redis cache, and a reverse proxy that ties them together under one hostname. Understanding which container does what is the difference between troubleshooting and flailing when something breaks.
The server container is the brain — it handles uploads, asset metadata, sharing, and the API the mobile app talks to. The web container serves the browser interface. The machine-learning container is the one that earns the RAM: it runs the face detection and recognition models and the CLIP model that powers smart search, turning “dog on a beach” into a vector similarity query against the database. PostgreSQL with pgvector stores those vectors and does the similarity search; Redis holds the job queue for background work like thumbnail generation and video encoding. The bundled proxy front-ends all of it so you expose one port, and in my setup I terminate TLS at my own Caddy reverse proxy in front of that.
One detail worth knowing: Immich moved its smart search from Typesense to pgvector, consolidating search into the database rather than a separate search engine. That is the kind of architectural change that makes pinning your version and reading release notes before updating worth the five minutes — a blind update mid-backlog can change how search behaves. I pin the image tags in my Compose file and update deliberately, never on a schedule I did not choose.
Where Should the Photo Library Live — SSD or NAS?
The originals belong on bulk storage (the NAS) and the database and thumbnails belong on SSD, because the workload splits cleanly into large sequential reads on one side and small random reads on the other. Getting this backwards — putting the database on slow spinning disk, or the originals on a small SSD you fill in a month — is the most common Immich performance complaint.
In my deployment, the Immich server container runs in an LXC on the Proxmox host, the upload and original-library volume is an NFS mount from the NAS on its own storage segment, and the PostgreSQL data directory and the thumbnail cache live on a local SSD. That split means a scroll through the timeline (which hits thumbnails and the database) is instant, while a full-resolution download (which hits the originals) streams from the NAS at wire speed. The NAS is on its own segment behind the OPNsense firewall with an allow-listed path from the LAB VLAN, so the photo library is reachable by the app and by nothing else.
The mistake I made here cost me a weekend. I let the library live on a single drive with no redundancy early on, and when that drive started failing during a thumbnail-generation pass — I could hear it clicking through the case before the SMART stats even confirmed it — I spent two days rescuing files before they were lost. Now the library sits on the NAS with ZFS snapshots and offsite replication, and I treat the photo volume as irreplaceable — because it is. The NAS as a home server guide covers the storage layer that makes this safe.

How Do You Migrate a Google Photos Library In?
The migration path is Google Takeout for the export and a bulk-upload tool for the ingest — expect the export to take Google days to prepare and the first ingest to pin your CPU overnight while the ML container processes every photo. It is not a one-click move, but it is a reliable one, and you only do it once.
Start with Google Takeout, requesting your Google Photos content with the originals and the metadata. Google delivers a set of archive files, and the JSON sidecar files in those archives carry the capture dates, descriptions, and album associations that Immich needs to reconstruct the timeline faithfully. Do not strip them. For the ingest, a community tool like immich-go reads the Takeout structure, preserves the album grouping and the metadata, and pushes the assets into Immich through the API — which is the right way, because it lets the server handle thumbnail generation and ML processing in its normal pipeline rather than dropping raw files into a storage directory.
The part nobody warns you about is the ML backlog. The moment several years of photos land, the machine-learning container queues every asset for face detection, face recognition, and CLIP embedding extraction. On a CPU-only box this runs for hours; the library is usable immediately but search and face grouping populate progressively as the queue drains. I started the ingest before bed and it was done by morning, but a larger library on slower hardware can take a day or more. That is normal — let it run, do not restart the container, and the clusters fill in.
Machine Learning: Face Detection and Smart Search
The machine-learning container runs two distinct jobs: face detection and recognition (the people panel), and CLIP-based image embedding for smart search (the search box). Both are CPU-intensive on first run and cheap thereafter, and both are the reason Immich feels like Google Photos rather than a file browser.
Face detection finds faces in a photo; face recognition clusters those faces into people and lets you name them. Smart search works differently — it runs a CLIP model that embeds each photo into a vector space, so a text query like “red car in snow” becomes a vector similarity search against every photo in the library. That is why you can search for concepts that appear nowhere in the filename or metadata. pgvector in PostgreSQL stores those vectors and does the similarity math, which is why the database is not optional and why its storage speed matters.
The tunable that bites people is the face recognition confidence threshold — set it too aggressive and Immich merges two different people; too conservative and one person fragments into five clusters. I set it once, named the obvious clusters, and let Immich suggest the rest. The model itself is the other variable: Immich ships different face and recognition models, and swapping one invalidates the existing clusters and forces a reprocess. I pin a model and do not change it unless I have a reason, because reprocessing 60,000 photos is an overnight job I do not want to repeat.

Reaching Immich From Your Phone Outside the House
Immich is built to be reached from a phone on cellular, which is the whole point of a Google Photos replacement — but the safe way to do it is WireGuard, not a forwarded port. The mobile app talks to your server over HTTPS, and you want that HTTPS to terminate cleanly without exposing the server to the open internet.
In my setup, Immich sits behind Caddy on the LAB segment, Caddy gets a real Let’s Encrypt certificate, and the hostname resolves to the server only when a device is on the WireGuard tunnel. A phone on cellular connects to WireGuard, gets a private address on the LAN, and the Immich app talks to the same hostname it uses at home — the DNS view is identical inside the tunnel and out. Nothing about Immich is port-forwarded; the home VPN and remote access guide and the Let’s Encrypt wildcard DNS-01 guide cover the substrate. If you are behind carrier-grade NAT and cannot host an endpoint, Tailscale gives you the same private reachability without a public IP.
One trap specific to photo apps: do not be tempted to expose Immich publicly so you can share an album link with a relative. Immich has a shared-link feature designed for exactly that, and it generates an unauthenticated link for the specific album — which is the safe way to share. Exposing the whole server so sharing “just works” hands the entire library to anyone who finds the hostname.
Backing Up the Library You Cannot Replace
A photo library is the one dataset in the personal cloud that is genuinely irreplaceable — files can be re-downloaded, passwords live in a vault with backups, but a decade of family photos exists in exactly one place once you delete Google’s copy. Back it up as if losing it would be a catastrophe, because it would.
My pattern is three layers. The live library is on the NAS on a ZFS dataset that snapshots hourly; those snapshots let me roll back an accidental deletion or a bad upload in seconds. The snapshots replicate to a second pool on the NAS for redundancy against a single drive failure. And the library replicates offsite, so a house-level disaster does not take the photos with it. Immich’s own database — the asset metadata, face clusters, and album definitions — is small and backs up with a pg_dump on a schedule, because rebuilding the ML indexes from the originals is an overnight job but rebuilding metadata you entered by hand is not. The monitoring stack watches the NAS pool and the replication jobs so I know the moment a backup stops running.
What I’d Do Starting Today
If I were standing up Immich fresh, I would put the server container and the ML container in LXC on the Proxmox host with 16 GB of RAM, mount the original-library volume from the NAS over NFS, keep the PostgreSQL data and thumbnails on local SSD, front it with Caddy and a real Let’s Encrypt cert, and reach it only over WireGuard. I would pin every image tag in the Compose file, migrate from Google Photos with Takeout and immich-go, and start the ingest before bed so the ML backlog clears by morning.
The discipline that makes Immich reliable is the same discipline that makes any self-hosted app reliable: pin versions, back up the database separately from the media, and never expose it publicly when a tunnel gives you the same access safely. Do that and the photo library that used to be a line item on a Google invoice becomes a thing you own outright, on hardware you control, behind a firewall whose rules you wrote. That is the entire reason to do this.
Does Immich need a GPU to run?
No. The machine-learning container runs on CPU and processes face detection and smart search fine; a first-time ingest of a large library takes hours overnight instead of minutes. A CUDA GPU accelerates the ML pass but is not required for daily use.
Can Immich automatically back up photos from my phone?
Yes. The Immich mobile app for iOS and Android uploads photos in the background over Wi-Fi or cellular the moment you take them, with a foreground notification so the OS does not kill it. This reproduces the silent instant-upload behavior of Google Photos.
How do I move my photos out of Google Photos?
Export your library with Google Takeout, keeping the JSON metadata sidecar files. Then ingest the archive with a community tool like immich-go, which preserves albums and metadata and pushes assets through the Immich API so thumbnails and machine learning process normally.
How much storage does an Immich library need?
Plan for the original photos plus roughly 10 to 15 percent for Immich-generated thumbnails and video previews. A family library passes a terabyte quickly once phone photos, RAWs, and 4K video are counted, so put originals on the NAS and keep the database and thumbnails on SSD.
Is it safe to expose Immich to the internet?
No. Reach Immich over WireGuard or a Tailscale overlay instead of forwarding a port. For sharing an album with someone outside the tunnel, use Immich built-in shared links, which expose only that specific album rather than the whole server.
Keep Building
- Self-Hosted Personal Cloud Apps: The Complete Guide
- Nextcloud vs Seafile vs OwnCloud for File Sync
- Vaultwarden: Running Your Own Bitwarden-Compatible Vault
- Proxmox Homelab Setup Guide: Build a Self-Hosting Platform
- Home VPN and Remote Access: The Complete Guide