Skip to content
Bytearium

No ads or affiliate links active

Homelab & storage

Immich: hardware, storage and backup plan

Plan Immich before leaving Google Photos: RAM, machine learning, storage per library size and backup order, with dated prices against cloud plans.

Google Photos is a very comfortable closet. With Immich you build the closet yourself, including the floor, and you also keep the key to the spare closet in another house. This guide does the planning before the first photo moves.

The short answer

What does Immich need to run? The project's documentation names at least 2 CPU cores and 6 GB of RAM, and recommends 4 cores and 8 GB [1]. On 4 GB you can run it with machine learning switched off [1]. The database belongs on local SSD storage, never on a network share [1]. Plan the storage at about 1.1 to 1.2 times your original library, and plan about three times your library across server, local backup and offsite copy (our derivation, details below). The backup rule that matters: Immich's own database dumps contain only metadata, so you must copy the photo folders yourself, and the project recommends doing the database first and the files second [6]. We say below what that costs per year, with dates and sources, and where self-hosting does not save money.

How it works

  1. What actually runs. The compose file of release v3.3.5 starts four containers: the Immich server (web, API and jobs, port 2283), a machine learning container, a Valkey instance as job broker, and a PostgreSQL database with the VectorChord extension [3]. Machine learning (ML) means the models that read your photos: smart search by content (CLIP) and face detection [10][22]. The docs list the CLIP search as running on top of Postgres, which is why the database matters so much [10].
  2. Pin the version. The latest release we found on 25 Oct 2026 is v3.3.5 from 21 Oct 2026 [4]. The example .env file sets IMMICH_VERSION=v3, a tag that follows the current major version [2][5]. The compose file falls back to release if the variable is empty [3]. We would pin a full version such as v3.3.5 instead, because upgrades should be your decision. The project promises breaking changes only in major versions, requires the server to match the app's major version, advises you to upgrade mobile clients first, and does not support downgrades [5]. We did not pull the images ourselves; the tag format comes from the project's documentation and release list [2][4].
  3. CPU, RAM and where it runs. Besides the minimums above, the docs say Immich runs on amd64 and arm64, and that the ML container on amd64 needs the x86-64-v2 instruction level, which most CPUs since about 2012 provide [1]. A full virtual machine is fine. Docker inside an LXC container is not recommended, and non-Linux hosts are discouraged [1]. If you limit Docker resources, the database needs at least 2 GB of RAM [1].
  4. How much RAM the ML container eats. It depends on the model you pick. The default search model is ViT-B-32__openai [12]. In the project's own benchmark (7800X3D, bare metal, no acceleration, full precision) it peaks at about 1,004 MiB of RAM; larger models need roughly 3,000 to 6,600 MiB, for example 3,854 MiB for ViT-SO400M-16-SigLIP2-384__webli [10]. The benchmark excludes image decoding and the web server [10]. For the default face model buffalo_l [12] we found no memory figure, so we call it unconfirmed. Job concurrency defaults are low (smart search 2, face detection 2, thumbnails 3, video conversion 1) [12], and the docs warn against raising them beyond your CPU cores [13].
  5. Four ways to handle machine learning. (a) Run it on the same box on the CPU. This is the simplest option. The docs give no throughput numbers, so we make no speed claims. Test with a few hundred photos before you import everything. (b) Switch ML off if you have only 4 GB; you lose content search and face grouping [1]. (c) Move the ML container to a stronger machine. You add its URL in the settings, and if you add it rather than replace the local one, Immich falls back to the local container when the remote is down. The docs warn that image previews travel to that container and that it has no security measures, so keep it on a trusted LAN [9]. (d) Use a GPU. Supported backends are CUDA (NVIDIA, compute capability 5.2 or higher, driver 545 or newer), ROCm (AMD, with a 35 GiB image), OpenVINO (Intel GPUs, with more issues on integrated ones), ARM NN (Mali) and RKNN (Rockchip). The docs call this feature experimental and Linux-only (or Windows through WSL2) [8].
  6. Video is the second load. By default, videos are transcoded to a compatibility copy; the original stays [6]. The documented defaults are H.264 at 720p, only where needed [12]. Hardware transcoding (NVENC, Quick Sync, RKMPP, VAAPI) is possible, but the docs say it produces significantly larger files with typically lower quality, it is experimental, and the Raspberry Pi is not supported [11].
  7. Where the disks go. The database folder (DB_DATA_LOCATION) typically holds 1 to 3 GB and should be on local SSD [1]. The compose file has a switch for databases on hard disks [3]. The media folder (UPLOAD_LOCATION) wants a Unix-compatible filesystem with user and group ownership, such as ext4 or ZFS [1]. Our reading: an SMB share without Unix permissions is a risk for this folder, so test before you commit. On Windows hosts, NTFS is not accepted for the database [1].
  8. Storage math (our derivation). Thumbnails and transcoded video add about 10 to 20 percent to the library, according to the docs [1]. You can shrink that by lowering the 1440p preview size [13]. Call your original photos and videos L. The server needs about 1.1 to 1.2 times L plus 1 to 3 GB for the database. A local backup copy needs about L, because thumbnails and transcodes can be regenerated [6][7]. An offsite copy needs another L. That makes roughly 3.1 to 3.2 times L, before you count versioned history and growth. The first table after this list shows the numbers. Measure L from your Takeout download or your phone, not from guesses. During the move you need room for the Takeout archives as well. The community tool immich-go, which the Immich docs recommend for Google Takeout [14], reads ZIP files directly [16]. Its own planning checklist suggests about 1.5 times the source size as free space [15]. That is a third-party rule of thumb.
  9. What a backup must contain. Immich stores file paths and metadata in the database and does not scan the library folder, so database backups are essential [6]. The built-in job writes dumps into UPLOAD_LOCATION/backups, daily at 02:00 and keeping 14 by default. They contain no photos or videos [6]. The critical originals live in library, upload and profile. Thumbnails and encoded video are regenerated by jobs after a restore [6]. The docs state plainly that Immich does not back up the filesystem for you [6], and the project README opens with a 3-2-1 warning [17].
  10. Backup order. The documentation gives two safe ways. Stop the immich-server container while you copy, so nothing changes. Or, if that is not possible, copy the database first and the files second. Then the worst case is files the database does not know about. The reverse order can leave you with database entries whose files are missing [6]. The template script from the docs follows this order: it dumps the database into a folder inside the upload location and only then archives everything with Borg, excluding thumbs and encoded-video [7]. We do the same, and the dump is mandatory: the script writes it to /srv/immich/library/database-backup/immich-database.sql.gz before Borg starts. That way every archive, local and offsite, contains both the dump and the assets. Both docs pages use pg_dump, so there is no difference between them to work around [6][7]. The script starts with set -euo pipefail. If the dump or gzip fails, the script stops, and no archive is created. Without pipefail, a failed pg_dump could slip through the pipe and leave a broken file in an archive that looks fine. The template's setup uses --encryption=none [7]. For an offsite copy we would choose an encrypted repository instead and keep its key and passphrase separate from the backup itself; our guide on restic and Borg, listed under Related pages, covers keys. Rehearse the restore either way.
  11. Restore. From the web interface under Administration, Maintenance, you can restore a listed dump; Immich creates a restore point first and rolls back if the restore fails [6]. For a fresh install, the command-line restore needs a database that has never run: delete the database folder if the server has started. The docs mention that the process changed in v2.5.0 [6]. A dump from a different Immich version may need migrations [6].
  12. What it costs (our calculation, prices from 25 Oct 2026). Google's list prices, quoted on a Telekom shop page, are €2.99 per month for 200 GB and €9.99 per month for 2 TB, which that page sells as Google AI Plus [18]. Over five years that is €179.40 and €599.40. For the offsite copy, Hetzner lists a Storage Box with 1 TB at €3.81 per month including 19 percent VAT (€228.60 over five years) [19] and one with 5 TB at €12.97 per month (€778.20) [20]. Both support Borg and restic [21]. The wattages are our assumptions: a server that draws 10 W around the clock uses 87.6 kWh a year, one at 25 W uses 219 kWh. At 37.0 ct/kWh, the German household average for 2026 so far in BDEW's analysis of August 2026 [23][24], that is €32.41 and €81.03 a year, or €162.06 and €405.15 over five years. Replace the price with your own tariff. Hardware and disks are unconfirmed, because we did not compare models. The second table after this list sums it up. On these numbers, self-hosting with a rented offsite copy does not save money. A cheaper offsite copy, such as a disk at a relative's home, would change that, but we have no price for it. Google's plans also cover Gmail and Drive, and Immich does not replace those. Choose Immich for control, privacy and ownership, and budget for the work. If you also want files and not just photos in your own hands, the Nextcloud guide under Related pages compares self-hosting with renting.

