Tech Digest

Head to head

Immich vs PhotoPrism

Immich and PhotoPrism get compared constantly and solve different problems. This page separates them, then tells you which one your hardware can actually run.

Last reviewed 2 tools compared

Should you use Immich or PhotoPrism?

Choose Immich if the job is getting photos off phones automatically, and PhotoPrism if the job is searching an archive you already organized. Immich has maintained iOS and Android apps with real background upload and takes ownership of the files it stores; its documented requirement is 6 GB of RAM minimum and 8 GB recommended, most of it the machine learning container. PhotoPrism indexes an existing folder tree in place without moving anything, runs in two containers on about 3 GB plus swap, and has no first-party mobile app: phone upload means PhotoSync or WebDAV. If you need both jobs done, run Immich for capture and point PhotoPrism at the archive read-only.

These two get compared because they both show photos in a browser and both do faces. That is where the overlap ends.

Immich replaces the phone backup. Its centre of gravity is the mobile app: it uploads new camera roll items in the background, dedupes them, and owns the resulting file layout. PhotoPrism replaces the search you never had over an archive you already built. Its centre of gravity is originals/, a folder tree that exists before PhotoPrism does and stays exactly as you arranged it afterwards.

So the question is not which is better. It is whether your photos are currently trapped on phones or already sitting in a directory you are proud of.

What the spec table is telling you#

Look at three rows and ignore the rest. Services to run is 4 against 2, and that is the shape of the difference: Immich needs a pinned Postgres with a vector extension plus a Valkey job queue, PhotoPrism needs an app and MariaDB. Memory in use is 3500 MB against 2000 MB, and that gap is almost entirely machine learning. Identity says both do native OIDC, but PhotoPrism's extra user roles and the admin UI to manage them sit behind a paid membership.

SpecificationImmichPhotoPrism
LicenceAGPL-3.0 (Copyleft)AGPL-3.0 (Community Edition); default images ship under the PhotoPrism Plus License (Copyleft)
Written inTypeScript / Node.js, Python (machine learning), Dart (mobile apps)Go (backend), Vue (frontend), TensorFlow (models)
First release20222019
MaturityStableMature
DatastorePostgreSQL 14 with the VectorChord extension, plus Valkey/Redis for the job queueMariaDB 10.5.12+ recommended; SQLite supported for small libraries
Services to run42
Idle memory900 MB450 MB
Memory in use3500 MB2000 MB
Operational load3 / 5, Moderate2 / 5, Light
IdentityNative OIDCNative OIDC
arm64 buildsYesYes
Default ports22832342
Backup shapePostgres dumpMySQL dump

The row that flatters PhotoPrism most, operational load 2 against 3, is real and comes from one property: if PhotoPrism's index goes wrong, you delete it and reindex from originals that were never modified. Immich's database is not regenerable, because albums, faces, shared links and the mapping to files exist only there.

Which one gets photos off a phone#

Immich, and it is not close.

The iOS and Android apps are first-party, maintained, and do the thing people actually depend on: background upload, so the photo you took in a car park is on your server before you get home. It has an App Store and Play Store presence, which matters when you are asking a family member to install something once and never think about it.

PhotoPrism ships a PWA and documents PhotoSync as the phone-side path. PhotoSync is a good app and plenty of people run exactly that pairing. It is still a third-party dependency, it is a per-device purchase, and configuring WebDAV upload targets is not something you hand to a relative. The PhotoPrism comparison table lists "PWA & PhotoSync" for every tier, including the paid ones, so this is not a feature waiting behind money. It is a scope decision.

If you are migrating a household off Google Photos, Replace Google Photos walks the whole path, and Immich is the answer at the front of it.

What the machine learning actually costs in RAM#

This is where installs die, so here are the numbers.

Immich documents 6 GB of RAM as the minimum and 8 GB as recommended. A running single-household instance sits around 3.5 GB, and the immich-machine-learning container is most of that because it holds the CLIP model and the face recognition model resident between jobs. When that container exits with code 137 it was killed for memory, not bugged, and the symptom is confusing: searches return nothing and face jobs stall silently. Two knobs matter. MACHINE_LEARNING_WORKERS loads a full copy of the models per worker, so leaving it at 1 is the difference between 3.5 GB and 6 GB. IMMICH_MACHINE_LEARNING_ENABLED=false drops you to roughly a gigabyte and removes semantic search and face grouping, which is most of why people install Immich.

