Immich
Photo and video backup and library: automatic upload from the iOS and Android apps, a timeline, albums and sharing, and smart search, face and text recognition from a local machine-learning container. Fits households and small teams that want their photo library on their own server. The stack is the server, the machine-learning container, Valkey and Immich's own PostgreSQL with VectorChord.
Resources by load level
What the app itself needs at each level, next to what we recommend for a server that runs only this app.
| Level | What it means | App requirements | Recommended |
|---|---|---|---|
| LightEstimate | 1-2 users, up to 50 GB of originals (~15,000 photos), ~500 new photos and 1 GB of video a month; the documented minimum host. | 2 vCPU · 6 GiB RAM · 79.25 GiB disk | 2.52 vCPU · 8.7 GiB RAM · 100.798 GiB disk |
| MediumEstimate | A family of up to 6 users, up to 200 GB of originals (~60,000 photos and videos), ~2,000 new photos and 4 GB of video a month. | 4 vCPU · 8 GiB RAM · 264.25 GiB disk | 4.92 vCPU · 11.1 GiB RAM · 313.548 GiB disk |
| HeavyEstimate | Up to 15 users, up to 500 GB of originals (~150,000 assets), ~6,000 new photos and 12 GB of video a month; imports run for days. | 5.5 vCPU · 11.5 GiB RAM · 637.25 GiB disk | 6.72 vCPU · 15.3 GiB RAM · 742.498 GiB disk |
Recommended = app requirements + system baseline + safety headroom, under sizing policy 2026.10.0. Options stay at their defaults. “Estimate” means the sources give no number for that case, so it is worked out from them by the method stated under Components. How the numbers are built
Ready-to-run files
Support level Supported
Compose template from the official sources; not yet verified by a run.
Components
What each component needs at each load level, before baseline and headroom.
| Component | Light | Medium | Heavy | Sources |
|---|---|---|---|---|
| Immich server (API, web UI, jobs) (app) | 0.5 / 1.75 / 69 | 2 / 3.5 / 253 | 3 / 5 / 623 | [15][18][19][24][28] |
| Immich machine learning (CPU) (model-runtime) | — | — | — | |
| Valkey (job queue) (queue) | 0.25 / 0.25 / 0.25 | 0.5 / 0.5 / 0.25 | 0.5 / 0.5 / 0.25 | [2][12][15][18] |
| PostgreSQL 14 with VectorChord (Immich image) (database) | 0.25 / 2 / 8 | 0.5 / 2 / 9 | 1 / 4 / 12 | [15][30][31] |
How the estimates are worked out
- Immich server (API, web UI, jobs) · Light: RAM and vCPU: the documented minimum host (6 GB, 2 cores) minus the database (2 GB), Valkey and machine learning (Immich runs in 4 GB without ML, so ML ≈ 2 GB). Disk: image 1.612 GiB unpacked + 50 GiB originals × 1.2 (thumbnails and transcodes add 10-20%) + 14 daily database dumps of ~0.5 GiB (assumed 25% of the database) = 68.6, rounded up to 69 GiB; GB taken as GiB.
- Immich server (API, web UI, jobs) · Medium: The documented recommended host (8 GB, 4 cores) minus the database, Valkey and machine learning; the server gets most of the CPU because transcoding and thumbnails are its heaviest jobs. Disk: 1.612 GiB image + 200 GiB × 1.2 + 14 dumps of ~0.75 GiB = 252.1, rounded up to 253 GiB.
- Immich server (API, web UI, jobs) · Heavy: Beyond the documented recommendation: one more vCPU and 1.5 GiB for parallel uploads, thumbnails and transcoding (the FAQ names them the heaviest jobs). Disk: 1.612 GiB image + 500 GiB × 1.2 + 14 dumps of ~1.5 GiB = 622.6, rounded up to 623 GiB.
- Valkey (job queue) · Light: No upstream figure for Valkey. It holds only the job queue in memory (the official Compose gives it no volume), so a quarter of a vCPU and 0.25 GiB fit inside the documented 6 GB host. Disk: 44.8 MB compressed image × 3 = 128 MiB, rounded up to 0.25 GiB.
- Valkey (job queue) · Medium: More users upload at once, so the queue holds more jobs: twice the light share, still inside the documented 8 GB host. Disk: the 128 MiB image, no volume.
- Valkey (job queue) · Heavy: As medium: the queue holds job ids and small payloads, not media, so it grows little with the library. Disk: the 128 MiB image.
- PostgreSQL 14 with VectorChord (Immich image) · Light: RAM: the documented 2 GB the database needs under resource limits (the image sets shared_buffers 512 MB, work_mem 16 MB). Disk: image 0.711 GiB unpacked + 2 GiB data (docs: typically 1-3 GB) + 5 GiB WAL (max_wal_size 5GB in the image) = 7.7, rounded up to 8 GiB.
- PostgreSQL 14 with VectorChord (Immich image) · Medium: RAM: the documented 2 GB. Disk: 0.711 GiB image + 3 GiB data (the top of the documented 1-3 GB) + 5 GiB WAL = 8.7, rounded up to 9 GiB.
- PostgreSQL 14 with VectorChord (Immich image) · Heavy: About 2.5 times the medium library, so twice the documented 2 GB to keep the asset, face and vector indexes cached, and one vCPU for search and nightly jobs. Disk: 0.711 GiB image + 6 GiB data (assumed to scale with the library) + 5 GiB WAL = 11.7, rounded up to 12 GiB.
machine-learning· Immich machine learning (CPU): RAM: the documented minimum is 6 GB with ML and 4 GB without, so 2 GiB; the default CLIP model alone peaks at 1,004 MiB, and idle models unload after 300 s. vCPU: one, as each model runs 2 intra-op threads and the FAQ warns 2-3 concurrent ML jobs can max a CPU. Disk: image 0.716 GiB unpacked + 0.74 GiB of default ONNX models (CLIP ViT-B-32 606 MB, buffalo_l 191 MB) + OCR models, rounded up to 2 GiB. Same at every load level.
Options that change resources
machine-learningRun the machine-learning container for smart search, faces, duplicates and text in photos. Off saves about 2 GiB of RAM (the docs run Immich in 4 GB without it); then also disable machine learning in Administration > Settings, and search and Explore work poorly.
Default: on
Ports
Public ports are meant to be reached from outside the stack, usually through a reverse proxy; internal ones stay on the stack's own network.
| Component | Port | Exposure | Purpose | Sources |
|---|---|---|---|---|
| Immich server (API, web UI, jobs) | 2283/tcp | Public, through a proxy | Web UI, REST API and mobile-app uploads (HTTP with WebSockets; put behind TLS) | [2][4] |
| Immich machine learning (CPU) | 3003/tcp | Internal only | Machine-learning API called by the server; unauthenticated | [17][22][24] |
| Valkey (job queue) | 6379/tcp | Internal only | Job queue between the server's workers (no password) | [13][17] |
| PostgreSQL 14 with VectorChord (Immich image) | 5432/tcp | Internal only | PostgreSQL connections from the server | [17][32] |
User and permissions (UID/GID)
The user each container's process runs as, and the paths it writes to. A bind mount for one of these paths must be writable by that UID:GID.
| Component | UID:GID | User | Starts as root | Writes to | Sources |
|---|---|---|---|---|---|
| Immich server (API, web UI, jobs)Derived | 0:0 | root | No | /data | [4][18][19] |
| Immich machine learning (CPU)Derived | 0:0 | root | No | /cache | [6][18] |
| Valkey (job queue) | 999:999 | valkey | Yes, prepares its directories, then drops to this user | /data | [13][14] |
| PostgreSQL 14 with VectorChord (Immich image)Derived | 999:999 | postgres | Yes, prepares its directories, then drops to this user | /var/lib/postgresql/data/var/run/postgresql/etc/postgresql | [11][32][33] |
- Immich server (API, web UI, jobs): The Dockerfile sets no USER and the image config has an empty User, so the server runs as root and never drops privileges; the FAQ shows how to set a non-root user. It writes originals, thumbnails, encoded video, profile images and database dumps under /data.
- Immich machine learning (CPU): No USER in the Dockerfile, so the Python service runs as root. It downloads models to MACHINE_LEARNING_CACHE_FOLDER=/cache (and the Hugging Face cache under it).
- PostgreSQL 14 with VectorChord (Immich image): Immich's image is built on the official PostgreSQL 14 image: its entrypoint copies the SSD or HDD config to /etc/postgresql as root, then the official entrypoint chowns PGDATA and switches to postgres (999).
Storage growth
How much each component's data grows per month at each load level, on top of the disk in the profile. A value marked Assumption is ANAROQ's stated assumption, not a figure from the sources; the notes say what it rests on.
| Component | Light | Medium | Heavy | Sources |
|---|---|---|---|---|
| Immich server (API, web UI, jobs)Derived | 3 | 12 | 35 | [15][19][24] |
| PostgreSQL 14 with VectorChord (Immich image)Assumption | 0.05 | 0.1 | 0.25 | [15] |
What the growth figures rest on
- Immich server (API, web UI, jobs): New photos at an assumed 3 MB each plus the level's video, × 1.2 for thumbnails and transcodes (docs: +10-20%): light (500 × 3 MB + 1 GB) × 1.2 ≈ 2.9, medium (2,000 × 3 MB + 4 GB) × 1.2 ≈ 11.5, heavy (6,000 × 3 MB + 12 GB) × 1.2 ≈ 34.5 GiB, rounded up. Immich never deletes originals on its own; trash is emptied after 30 days.
- PostgreSQL 14 with VectorChord (Immich image): Immich gives no growth rate, only that the database is typically 1-3 GB. ANAROQ assumes it grows with the asset count (metadata, CLIP embeddings, faces) by a few tens of KB per new asset.
Upgrade and rollback
How to move to a new version safely, and how to go back if it fails.
Back up first
Create a database dump first (Administration > Job Queues > Create Database Dump, or pg_dump of the immich database) and have a current copy of the library, upload and profile folders of the upload volume. [19][21]
Upgrade steps
- Read the release notes of every version you skip, and update the mobile apps first: the server only works with apps of its own major version. [21]
- Set the same new tag on the server and the machine-learning image; keep the database image unless the release notes change it. [2][17][18]DerivedUpstream sets both images from one IMMICH_VERSION; the FAQ warns that a PostgreSQL major upgrade is more than changing the image.
- Run docker compose pull && docker compose up -d. Migrations run at startup. [17][21]
Roll back
Downgrades are not supported, even within a minor version. To go back, run the old tags on a fresh database and restore the dump taken before the upgrade (onboarding restore or psql), with the same files in the upload volume. [19][21]
Known breaking changes
- In 3.0.0: The machine-learning container on amd64 needs an x86-64-v2 CPU (most CPUs since ~2012; pick a matching CPU type in a VM). The server works only with mobile apps of major version 3. [15][21]
- In 2.5.0: Database backup and restore changed: backups made before 2.5.0 are restored with the instructions of their own docs version. [19]
- In 1.133.0: VectorChord replaced pgvecto.rs in the database image. After the switch, do not go back below 1.133.0, and restore newer backups only into an image with VectorChord. [21]
Limits
- Immich needs at least 6 GB of RAM and 2 cores (8 GB and 4 cores recommended); with machine learning off it runs in 4 GB. On amd64 the machine-learning container needs an x86-64-v2 CPU. [15]
- The first backup of a large library is the heaviest period: thumbnails, video transcoding and ML jobs run for every asset. Lower job concurrency and transcoding threads on small hosts; ML runs on the CPU here, with no GPU acceleration. [18]
- Keep the database on local SSD storage, never a network share; the photo library itself may live on a large disk. Immich must be served at the root of a (sub)domain, not on a sub-path. [15][20]
Security
- Serve Immich only over HTTPS from a reverse proxy that forwards Host and X-Forwarded-* headers, passes WebSockets, allows large uploads and 600 s timeouts. With a self-signed certificate, uploads and video in the mobile apps often fail: use a trusted certificate. [18][20]
- Never expose the machine-learning container, the database or Valkey: the ML API has no security measures at all and Valkey has no password. In this template they listen only on the stack's internal network. [17][22]
- The first user to register becomes the admin. Create that account right after the first start, before the URL is shared. [25]
Backup
- Back up both the database and the files. Immich writes a database dump to the backups folder of the upload volume every day at 02:00 and keeps 14; the dumps hold metadata only, never photos. [19][24]
- Copy the upload volume with your own backup tool (3-2-1 recommended). Only library, upload and profile are irreplaceable; thumbs and encoded-video can be regenerated by rerunning the jobs. Immich makes no file backup itself. [19]
- A database restore needs a fresh database and the same files in the upload volume as when the dump was taken; restore from Administration > Maintenance or from the onboarding screen. [19]
Latest release
- This profile was checked against
Immich 3.3.3
This profile was checked against the newest release.
- Checked on
- 14 Oct 2026
- State
- Checked within the last 90 days
- Where releases are published
- GitHub Releases
Newest stable git tag v3.3.3 on 2026-10-14 (git ls-remote; later tags are release candidates or none); its docker-compose.yml and the v3.3.3 server and ML images exist.
Version
- Profile status
- Published
- Checked against release
- Immich 3.3.3
- Profile version
- 1.0.0
- Figures verified
- 14 Oct 2026
- Catalog release
- 2026.10.10
- Sizing policy
- 2026.10.0
- Compose file
- Unverified
Project and alternatives
- Official site
- immich.app
- Source code
- github.com/immich-app/immich
- Alternatives
- PhotoPrismEnte Photos
Sources
- Docker Docs: Control startup order in Compose (pg_isready healthcheck, service_healthy) (Official docs · read 11 Oct 2026)
- immich repository: docker/docker-compose.yml at v3.3.3 (server 2283:2283, machine-learning, valkey/valkey:9, ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0, shm_size 128mb) (Official Compose · read 14 Oct 2026)
- immich repository: docker/example.env at v3.3.3 (UPLOAD_LOCATION, DB_DATA_LOCATION, DB_PASSWORD A-Za-z0-9 only, DB_USERNAME postgres, DB_DATABASE_NAME immich) (Official repository · read 14 Oct 2026)
- immich repository: server/Dockerfile at v3.3.3 (no USER, VOLUME /data, EXPOSE 2283, HEALTHCHECK immich-healthcheck) (Official repository · read 14 Oct 2026)
- immich repository: server/bin/immich-healthcheck at v3.3.3 (curl /api/server/ping on port 2283, expects pong) (Official repository · read 14 Oct 2026)
- immich repository: machine-learning/Dockerfile at v3.3.3 (CPU image, no USER, MACHINE_LEARNING_CACHE_FOLDER=/cache, HEALTHCHECK python3 healthcheck.py) (Official repository · read 14 Oct 2026)
- immich repository: machine-learning/scripts/healthcheck.py at v3.3.3 (GET /ping on IMMICH_PORT, default 3003) (Official repository · read 14 Oct 2026)
- immich repository: server/src/repositories/config.repository.ts at v3.3.3 (IMMICH_TRUSTED_PROXIES defaults to linklocal and uniquelocal) (Official repository · read 14 Oct 2026)
- immich-app/base-images: postgres/Dockerfile (pgvector/pgvector base + VectorChord, DB_STORAGE_TYPE=SSD, HEALTHCHECK healthcheck.sh every 5m, start interval 5s) (Official repository · read 14 Oct 2026)
- immich-app/base-images: postgres/healthcheck.sh (pg_isready, then fails on any data-checksum failure) (Official repository · read 14 Oct 2026)
- immich-app/base-images: postgres/immich-docker-entrypoint.sh (copies the SSD or HDD config, then runs the official docker-entrypoint.sh) (Official repository · read 14 Oct 2026)
- Docker Hub: valkey/valkey tag 9.1.2 (linux/amd64 44,768,058 B compressed; the digest pinned upstream is a 9.1.2 build too) (Official repository · read 14 Oct 2026)
- valkey-io/valkey-container: 9.1/debian Dockerfile (VALKEY_VERSION 9.1.2, valkey uid/gid 999, WORKDIR /data, EXPOSE 6379, valkey-cli) (Official repository · read 14 Oct 2026)
- valkey-io/valkey-container: 9.1/debian docker-entrypoint.sh (chown of /data, then setpriv to valkey) (Official repository · read 14 Oct 2026)
- Immich Docs: Requirements (RAM minimum 6 GB, recommended 8 GB; 4 GB with ML disabled; CPU 2 / 4 cores; thumbnails and transcodes +10-20%; database 1-3 GB, at least 2 GB RAM) (Official docs · read 14 Oct 2026)
- Immich Docs: Docker Compose install (recommended production method; start_interval needs Docker Engine v25) (Official docs · read 14 Oct 2026)
- Immich Docs: Environment variables (DB_* and REDIS_* defaults, IMMICH_PORT 2283 / 3003, MACHINE_LEARNING_MODEL_TTL 300 s, DB_STORAGE_TYPE) (Official docs · read 14 Oct 2026)
- Immich Docs: FAQ (disable machine learning; lowering CPU and RAM; 2-3 concurrent ML jobs can max a CPU; non-root user; ML workers out of memory) (Official docs · read 14 Oct 2026)
- Immich Docs: Backup and restore (daily database dumps in UPLOAD_LOCATION/backups, keep 14; back up library, upload and profile; restore from the UI or psql) (Official docs · read 14 Oct 2026)
- Immich Docs: Reverse proxy (forward Host and X-Forwarded-*, WebSockets, large uploads, 600 s timeouts, no sub-path) (Official docs · read 14 Oct 2026)
- Immich Docs: Upgrading (read release notes, docker compose pull && up -d; server only works with mobile apps of its major version; downgrades not supported; VectorChord since 1.133.0) (Official docs · read 14 Oct 2026)
- Immich Docs: Remote machine learning (the ML container has no security measures; it receives image previews and keeps nothing) (Official docs · read 14 Oct 2026)
- Immich Docs: Searching (CLIP models; default ViT-B-32__openai peak RSS 1,004 MiB, measured without acceleration) (Official docs · read 14 Oct 2026)
- Immich Docs: Config file (default ML URL http://immich-machine-learning:3003, CLIP ViT-B-32__openai, faces buffalo_l, OCR PP-OCRv5_mobile, database dump daily 02:00, keep 14) (Official docs · read 14 Oct 2026)
- Immich Docs: Post install (the first user to register becomes the admin) (Official docs · read 14 Oct 2026)
- Immich Docs: System settings (External Domain for shared links and emails) (Official docs · read 14 Oct 2026)
- immich repository: LICENSE at v3.3.3 (GNU AGPL v3) (Official repository · read 14 Oct 2026)
- GHCR manifest of ghcr.io/immich-app/immich-server:v3.3.3 (linux/amd64, anonymous token): 611,460,416 B compressed; layers decompressed and counted: 1,731,393,536 B (Measurement · read 14 Oct 2026)
- GHCR manifest of ghcr.io/immich-app/immich-machine-learning:v3.3.3 (linux/amd64, anonymous token): 271,038,696 B compressed; layers decompressed and counted: 769,134,080 B (Measurement · read 14 Oct 2026)
- GHCR manifest of ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0 (index digest bcf63357 as pinned upstream; linux/amd64): 205,280,433 B compressed; decompressed 763,875,840 B (Measurement · read 14 Oct 2026)
- immich-app/base-images: postgres/postgresql.ssd.conf (shared_buffers 512MB, work_mem 16MB, max_wal_size 5GB, wal_compression on) (Official repository · read 14 Oct 2026)
- docker-library/postgres: 14/bookworm Dockerfile (postgres uid/gid 999, PGDATA and VOLUME /var/lib/postgresql/data) (Official repository · read 14 Oct 2026)
- docker-library/postgres: 14/bookworm docker-entrypoint.sh (chown PGDATA as root, then gosu postgres) (Official repository · read 14 Oct 2026)
- PostgreSQL 14 documentation: 20.4 Resource Consumption (dynamic_shared_memory_type posix uses /dev/shm) (Official docs · read 14 Oct 2026)
- Hugging Face: immich-app/ViT-B-32__openai (ONNX textual 254,193,396 B + visual 351,613,724 B) (Official repository · read 14 Oct 2026)
- Hugging Face: immich-app/buffalo_l (ONNX detection 16,923,827 B + recognition 174,383,860 B) (Official repository · read 14 Oct 2026)