Tables: storage and five-year cost (our derivation)

Disk space by library size, from the factors in steps 8 and 9:

Library LServer (1.1–1.2 × L)All three copies (3.1–3.2 × L)
100 GB110–120 GB310–320 GB
250 GB275–300 GB775–800 GB
500 GB550–600 GB1,550–1,600 GB
1,000 GB1,100–1,200 GB3,100–3,200 GB

Five-year cost before hardware and disks, from the prices in step 12 (power price 37.0 ct/kWh, the BDEW household average for 2026 so far [23][24]):

Five years, before hardware and disksCloud planSelf-hosted, 10 WSelf-hosted, 25 W
Library up to about 180 GB (Google 200 GB vs. 1 TB offsite box)€179.40€390.66€633.75
Library around 1.5 TB (Google 2 TB vs. 5 TB offsite box)€599.40€940.26€1,183.35

A homelab example

This is a generic setup for your own server, not a report on ours. We make no statement about Immich or photo hosting in the Bytearium homelab. Assume Linux with Docker, a small SSD at /srv/immich/postgres, a data disk at /srv/immich/library and a backup disk at /mnt/backup.

Download the two files as the docs describe [2]: wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml and wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env. Then edit .env:

UPLOAD_LOCATION=/srv/immich/library
DB_DATA_LOCATION=/srv/immich/postgres
IMMICH_VERSION=v3.3.5
DB_PASSWORD=<random, only A-Za-z0-9>
TZ=Europe/Berlin

