If you run a self-hosted Immich server and your CPU spikes to 100 percent every time someone uploads a video, you are not alone. Learning how to enable hardware transcoding in Immich with VAAPI and NVENC is the single biggest performance upgrade you can make, and it takes about 15 minutes once you know the right steps.
I have set up Immich hardware acceleration on Intel N100 mini PCs, NVIDIA RTX systems, and AMD Ryzen builds. The process is the same at its core, but the details that trip people up are different for each platform. This guide covers all of them in one place.
Here is what you will learn: what hardware transcoding actually does in Immich, which API matches your hardware, the exact Docker Compose changes for NVENC, Quick Sync, and VAAPI, how to verify the GPU is really being used, and how to fix the common failures that leave people stuck.
One quick note before we start. Immich has two separate hardware acceleration features, and they are easy to confuse. Video transcoding acceleration (covered here) speeds up converting video files. Machine learning acceleration is a different feature with its own compose file, used for facial recognition and smart search. Both are worth setting up, but this article focuses on transcoding.
Table of Contents
Quick Start: Enable Hardware Transcoding in 4 Steps
If you just want the short version, here are the four steps to enable hardware transcoding in Immich. Detailed instructions for each step follow.
Download the hwaccel.transcoding.yml file. Grab the appropriate file from the Immich GitHub repo for your GPU backend (nvenc, quicksync, vaapi, or vaapi-wsl).
Edit your docker-compose.yml. Add the downloaded file to the
extendssection of theimmich-serverservice so Docker plumbs your GPU into the container.Redeploy the container. Run
docker compose up -dto recreate the server with the new configuration.Change the Admin setting. Open the Immich web UI, go to Administration, then Video Transcoding, and select your hardware acceleration API from the dropdown. Save.
Both steps 2 and 4 are required. Updating the compose file without changing the Admin setting does nothing. Changing the Admin setting without the compose wiring also does nothing. This paired dependency is the number one reason setups fail, according to community reports.
You do not need to redo existing transcodes after enabling hardware acceleration. Immich applies the new encoder to videos processed from that point forward.
Supported Hardware APIs in Immich
Immich supports four hardware transcoding APIs. Each one targets a specific GPU family, and you pick the one that matches your hardware.
NVENC for NVIDIA GPUs (GTX 1650 and newer, most RTX cards). Uses the fixed-function encoder on the GPU die.
Quick Sync (QSV) for Intel integrated GPUs and Intel Arc discrete GPUs. The best option for Intel N100, Alder Lake, and newer iGPUs.
VAAPI for AMD GPUs and as a generic Linux path for Intel iGPUs when QSV is unavailable. Covers Ryzen integrated graphics and Radeon cards.
RKMPP for Rockchip system-on-chip boards, including the Odroid M1 and compatible ARM single-board computers.
vaapi-wsl for running Immich inside Windows Subsystem for Linux 2 (WSL2) with Intel GPU passthrough.
If you have an NVIDIA card, use NVENC. If you have an Intel iGPU, use Quick Sync. If you have an AMD GPU, use VAAPI. The rest of this guide walks through each setup in detail.
Prerequisites by GPU Type
Each API has its own host-level requirements before Docker can access the hardware. Get these in place first, because most silent failures trace back to a missing prerequisite.
NVENC (NVIDIA) Prerequisites
You need the proprietary NVIDIA driver installed on the host, plus the NVIDIA Container Toolkit. Without the toolkit, Docker cannot see the GPU at all.
Install the NVIDIA Container Toolkit using your distribution’s package manager, then configure the Docker daemon with the NVIDIA runtime:
sudo nvidia-ctk runtime configure --runtime=dockersudo systemctl restart docker
Verify the GPU is visible to Docker by running docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi. If you see the GPU stats table, you are ready. If you get an error, your driver version and toolkit version are likely mismatched.
Quick Sync and VAAPI (Intel and AMD) Prerequisites
For Intel iGPUs and AMD GPUs, the host needs the /dev/dri device nodes to exist and be accessible. On most Linux distributions these appear automatically when the correct kernel driver is loaded.
Check that the devices exist by running ls -l /dev/dri. You should see at least card0 and renderD128. If /dev/dri does not exist, your GPU driver is not loaded or the kernel does not recognize the hardware.
For the Intel N100, Alder Lake N, Jasper Lake, and Elkhart Lake processors specifically, you also need to add group_add to your Docker Compose file. This is the fix documented in GitHub issue #14050, and it is not mentioned in the official Immich docs. Without it, both QSV and VAAPI fail silently on these chips.
Install intel-gpu-tools on the host so you can monitor GPU usage later with intel_gpu_top.
RKMPP (Rockchip) Prerequisites
For Rockchip boards, you need the Mali GPU driver and the MPP libraries installed on the host. The /dev/mpp_service and related device nodes must be present. This path is niche, so if you are running an Odroid M1 or similar, follow the board-specific instructions in the Immich documentation.
Full Setup: How to Enable Hardware Transcoding in Immich With VAAPI and NVENC
This section walks through the complete setup for each GPU type. Follow the section that matches your hardware.
Setting Up NVENC (NVIDIA)
Step 1: Download the hwaccel.transcoding.yml file from the Immich GitHub repository to the same directory as your docker-compose.yml:
wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml
Step 2: Open your docker-compose.yml and update the immich-server service to extend the nvenc profile. The service block should include:
services: immich-server: extends: file: hwaccel.transcoding.yml service: nvenc
Step 3: Redeploy the container:
docker compose up -d
Step 4: Open the Immich web UI. Click your profile in the top right, select Administration, then go to Settings and open Video Transcoding. Under Hardware Acceleration, select NVENC. Click Save.
That completes the NVENC setup. Jump to the verification section to confirm it is working.
Setting Up Quick Sync (Intel iGPU)
Step 1: Download the same hwaccel.transcoding.yml file to your Immich directory.
Step 2: Edit your docker-compose.yml and extend the immich-server service with the quicksync profile:
services: immich-server: extends: file: hwaccel.transcoding.yml service: quicksync
For Intel N100, Alder Lake N, Jasper Lake, and Elkhart Lake CPUs, add this to the immich-server service block to apply the group_add fix from GitHub issue #14050:
group_add: - "107"
The group ID 107 corresponds to the render group on most systems. Verify with getent group render on the host and adjust if your system uses a different GID.
Step 3: Redeploy with docker compose up -d.
Step 4: In the Immich Admin UI, set Video Transcoding hardware acceleration to Quick Sync and save.
Setting Up VAAPI (AMD and Intel)
VAAPI is the generic Linux path and works with both AMD GPUs and Intel iGPUs when you prefer it over Quick Sync.
Step 1: Download hwaccel.transcoding.yml if you have not already.
Step 2: Extend the immich-server service with the vaapi profile:
services: immich-server: extends: file: hwaccel.transcoding.yml service: vaapi
For AMD GPUs specifically, VAAPI is your only option since neither NVENC nor Quick Sync apply. The setup is identical to Intel VAAPI.
Step 3: Redeploy the container.
Step 4: In the Admin UI, select VAAPI as the hardware acceleration setting and save.
Setting Up VAAPI on WSL2
If you run Immich inside WSL2 on Windows with an Intel GPU, use vaapi-wsl instead of vaapi. The standard vaapi profile fails because WSL2 handles GPU passthrough differently.
Extend the immich-server service with service: vaapi-wsl from hwaccel.transcoding.yml, then select VAAPI in the Admin UI. Quick Sync is not available on WSL2.
Platform Variations
Unraid users: You do not edit docker-compose.yml directly. Instead, open the Docker tab, edit the Immich container, enable Advanced View, and add --device=/dev/dri to the Extra Parameters field for Intel or AMD. For NVIDIA, add --runtime=nvidia and the appropriate NVIDIA_VISIBLE_DEVICES variable. Then change the Admin setting as described above.
Single compose file method (Portainer): If you prefer not to use a separate file, you can inline the device mappings directly in your docker-compose.yml. Add devices: - /dev/dri:/dev/dri for Intel or AMD, or the NVIDIA runtime configuration for NVENC, directly under the immich-server service.
How to Verify Hardware Transcoding Is Actually Working
Enabling the setting does not guarantee the GPU is being used. Many users discover weeks later that transcoding was silently falling back to software. Here is how to confirm your hardware is actually engaged.
Verify NVENC With nvidia-smi
While a video is being transcoded in Immich (upload a test clip to trigger it), run nvidia-smi -l 1 on the host. This refreshes the GPU stats every second. Watch the encoder utilization column for the Immich container’s process.
If encoder utilization jumps above zero during transcoding, NVENC is working. One Reddit user described it perfectly: the container logs show NVENC encoding, and GPU usage bounces between 60 and 100 percent during processing.
If GPU usage stays at zero while a video transcodes, something is wrong. Check the NVIDIA Container Toolkit installation and the Admin UI setting.
Verify Quick Sync and VAAPI With intel_gpu_top
For Intel GPUs, install intel-gpu-tools and run sudo intel_gpu_top while a video transcodes. The Video Encode and Video Decode rows should show activity above zero percent.
For AMD GPUs, use nvtop or radeon_top depending on your driver stack. The encode engine activity confirms VAAPI is engaged.
Verify With Docker Logs
The Immich server logs explicitly report which encoder is being used. Run docker logs -f immich-server and trigger a video transcode. You should see log lines referencing NVENC, QSV, or VAAPI in the ffmpeg output.
Look for lines like SVT NVENC or h264_nvenc for NVIDIA, h264_qsv for Intel Quick Sync, or h264_vaapi for VAAPI. If you see only libx264 or libx265 in the logs, the GPU is not being used and transcoding is running on software.
Verify Through System Load
As a sanity check, watch your CPU usage with htop during a transcode. With hardware acceleration working, CPU usage should be modest (under 40 percent on most systems). Without it, a single transcode can pin one or more cores at 100 percent.
If CPU usage is high and GPU usage is zero, you have confirmed the problem. Work through the troubleshooting section below.
Troubleshooting Common Hardware Transcoding Failures
The same handful of problems account for nearly every failed setup reported on Reddit, GitHub, and the Unraid forums. Here is a map of errors to causes and fixes.
No /dev/dri Devices Found
If your container logs show that /dev/dri cannot be found, the GPU device nodes are not being passed into the container. This happens when the hwaccel.transcoding.yml file is not properly extended, or when the device path is wrong.
On the host, run ls -l /dev/dri to confirm the nodes exist. If they do, verify your docker-compose.yml extends the correct service from hwaccel.transcoding.yml. For Unraid, confirm --device=/dev/dri is in the Extra Parameters field.
If /dev/dri does not exist on the host, your GPU driver is not loaded. Install the correct driver for your hardware and reboot.
NVENC Not Detected on NVIDIA GPUs
If you have an NVIDIA GPU but transcoding falls back to software, the NVIDIA Container Toolkit is the usual culprit. Verify Docker can see the GPU with the test command in the prerequisites section.
Driver version mismatches between the host driver and the container toolkit also cause silent failures. Make sure both are on compatible versions. Older cards like the GTX 1050 Ti have particular trouble here, as reported in GitHub discussion #12544.
Also confirm the Admin UI setting is set to NVENC, not left on software. The compose wiring alone does not activate hardware encoding.
Intel N100: QSV and VAAPI Both Fail
This is the most common Intel-specific problem and the one that catches the most people off guard. On Intel N100, Alder Lake N, Jasper Lake, and Elkhart Lake processors, hardware transcoding fails with both QSV and VAAPI despite correct setup.
The fix is the group_add entry documented in GitHub issue #14050. Add group_add: - "107" (or your system’s render GID) to the immich-server service in docker-compose.yml. After redeploying, both QSV and VAAPI work.
WSL2: Using vaapi Instead of vaapi-wsl
WSL2 users who select the standard vaapi profile get device-not-found errors. WSL2 passes the GPU through a translation layer that requires the vaapi-wsl profile specifically. Switch your extends service from vaapi to vaapi-wsl and redeploy.
Gray Tiles or Videos Not Playing
If videos show gray tiles or fail to play after enabling hardware transcoding, the transcode may have failed partway through. Check the Immich server logs for ffmpeg errors. A common cause is selecting an incompatible constant quality (CQP) value or a codec the GPU does not support.
Try reprocessing a single video to isolate the issue. If it fails consistently, temporarily switch back to software transcoding in the Admin UI to confirm the source video is not the problem.
Hardware Transcoding Produces Larger Files
This is expected behavior, not a bug. Hardware encoders prioritize speed over compression efficiency, so the same quality setting produces larger files than software encoding. This catches many users off guard.
To reduce file sizes, use the CQP (constant quality) mode instead of a fixed bitrate, and select a slower preset if available. NVENC supports this well. Accept that hardware transcoded files will typically be 10 to 30 percent larger than software transcoded equivalents at similar visual quality.
Limitations, Larger Files, and Hardware Decoding
Hardware transcoding in Immich is powerful, but it has real limitations worth understanding before you commit to it.
Two-Pass Encoding Is NVENC Only
Two-pass encoding, which produces better quality at a given bitrate, is only available with NVENC. If you rely on two-pass mode, you need an NVIDIA GPU. QSV and VAAPI support single-pass encoding only.
CQP Mode for Intel Low-Power Chips
Jasper Lake, Elkhart Lake, and similar low-power Intel processors require CQP (constant quality) mode rather than a target bitrate. Immich handles this automatically when you select Quick Sync, but if you see quality issues, verify CQP is active in the transcoding settings.
VP9 Encoding Limitations
Hardware VP9 encoding support is limited across all APIs. If your source videos are VP9, expect software fallback for the encode step even with hardware acceleration enabled. H.264 and HEVC (H.265) are well supported by all backends.
Hardware Decoding (End-to-End Acceleration)
Transcoding involves two steps: decoding the source video and encoding the output. Hardware transcoding acceleration speeds up the encode step. You can also enable hardware decoding to accelerate the decode step, achieving end-to-end GPU acceleration.
To enable hardware decoding, check the hardware decoding option in the Admin UI under Video Transcoding. Immich uses the same GPU for both decode and encode when this is on. This further reduces CPU load and speeds up the entire pipeline, especially for HEVC and AV1 sources.
When Hardware Transcoding Is Worth It
Hardware transcoding is most valuable if you have a large video library (1000-plus clips), 4K source footage, or a low-power CPU that struggles with software encoding. The Intel N100, despite the group_add quirk, is an excellent transcoding chip for the price.
If your library is small (a few hundred short clips) and you upload infrequently, software transcoding may be fast enough that the setup effort is not justified. Run a test transcode in software first and see how long it takes. If it finishes in seconds, you may not need hardware acceleration yet.
Machine Learning Acceleration Is Separate
Do not confuse video transcoding acceleration with machine learning acceleration. ML acceleration uses a separate compose file (hwaccel.ml.yml) and targets CUDA (NVIDIA) or OpenVINO (Intel) to speed up facial recognition and smart search indexing. Setting up transcoding acceleration does not automatically accelerate ML tasks.
Frequently Asked Questions
How to enable hardware transcoding in Immich?
Download hwaccel.transcoding.yml, extend the immich-server service in docker-compose.yml with your GPU backend (nvenc, quicksync, or vaapi), redeploy the container, then select the same backend in Admin Settings under Video Transcoding. Both the compose change and the Admin setting are required.
Does Immich benefit from GPU acceleration?
Yes. GPU acceleration dramatically reduces CPU load during video transcoding and machine learning tasks. Users with large video libraries or 4K footage see the biggest benefit, with transcoding times dropping significantly and CPU usage falling from 100 percent to under 40 percent.
Does Immich transcode videos by default?
Yes. Immich transcodes uploaded videos to ensure browser-compatible playback. By default this uses software encoding on the CPU. Hardware transcoding offloads that work to the GPU when configured.
What hardware do I need for Immich hardware transcoding?
You need an NVIDIA GPU (GTX 1650 or newer for NVENC), an Intel iGPU with Quick Sync (N100, Alder Lake, or newer), an AMD GPU (VAAPI), or a Rockchip board (RKMPP). The host also needs the correct drivers and Docker GPU runtime configured.
How do I verify hardware transcoding is working in Immich?
Run nvidia-smi for NVIDIA or intel_gpu_top for Intel while a video transcodes. Watch the encoder utilization. Also check docker logs for the immich-server container for lines referencing nvenc, qsv, or vaapi. If you see libx264 instead, software fallback is active.
Why is hardware transcoding producing larger files in Immich?
Hardware encoders prioritize speed over compression efficiency, so files are typically 10 to 30 percent larger at similar visual quality. Use CQP constant quality mode and slower presets to reduce file sizes. This is expected behavior, not a bug.
Does VAAPI work on AMD GPUs in Immich?
Yes. VAAPI is the supported path for AMD GPUs in Immich. It is also the generic Linux option for Intel iGPUs when Quick Sync is unavailable. Download hwaccel.transcoding.yml and extend the vaapi service in docker-compose.yml.
Can I use VAAPI with NVIDIA in Immich?
No. NVIDIA GPUs use NVENC, not VAAPI. VAAPI is for AMD and Intel GPUs. For an NVIDIA card, select NVENC in both the hwaccel.transcoding.yml extends section and the Immich Admin UI.
Conclusion
Learning how to enable hardware transcoding in Immich with VAAPI and NVENC comes down to two paired steps: wire the GPU into the Docker container through hwaccel.transcoding.yml, then select the matching backend in the Immich Admin UI. Miss either one and nothing changes.
The details that cause failures are specific to your hardware. Intel N100 users need the group_add fix. WSL2 users need vaapi-wsl. NVIDIA users need the Container Toolkit installed and a compatible driver. Knowing which quirk applies to your setup saves hours of debugging.
Once it is working, verify it with nvidia-smi or intel_gpu_top rather than trusting the Admin UI dropdown. The logs do not lie, and the GPU utilization numbers confirm everything at a glance.
Your next step is to set up machine learning acceleration separately if you have not already. That uses hwaccel.ml.yml with CUDA or OpenVINO and speeds up facial recognition and smart search. With both transcoding and ML acceleration active, your Immich server will handle large libraries and 4K footage without breaking a sweat.