PhotoPrism asks for at least 3 GB of physical memory, RAM roughly matching core count, at least two cores, and at least 4 GB of swap. It uses TensorFlow on CPU for labels and faces, with no GPU path at all, and it disables TensorFlow automatically on hosts with 1 GB or less. The docs explicitly advise against hard container memory limits, because indexing RAW files and large panoramas temporarily needs more than steady state. On a NAS with a 2 GB cap, that is the failure: the index dies partway through and the library looks half-imported.

Practical translation. An 8 GB mini PC runs Immich properly. A 4 GB box runs PhotoPrism properly and runs Immich only with search turned off. If you are still buying hardware, Choosing home server hardware has the sizing, and Stack planner will add these figures to whatever else you plan to run.

Which one owns your files#

Immich takes ownership. Uploads land under UPLOAD_LOCATION/library/ in a layout Immich manages, and the database is what makes that layout meaningful. External libraries exist as read-only references if you want to keep an archive outside, but the primary workflow is Immich's own store.

PhotoPrism does not. It indexes originals/ in place, never modifies the files, and writes everything it derives into storage/. Your folder structure stays canonical. This is the correct answer for anyone with a decades-deep, hand-sorted tree who is not willing to hand it to a database.

Two traps sit on this line. First, PhotoPrism's import/ workflow is destructive in a way indexing is not: it moves files into originals/ under date-based naming and rewrites the structure they arrived in. Drop your archive in import/ to try it out and you have reorganized it. Second, storage/sidecar/ holds the metadata edits you made in the UI, so losing storage/ while keeping originals/ loses your work even though the photos survive.

Backups differ accordingly. Immich means pg_dumpall plus the library/ tree, restored database first, and the Postgres directory must be local disk rather than NFS or a mapped SMB share. PhotoPrism means originals/ plus docker compose exec photoprism photoprism backup -i -f, which writes a SQL dump into storage/ and keeps three by default. Backing up a running database covers why the dump matters more than the snapshot.

What happens on upgrade day#

Immich used to be the riskiest upgrade in self-hosting and mostly is not any more. Version 2.0.0 (1 October 2025) was the first stable release and brought semantic versioning: any 2.x mobile app talks to any 2.x server, so the ritual of reading release notes before every single pull is now only mandatory across majors.

Majors still bite. 3.0.0 (2 July 2026) removed pgvecto.rs entirely, so anyone whose instance predates 1.133.0 has to reach a VectorChord-capable version and let that migration finish first. The same release moved the amd64 machine learning image to an x86-64-v2 baseline, which strands older Xeons and Atoms on ML container version 2.7.5. And downgrades are unsupported even within a minor, because migrations run forward only at startup. The recovery path from a bad upgrade is the database dump you took beforehand, not the old tag.

PhotoPrism ships date-tagged releases (260728, 28 July 2026) and upgrades have historically been dull: pull, restart, reindex if asked. One thing to get right before the first start, because it cannot be changed later: MARIADB_PASSWORD is fixed once MariaDB initializes, and PHOTOPRISM_ADMIN_PASSWORD only applies when the admin account is created. Changing either in .env afterwards does nothing, which sends people hunting for a container that is not reading its environment. Reset the admin with docker compose exec photoprism photoprism passwd admin.

The licence detail nobody mentions#

PhotoPrism's Community Edition source is AGPL, but photoprism/photoprism:latest is built under the PhotoPrism Plus License with member extensions compiled in. The strictly AGPL build is the separate ce tag. Both are free to run. If your reason for self-hosting is a clean open source supply chain, the image you get by copying the quick-start compose file is not the one you want.

Membership is EUR 2/month for Essentials and from EUR 6/month for Plus. What it buys: extra User and Viewer roles, the admin web UI, 3D vector and satellite maps, unrate-limited reverse geocoding and SVG support. Faces, labels, RAW, video, WebDAV and OIDC are all in the free build. That makes multi-user PhotoPrism the paid case, which is worth knowing if the plan was one instance for a whole household.

Immich is AGPL-3.0 throughout with no paid tier and no gated features.

The verdict, by situation#