Start with docker compose up -d and register the first user, who becomes the admin [2]. To test machine learning before the big import, upload a few hundred photos and open the job page.

For the backup, dump the database first with the command from the restore section [6], then copy the files:

#!/usr/bin/env bash
set -euo pipefail
mkdir -p /srv/immich/library/database-backup
docker exec immich_postgres pg_dump --clean --if-exists --dbname=immich --username=postgres | gzip > /srv/immich/library/database-backup/immich-database.sql.gz.tmp
mv /srv/immich/library/database-backup/immich-database.sql.gz.tmp /srv/immich/library/database-backup/immich-database.sql.gz
borg create --stats /mnt/backup/immich-borg::'{now}' /srv/immich/library --exclude /srv/immich/library/thumbs --exclude /srv/immich/library/encoded-video

The borg create line follows the exclude pattern of the docs' template [7]. Create the repository once with an encrypted mode, for example borg init --encryption=repokey-blake2 /mnt/backup/immich-borg, and keep the key and passphrase separate from the backup. The script writes the dump into /srv/immich/library/database-backup/immich-database.sql.gz first, so every archive contains dump and library together [7]. The offsite copy repeats the borg create against a remote repository, always after the dump has been written, so the offsite archive includes the dump too. On a Hetzner Storage Box, SSH runs on port 23 and you can choose the Borg version with --remote-path, for example borg-1.4 [21]. Because of set -euo pipefail, a failed dump or gzip stops the script before any archive is created.

Rehearse the restore on a second machine: install Immich with the same version in .env, move the backed-up folders into its upload location, and restore the dump with the command-line procedure from the restore section [6]. The web restore accepts .sql.gz files [6], but we did not verify that it accepts a dump made with our command. Check that photos open, not just that the list is there.

Checklist

  • Measure your library size in GB from the Takeout archives or the phone, and write down L.
  • Check that the host has at least 6 GB of RAM and 2 cores, or decide on ML off or remote ML.
  • Pin IMMICH_VERSION to a full version, and read the release notes before every upgrade.
  • Place the database on a local SSD, and keep it off every network share.
  • Pick a model deliberately, and compare its memory figure in the docs table with your free RAM.
  • Plan about three times L of disk across server, local backup and offsite, and add your growth.
  • Back up the database first and the files second, or stop the server container while you copy.
  • Exclude thumbs and encoded-video only if you accept regenerating them after a restore.
  • Encrypt the offsite repository, and store the key apart from the repository.
  • Restore on a second machine once, and write down the date and the result.
  • Compare costs with your own power price and dated provider prices, not with ours.

Primary sources

These sources are the basis of this page. That does not mean every claim was checked individually; whether a review record exists is shown above under “Status”. The interpretation and checklist are our own work.

There is no documented review record for this version yet. The text relies on the sources listed.

How this page was made: Bytearium creates these pages with the help of AI and is responsible for publishing them. AI can be wrong, so we show our sources and review status openly.

  1. Immich projectRequirements
  2. Immich projectDocker Compose [Recommended]
  3. Immich projectdocker-compose.yml at tag v3.3.5
  4. Immich projectv3.3.5
  5. Immich projectUpgrading
  6. Immich projectBackup and Restore
  7. Immich projectBackup Script
  8. Immich projectHardware-Accelerated Machine Learning
  9. Immich projectRemote Machine Learning
  10. Immich projectSearching
  11. Immich projectHardware Transcoding
  12. Immich projectconfig-file.md
  13. Immich projectSystem Settings
  14. Immich projectThe Immich CLI
  15. simulot/immich-gobest-practices.md
  16. simulot/immich-goupload.md
  17. Immich projectREADME
  18. Telekom DeutschlandGoogle One & Google AI
  19. Hetzner OnlineStorage Box BX11
  20. Hetzner OnlineStorage Box BX21
  21. Hetzner DocsAccess with SSH/rsync/BorgBackup
  22. Immich projectFacial Recognition
  23. BDEWBDEW-Strompreisanalyse August 2026
  24. BDEWStrompreisanalyse

This page has no ads and no affiliate links.