PhotoPrism vs Immich: which photo server?
Two self-hosted photo servers compared: the real RAM floors, the phone apps, the maps, and the exact backup commands each one needs on a VPS.
PhotoPrism vs Immich: the short answer
PhotoPrism vs Immich is a choice between two different jobs, not two versions of the same product. Immich replaces Google Photos: a phone app backs up your camera roll automatically, and the timeline you get looks familiar to anyone leaving a phone gallery behind. PhotoPrism organises a photo library you already have: it indexes folders of files on disk, reads their metadata, puts them on a map, and leaves the files exactly where they were.
Pick Immich if the problem is "my phone is full and I want off Google Photos". Pick PhotoPrism if the problem is "I have 400 GB of photos on a drive and I cannot find anything in them". Both are open source, both run as Docker containers on a normal VPS, and both index and search your library without sending anything to a third party.
The philosophy split, and why it decides everything
Immich owns the files. You point it at an upload location, the phone app or the web uploader sends originals in, and Immich stores them under its own path with its own naming. The database holds the truth about albums, faces and search. That design is what makes the phone experience good, because the server always knows the full state of every asset.
PhotoPrism reads the files. You mount an originals folder that you already control, and PhotoPrism builds an index over it. Your directory tree stays yours. If you remove PhotoPrism tomorrow, the photos sit there in the same folders with the same names, and PhotoPrism will have written sidecar YAML files next to them describing what it learned.
That single difference explains most of the rest. Immich has strong mobile support because it controls ingestion. PhotoPrism has strong library curation because it never fights your existing structure. Immich is the better answer for a family whose photos live on phones. PhotoPrism is the better answer for an archive that lives on a disk.
Hardware appetite: Immich asks for more
The documented memory floors are far apart, and on a small VPS this is usually the deciding factor.
The data behind this chart
[
{
"label": "Immich",
"min_ram_gb": 6,
"recommended_ram_gb": 8
},
{
"label": "PhotoPrism",
"min_ram_gb": 3,
"recommended_ram_gb": 4
}
]Immich documents 6 GB of RAM as the minimum and 8 GB as recommended, with a note that a 4 GB machine can run it only with machine learning turned off. PhotoPrism documents 3 GB of physical memory and two CPU cores, and says the amount of RAM should match the core count.
The gap is real, and it comes from the machine learning container. Immich runs its models in a separate immich-machine-learning service that loads CLIP (contrastive language image pretraining) and face detection models into memory. On a 2 GB box the kernel kills that container, and you see it exit with code 137, which is what an out of memory kill looks like from Docker. PhotoPrism's TensorFlow models are smaller and it degrades instead of dying: on machines with 1 GB or less it disables RAW conversion and TensorFlow rather than crashing.
Both projects ask for swap. PhotoPrism's docs are explicit about wanting at least 4 GB of swap on the server. Add it before you install either one.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -hfree -h should now print a Swap: line showing 4.0Gi. If it prints 0B, then swapon failed, usually because the filesystem does not support fallocate, and sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 is the fallback. Container memory ceilings matter here too, and setting memory limits in Docker Compose is how you stop one hungry service taking the whole box down.
One more requirement catches people. Immich's Postgres database must sit on a normal Unix filesystem with real ownership and permissions, on local storage, never on a network share. PhotoPrism says the same thing about its database files. Neither app is safe to run with its database on a mounted object store.
How to install each one
Both installs are a vendor compose file plus one command. Set up Docker Engine and the Compose plugin first, as covered in our guide to Docker Compose on a VPS.
Immich publishes its compose file and an example environment file with every release.
sudo mkdir -p /opt/immich && cd /opt/immich
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.envEdit .env before starting anything. UPLOAD_LOCATION is where your originals will live, and DB_PASSWORD must be changed from the default using only the characters A-Za-z0-9, because special characters break the connection string. Then start it.
docker compose up -d
docker compose psThe web interface answers on port 2283. The first account registered through that page becomes the administrator, so reach it and register immediately rather than leaving an open instance sitting on the internet.
PhotoPrism ships one compose file that already includes MariaDB.
sudo mkdir -p /opt/photoprism && cd /opt/photoprism
wget https://dl.photoprism.app/docker/compose.yamlOpen compose.yaml and change PHOTOPRISM_ADMIN_PASSWORD before the first start. The docs are blunt about this: the app starts with whatever initial password is in that file, the minimum length is 8 characters, and the default value must never be used on a public server. Set the originals volume to the folder holding your photos at the same time.
docker compose up -d
docker compose logs -f photoprismPhotoPrism answers on port 2342 with the user admin. Neither app should be exposed directly. Put a reverse proxy with TLS (transport layer security) in front, the same shape of setup used for a self-hosted Nextcloud with Docker, TLS and backups.
Which one has the better phone app
This is where the two projects are furthest apart, and it is the reason most people end up on Immich.
Immich ships official apps for Android and iOS. They do background camera roll backup, which means new photos leave the phone without anyone opening anything. The app wants an HTTPS endpoint, so the reverse proxy is not optional if you plan to use it away from home.
PhotoPrism has no official native app. It ships a progressive web app, which you add to the home screen from the browser, and it documents WebDAV (web distributed authoring and versioning) as the way to sync from a phone. The project recommends a third party app called PhotoSync for this, pointed at the /import/ or /originals/ directory over WebDAV. It works, and it is a paid third party app doing a job Immich does inside its own client.
If automatic phone backup for several family members is the requirement, that settles it. Immich.
What the machine learning actually gives you
Immich does semantic search over your library using CLIP, so a query like "red bicycle in snow" finds photos nobody ever tagged. It also does face detection and clustering, and duplicate detection. Indexing a large import on CPU runs for hours in the background, which is normal and does not need a GPU (graphics processing unit).
PhotoPrism classifies images with TensorFlow into labels, detects faces and groups them into people, and reads location metadata to build a places map. The map is the feature people stay for: a library indexed by where it happened is a genuinely different way to browse twenty years of photos. Face recognition is included in the free Community edition. The paid Essentials and Plus memberships add extras such as richer map layers, more user roles and a user management interface, starting at a few euros per month as of July 2026.
Immich is fully free with no paid tier. PhotoPrism's core is free, with optional paid extras.
Backups decide whether you keep it
A photo server with no backup is one disk failure away from losing everything a family has. Both apps need two backups: the database, and the files.
For Immich, dump the database from the Postgres container and copy the upload location.
docker exec -t immich_postgres pg_dump --clean --if-exists --dbname=immich --username=postgres | gzip > /backup/immich-db.sql.gzThen back up UPLOAD_LOCATION. The folders holding irreplaceable data are upload, library and profile. The thumbs and encoded-video folders can be regenerated, at the cost of hours of CPU time. A database dump on its own restores nothing, because it holds only metadata.
For PhotoPrism, the index has its own command.
docker compose exec photoprism photoprism backup -i -fThat writes an SQL dump under storage/backup/. Then copy the originals folder and the storage folder. Because PhotoPrism also writes sidecar YAML files describing each photo, a lost index can be rebuilt from the files alone, which is a real advantage for an archive you plan to keep for decades.
Whichever you pick, send those backups off the server on a schedule with encrypted, deduplicated restic backups to remote storage. A backup living on the same disk as the library is not a backup.
Which one should you run
Run Immich if your photos are on phones, if more than one person needs to back up a camera roll, and if you can give the server 6 GB of RAM or more. It is the closest thing to Google Photos you can host yourself, and the mobile experience is the point. Our step by step Immich install guide covers the memory kills and the upgrade traps in detail.
Run PhotoPrism if you already have a photo archive on disk, if you care about maps and metadata and keeping your own folder structure, or if your VPS has 4 GB of RAM and you would rather have a working library than a swapping one. It is the better curation tool and it is gentler on small hardware.
Running both is also reasonable. Immich handles daily phone ingestion, and once a year you sort the keepers into your archive and let PhotoPrism index that. They do not conflict, because PhotoPrism reads folders while Immich owns its own.
FAQ
Can PhotoPrism and Immich share the same photo folder?
Not safely in both directions. PhotoPrism reads an originals folder and writes sidecar YAML files next to your images, while Immich expects to own the contents of its upload location. You can point PhotoPrism at a read-only copy of Immich's library folder to browse it, but do not let both apps manage the same files, because Immich's storage template can move or rename assets under PhotoPrism while it is indexing.
Is Immich stable enough to hold the only copy of my photos?
No self-hosted app should ever hold the only copy of anything. Immich ships breaking changes often, and a careless docker compose pull can leave the database unable to start, so pin your version and read the release notes before upgrading. Keep the original files backed up off the server and the risk stays small.
Why does the Immich machine learning container keep restarting?
It is being killed for using too much memory. Run docker compose ps and look for the machine learning service exiting with code 137, which is the kernel out of memory killer. Add swap, or give the container a memory limit so it is throttled rather than killed, or disable machine learning entirely on a 4 GB machine. Search stops working without it, and the rest of Immich runs fine.
Does PhotoPrism need MariaDB, or will SQLite do?
SQLite works and is fine for a personal library, but PhotoPrism caps itself at four workers when using it, and the docs recommend switching to MariaDB because it handles high concurrency better. The compose file the project ships already includes MariaDB, so the recommended path is also the default one.
How much disk space should I budget above my library size?
Add 10 to 20 percent on top of the size of your originals, for either app. That covers generated thumbnails and transcoded video previews. A 200 GB collection wants roughly a 300 GB volume once you leave room for the database, the local backup copy and growth.