Immich RAM na disk: how much you really need
Immich document 6 GB RAM as minimum. See wetin server, Postgres, Redis and machine learning need, plus how to run Immich on 4 GB without guesswork.
Immich need how much RAM?
Immich dey ask for 6 GB RAM (random access memory) as the minimum wey dem document, and 8 GB as recommendation. E need 2 CPU cores for the low end and 4 for install wey go run comfortably. This figure cover the whole stack because Immich na four containers, no be one application. To browse library wey don already import no dey use plenty resources. Importing na where memory dey go, and most of am dey go one container wey you fit switch off.
Di data wey dey behind dis chart
[
{
"label": "Documented minimum",
"ram_gb": 6,
"cpu_cores": 2
},
{
"label": "Documented recommended",
"ram_gb": 8,
"cpu_cores": 4
}
]These figures na the ones Immich publish for the requirements page as of October 2026. Dem na sizing recommendation, no be check wey software dey perform when e start. Immich fit start with less. For smaller server, wetin change na which background jobs go finish and wetin import go do when memory finish.
One real hard limit dey. Since version 3, machine learning container for amd64 hosts need an x86-64-v2 CPU. This cover most processors wey dem sell since around 2012. The requirement na for that container, no be for the server. So, for older hardware, you fit switch machine learning off, run am for another machine as described below, or remain for v2.7.5, wey Immich docs name as the last compatible version.
If you never start the install, begin with the complete Immich install for VPS with Docker Compose and come back here to size the server.
Memory dey go where: four containers
The official Compose file dey start four services. Each one get different memory pattern, so one total number fit hide the useful part.
immich-server dey serve the web interface and API, and e still dey run the background job workers. Two workers dey inside that one container. api dey answer requests from browser and mobile app. microservices dey run the queues, including thumbnail generation and video encoding. The variables IMMICH_WORKERS_INCLUDE and IMMICH_WORKERS_EXCLUDE dey split those two into separate containers. Na so you fit give the noisy half its own memory limit without capping the half wey dey serve your photos.
database na PostgreSQL 14 image wey get VectorChord extension built inside. E dey hold all metadata and one search vector for each asset. The Immich docs give this service the only explicit minimum for the stack: if you apply Docker resource limits, the database need at least 2 GB. The same page talk say database suppose ideally dey on local SSD storage and never on any kind network share, because vector and index lookups na small random reads. Network volume go turn each lookup into a round trip. If plan choice depend on this, the difference between NVMe and SATA SSD storage for VPS matter pass for here than anywhere else for this stack.
redis dey run the Valkey image and hold the job queues. E small pass the other three by far, because e dey store job records instead of photo data.
immich-machine-learning na the service wey dey decide the size of your plan. E dey load models for smart search, face detection, and text recognition, and loaded model dey remain for memory. MACHINE_LEARNING_MODEL_TTL default na 300, so e go remove a model after five minutes without requests and read am again from the /cache volume when the next request come. During bulk import, five-minute gap no dey happen, so the models remain loaded from the first asset reach the last one.
Wetin dey change during import
When Immich dey idle, e quiet. Import na where small servers fit crash, because uploading one asset dey queue a chain of jobs, and several queues dey run at the same time.
Metadata extraction dey read the file header, and e light. Thumbnail generation heavier. Immich dey produce three thumbnail outputs for each asset: one blurred thumbhash placeholder, one WebP preview, and one JPEG thumbnail. E still produce one extra thumbnail for every face wey e detect. Each job dey decode an image, and job concurrency decide how many images dem go decode at once. Concurrency na the multiplier wey turn small cost for each job into cost across the whole server. Na why Immich FAQ call am the first thing to reduce for machine wey get limited resources. Set concurrency for the heavy queues to 1 under Administration, Settings, Job Settings.
Video assets add transcoding. Each transcode job na separate FFmpeg process with its own memory, and e go use every CPU thread wey you allow am.
Smart search dey send every new asset go the machine learning container to calculate one embedding vector. Face detection dey run a second model over the same image. During the first import of an existing photo library, both queues dey run over every asset wey you get, for hours. Na this be the worst time for memory for the whole installation, and e happen only once.
Why face and object recognition need the most RAM
Face handling na two jobs. Face detection dey run model for the machine learning container and find the boxes. Facial recognition then group those detections into people, and that step dey query the vector index for Postgres. So large library dey put pressure on both services one after another: model container when detection dey run, then database when grouping dey run.
Four settings dey change wetin machine learning container dey hold.
- The face model. Immich dey ship
buffalo_lby default, and FAQ dey recommendbuffalo_sfor small server. E na smaller model, so e dey use less memory and run faster, but accuracy fit reduce for small faces or faces wey turn sideways. - The worker count.
MACHINE_LEARNING_WORKERSdefault na 1. Each worker na separate process wey load im own copy of the models, so if you raise am to 2, resident model memory go roughly double. Leave am for 1 unless you get RAM wey you no dey use. - The batch size.
MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITIONdey limit how many faces dem fit process at once. Batch dey stay for memory together, so group photo with forty faces go use more memory pass portrait. - Which model types dey run at all. Smart search, face detection, and text recognition each load im own models. If you turn off the ones you no use under Administration, Settings, Machine Learning Settings, dem memory go comot permanently instead of only between imports.
You also get MACHINE_LEARNING_MODEL_ARENA, wey documentation describe as setting aside CPU memory early to prevent fragmentation, and e dey on by default. Change am last. The effect depend on the memory allocator underneath, so the only correct way to judge am na to monitor docker stats before and after.
Three tested profiles: 2 GB, 4 GB and 8 GB
Di data wey dey behind dis chart
[
{
"label": "2 GB VPS",
"server_limit_mb": 768,
"db_limit_mb": 768,
"ml_limit_mb": 0,
"redis_limit_mb": 128,
"notes": "machine learning container removed"
},
{
"label": "4 GB VPS",
"server_limit_mb": 1024,
"db_limit_mb": 1280,
"ml_limit_mb": 1024,
"redis_limit_mb": 192,
"notes": "machine learning on, job concurrency 1, buffalo_s"
},
{
"label": "8 GB VPS",
"server_limit_mb": 2048,
"db_limit_mb": 2048,
"ml_limit_mb": 2560,
"redis_limit_mb": 256,
"notes": "everything on at default settings"
}
]Take dem as limits wey you go type inside Compose, no be measurement of wetin Immich dey use. Limit na ceiling. E no reserve anything, and e no make service smaller. E decide which service kernel go kill when the box memory finish, and na better make you make that decision instead of leaving am to kernel own scoring.
The 2 GB box: remove the machine learning container
2 GB dey below the documented minimum of 6 GB, so na compromise be this and e good make we call am that. Comment out the whole immich-machine-learning service for docker-compose.yml, or leave am running and disable every model under Administration, Settings, Machine Learning Settings. Removing the container na the stronger option, because disabled model still leaves Python process resident.
You still get uploads, albums, sharing, mobile backup, thumbnails, and search by date, place and filename. You no go get search by description, automatic grouping of faces into people, and text recognition inside images.
The four limits add up to about 1.7 GB, leaving the host with roughly 300 MB. Note say 768 MB for the database dey below the documented 2 GB floor. Na exactly the compromise wey 2 GB force, and na why Postgres na the service wey kernel most likely go kill here.
Na the import go spoil first, no be browsing. Library wey get low tens of thousands of photos dey browse acceptably after e enter, because serving page na metadata query plus file read. Video-heavy import for the same box go use swap, because transcode and thumbnail queue need the memory at the same time. Set every heavy queue to concurrency 1 and add a swap file.
The 4 GB box: machine learning on, one job at a time
4 GB na the smallest size wey make face and object recognition worth switching on. Limit the machine learning container to 0 MB, switch facial recognition to buffalo_s, and set job concurrency to 1 for thumbnail generation, face detection and smart search.
The first pass over existing library go run for many hours, and for large library e fit pass one day. Na CPU limit cause this, no be memory limit, so extra RAM no go make am finish faster.
Na the machine learning container go spoil first here during that first bulk pass. If you no set limit, e go grow while transcode job dey grow too, and kernel go kill the bigger one. Because e restart within seconds, docker ps -a go show say e Up with uptime wey short pass the other services, instead of Exited (137), and the queue go quietly dey further behind than when you last check am.
The 8 GB box: the documented recommendation
8 GB with 4 cores match wetin Immich recommend, and everything run with default settings: smart search, face detection, text recognition and transcoding, with default concurrency. Libraries wey pass one hundred thousand assets dey comfortable here, and pressure shift from memory to disk speed, because na vector index and metadata queries database dey handle all day.
Set the limits anyway. For box wey get enough room, limits stop one runaway queue from taking database down with am. If you dey compare the price with smaller options, wetin VPS really costs by memory tier usually make 8 GB plan the cheapest way to stop constant tuning.
Service per Compose limits dey cap memory
No edit docker-compose.yml for this. wget dey replace that file every time you upgrade. Put the limits for docker-compose.override.yml beside am, because docker compose dey merge am automatically.
services:
immich-server:
deploy:
resources:
limits:
memory: 1024M
immich-machine-learning:
deploy:
resources:
limits:
memory: 1024M
cpus: '1.5'
database:
deploy:
resources:
limits:
memory: 1280M
redis:
deploy:
resources:
limits:
memory: 192Mdocker compose up -d
docker stats --no-streamdocker stats suppose don show your memory ceiling for MEM USAGE / LIMIT column instead of the host total memory. If the limit column still dey show the full host size, e mean say override file no enter: check the file name and run docker compose config to see the merged result.
Limit wey too low fit turn slow service to dead service, so increase am if container dey restart repeatedly. You fit read more about how e work for setting memory limits per service for Docker Compose, including why deploy dey work outside Swarm with Compose v2.
Sọ́ọ̀sì otu esi gbanyụọ ma ọ bụ kwagharịa machine learning container
Fun server wey small, ịkwagharịa container a gaa ebe ọzọ na-bụ mgbanwe kasị ukwuu wey ị nwere ike ime. Immich support ịgba ya na machine ọzọ. Mepụta file a na host nke abụọ. E nwere ike ịbụ desktop wey na-agbanye naanị na mgbede:
name: immich_remote_ml
services:
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
restart: always
ports:
- 3003:3003
volumes:
model-cache:docker compose up -d
curl -s http://localhost:3003/pingMgbe ahụ gaa Administration, Settings, Machine Learning Settings n'ime web interface. Pịa Add URL, tinye http://<host>:3003. Version wey dey hosts abụọ ahụ ga-abụrịrị otu, maka na Immich docs dọrọ aka na ntị say version mismatch n'etiti ha abụọ fit kpata bugs na instability.
Port a na-ebuga photos gị gaa machine nke ọzọ na-enweghị encryption. Ya mere, debe ya na private network ma ọ bụ gbaa ya site na WireGuard tunnel n'etiti hosts abụọ ahụ. Agaghị ekpughe 3003 na internet ma ọlị.
Ọ bụrụ na resident model container n'onwe ya bụ nsogbu, nke ahụ bụkwa ezigbo ihe mere ị ga-eji tụlee otu PhotoPrism na Immich si dị iche n'ihe ha na-agba mgbe ha nọ idle tupu ị họrọ plan size.
Disk space Immich library need na how much?
No be one multiplier fit work for every case, because four different things dey grow at four different rates. See the calculation for library wey get 50,000 photos and 500 short videos.
Di data wey dey behind dis chart
[
{
"label": "Originals: 50,000 photos at 4 MB",
"gb": 200
},
{
"label": "Originals: 500 videos at 120 MB",
"gb": 60
},
{
"label": "Thumbnails and encoded video at 15%",
"gb": 39
},
{
"label": "Postgres database",
"gb": 3
},
{
"label": "Machine learning model cache",
"gb": 2
}
]The 200 GB photos and 60 GB video na assumptions. Replace dem with your own averages before you buy anything, because video na the main thing wey decide this number: one minute of phone video bigger pass one hundred photos.
find /srv/immich/upload -type f -printf '%s\n' \
| awk '{n++; s+=$1} END {printf "%d files, %.1f MB average\n", n, s/n/1048576}'The 39 GB row na the only published ratio wey Immich provide: generated thumbnails and transcoded video add 10 to 20 percent to the library size on average. E be range because e depend on how many of your assets be video wey need re-encoding for browser compatibility. Library wey mostly get JPEGs go dey near the bottom of that range.
The database na 3 GB, and this one nearly be fixed cost. Immich document database files as typically 1 to 3 GB, because dem hold metadata and search vectors, no be pixels. The model cache na 2 GB, and e go grow if you enable several models or test different ones. The FAQ flag this volume as space consumer for exactly that reason.
The five rows add up to small pass 300 GB, so 500 GB volume leave room to grow, but 250 GB volume no go. Monitor the split with:
grep UPLOAD_LOCATION .env
du -sh /srv/immich/*Six folders dey under UPLOAD_LOCATION. upload and library hold the originals, thumbs hold previews and face thumbnails, encoded-video hold re-encoded copies, profile hold avatars, and backups hold automatic database dumps. Na only upload, library and profile no fit replace, because everything else fit regenerate from dem.
Two things dey surprise people. Deleted assets first go trash and keep their space until you empty the trash, so big cleanup no go free any space on the same day wey you do am. And database dump na metadata only, so e no get value without the files:
docker exec -t immich_postgres pg_dump --clean --if-exists \
--dbname=immich --username=postgres | gzip > /srv/backups/immich-dump.sql.gzCombine this with file level copy of the originals to somewhere outside the server. Na wetin restic backups from VPS go off-server storage dey for.
Transcoding CPU na e dey limit speed, no be RAM
Adding RAM no go make transcoding faster. Immich dey use FFmpeg, and for ordinary VPS, na CPU dey decode and encode every frame. Every FFmpeg process still dey keep buffers of decoded frames for memory. Na why the import section count transcode as separate memory cost. But CPU na e dey determine the speed. Even when hardware acceleration dey available, Immich documentation talk say by default na encoding only dey accelerated. So CPU still dey do decoding and tone mapping unless you also enable hardware decoding.
Hardware acceleration need the extra hwaccel.transcoding.yml Compose file plus one device wey you go pass through, using NVENC, Quick Sync, RKMPP or VAAPI. Most VPS plans no get any of these, so plan based on CPU.
The practical setting na thread count. Under Administration, Settings, Video Transcoding Settings, thread value of 0 mean all cores. This fit make one video freeze the web interface for 2 core plan. Set am to 1 or 2 there, as Immich FAQ suggest. This one go make transcode slow instead of making the whole service disruptive.
Why swap thrashing import dey look like hang
Na this failure people dey misread pass. When Immich run out of memory, two things fit happen, but na only one go look like failure.
Without swap, kernel go kill one process. Container go restart within seconds, so for browser, job queue go just pause, then continue. Evidence dey for docker ps -a:
docker ps -a --filter name=immich
docker inspect immich_machine_learning | grep -i oomkilled
sudo dmesg -T | grep -i -E 'out of memory|oom-kill'Exited (137) mean say process dem kill am with signal 9. 137 na 128 plus 9. You go only see this status while container dey stopped. Once restart policy don bring am back, docker ps -a go show Up again, and uptime wey short well-well compared with other Immich containers na the clue. Signal 9 by itself no prove memory problem, because Docker still dey send am when normal stop pass timeout. An OOMKilled value of true confirm say memory kill cause am, and once container don restart, the oom-kill lines from dmesg na the record wey you suppose trust.
With swap, nothing dey get killed and no error dey happen. Kernel go start moving pages go disk, import go slow by one order of magnitude, and web interface go stop answering within normal timeout. Every container dey run. Every health check fit still pass. E go look like hang, and people go reboot the box for this point. That one go lose queue progress and no change anything.
free -m
vmstat 1 5Non-zero values wey continue for si and so columns of vmstat mean say machine dey read and write swap continuously. Na this be the definition of thrashing. The free -m row for Swap used go dey increase at the same time.
Add swap anyway for 2 GB or 4 GB box, because slow import wey you fit diagnose better pass container wey die and you no fit diagnose:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabThen fix the cause. Reduce job concurrency go 1, limit the machine learning container, or remove am from this host. Swap go buy you time to do that. Swap no be the answer by itself.
FAQ
I fit run Immich for 2 GB VPS?
Yes, if you comment out the immich-machine-learning service for docker-compose.yml and set job concurrency to 1. This dey below the documented minimum of 6 GB, so treat am as known compromise. You still get uploads, albums, sharing, mobile backup, and search by date, place, and filename. You no go get search by description, automatic grouping of faces into people, or text recognition inside images. Add 2 GB swap file so import spike go slow the server instead of making container get killed.
Why my Immich import dey stop without error message?
Two different causes fit look the same from browser. Either memory kill one container and e don restart already; for this case, docker ps -a go show say e Up with suspiciously short uptime. (Exited (137) go only appear if you catch am while e dey stopped.) Or host dey use swap; for this case, every container still dey run, but everything just dey very slow. vmstat 1 5 go separate the two cases: steady non zero numbers for the si and so columns mean say system dey swap. Reduce job concurrency for thumbnail generation, face detection, and smart search for either case.
Wetin exit code 137 mean for Immich logs?
137 na 128 plus signal 9, so process get killed with SIGKILL. For Immich server, this usually mean memory limit: either the container own limit or the host run out of memory. But the code alone no prove am. Docker also sends SIGKILL when container no stop within its timeout, wey be 10 seconds by default for Linux. Check with docker inspect immich_machine_learning | grep -i oomkilled. A value of true confirms say kernel kill am because of memory. Then free -m plus sudo dmesg -T | grep -i oom-kill tell you whether na container limit or the whole host cause am. The machine learning container na the usual victim because e normally get the largest process.
How much disk space Immich need for each photo?
Plan for the original file plus 10 to 20 percent. Immich documentation say generated thumbnails and transcoded video increase library size by 10 to 20 percent on average. The database itself normally dey around 1 to 3 GB, even for large library. Video na wetin really determine your total size, so measure your own average file size before you choose plan. No just apply multiplier to photo count.
I need GPU for Immich?
No. Every part of Immich dey run for CPU. Graphics card fit make model inference for the machine learning container and video encoding faster, but neither one required. Most VPS plans no offer GPU. For hardware wey get CPU only, set transcoding threads to 1 or 2, use the buffalo_s face model, and make the first bulk import run overnight.