SituationPickWhy
Three phones, nobody wants to think about backupImmichThe only one with maintained first-party apps that upload in the background
400 GB of hand-sorted folders going back to 2004PhotoPrismIndexes in place, never touches your structure, and the index is disposable
4 GB of RAM on the whole serverPhotoPrismImmich without machine learning is Immich without the reason to run it
A pre-2012 CPUPhotoPrismThe Immich ML image needs x86-64-v2 and will crash on start
You want per-user libraries for a household, freeImmichPhotoPrism puts extra roles and the user admin UI behind membership
Strict open source supply chainEither, carefullyImmich is AGPL throughout; on PhotoPrism you must use the ce tag
Phone backup and a curated archive bothImmich plus PhotoPrism read-onlyImmich captures, PhotoPrism indexes the same originals
You already run Nextcloud and wonder if that is enoughRead Immich vs Nextcloud for photosNextcloud Photos is not in this class, and the page says why

What to do next#

Decide the question first, then install. If phones are the problem, start with Immich, give it 8 GB, put DB_DATA_LOCATION on an SSD, and do not raise MACHINE_LEARNING_WORKERS until you have watched memory under a full import. If an existing archive is the problem, start PhotoPrism with PHOTOPRISM_READONLY=true, point it at a copy of one year's photos, and time the first index before you unleash it on the whole tree.

Either way the originals need a backup that the photo app cannot reach, ideally on a different disk and a different schedule: see ZFS, btrfs, mdadm or one disk for where the files should live and An update strategy that does not lose data for how to take releases without losing a weekend. If sync rather than photo management is what you actually wanted, look at Syncthing and Syncthing vs Nextcloud instead. The rest of the category is in Photos and files.

Questions#

Can PhotoPrism back up photos from my phone?

Not with a first-party app. PhotoPrism ships a PWA and documents PhotoSync as the phone-side option, and that is true on the paid tiers too. PhotoSync works well and costs a one-off app purchase, but it is a third-party dependency and it is not the install-once-and-forget experience of the Immich app. If automatic background upload from several phones is your actual requirement, this is the deciding fact, not a detail.

How much RAM does Immich really need?

The docs say 6 GB minimum, 8 GB recommended, and a running instance typically sits around 3.5 GB. The immich-machine-learning container is most of it, because it keeps the CLIP and face recognition models resident. Each extra MACHINE_LEARNING_WORKERS loads a second full copy of the models, so raising it roughly doubles resident memory. You can set IMMICH_MACHINE_LEARNING_ENABLED=false and run in about 1 GB, but you lose search and face grouping.

Does PhotoPrism modify my original files?

Indexing does not: it reads originals/ in place and writes thumbnails and sidecars into storage/. Import does, and the two get confused. Import takes files from import/ and moves them into originals/ under PhotoPrism's own date-based naming, which rewrites whatever structure they arrived in. Mount your library as originals, leave import empty, and set PHOTOPRISM_READONLY=true if you want a hard guarantee.

Is Immich stable enough to trust now?

More than it was. Version 2.0.0 on 1 October 2025 was the first stable release and brought semantic versioning, so any 2.x app talks to any 2.x server and you no longer need to read release notes before every pull. Majors still break: 3.0.0 in July 2026 removed pgvecto.rs and raised the amd64 machine learning image to an x86-64-v2 CPU baseline. Downgrades are unsupported even within a minor.

Which one runs on a NAS or a Raspberry Pi?

PhotoPrism, more comfortably. Two containers, about 3 GB of RAM plus 4 GB of swap, and TensorFlow disables itself automatically at 1 GB or less. Immich runs on arm64 but wants 6 to 8 GB, needs its Postgres data directory on local disk rather than NFS or SMB, and only gets GPU acceleration on Mali via ARM NN or RK3576/RK3588 via RKNN. CUDA, OpenVINO and ROCm are x86-64 only.

Can I run Immich and PhotoPrism at the same time?

Yes, and it is a reasonable setup. Let Immich own the phone backup and its UPLOAD_LOCATION/library/ tree, then mount that tree into PhotoPrism as /photoprism/originals with PHOTOPRISM_READONLY=true. You get Immich's mobile apps and PhotoPrism's browsing over one set of originals. The cost is a second set of thumbnails and a second indexing pass, so budget the disk and do not let both write.

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.