FigJam Diagram: GPU Transcoding Architecture — k3s-agent-4 (expires 2026-04-13)
Intel UHD 630 (CoffeeLake-S GT2) via PCI passthrough on k3s-agent-4 — the cluster's sole active GPU node.
| Property | Value |
|---|---|
| Node | k3s-agent-4 (VM on pve4) |
| GPU | Intel UHD 630 (CoffeeLake-S GT2) |
| CPU | Intel i7-8700T (6 cores / 12 threads) |
| Device ID | 8086:3e92 |
| EU Count | 24 |
| Max Freq | 1100 MHz |
| Media Engine | Gen 9.5 |
| Node Label | gpu=intel-uhd-630 |
| Longhorn | Disabled (aging NVMe on pve4 host) |
| Passthrough | VFIO PCI passthrough, /dev/dri available in-pod |
Note: pve1/pve2/pve3 M920q hosts also have UHD 630 iGPUs but passthrough is not configured. See Scaling Options for enabling them.
Two workloads compete for the UHD 630:
| Workload | Scheduling | GPU Use | Priority |
|---|---|---|---|
| Jellyfin | preferredDuringScheduling affinity → k3s-agent-4 |
Real-time QSV transcode for active streams | User-facing |
| Plex | preferredDuringScheduling affinity → k3s-agent-4 |
Real-time QSV transcode for active streams | User-facing |
| Tdarr Worker | DaemonSet nodeSelector: gpu=intel-uhd-630 |
Batch background re-encoding | Background |
| Intel GPU Exporter | DaemonSet nodeSelector: gpu=intel-uhd-630 |
Metrics collection | Infrastructure |
| Codec | Decode | Encode | Max Resolution |
|---|---|---|---|
| H.264 (AVC) | Yes | Yes | 4096×4096 |
| H.265 (HEVC) 8-bit | Yes | Yes | 8192×8192 |
| H.265 (HEVC) 10-bit | Yes | Yes | 8192×8192 |
| VP9 8-bit | Yes | No | 8192×8192 |
| VP9 10-bit | Yes | No | 8192×8192 |
| AV1 | No | No | N/A |
| MPEG-2 | Yes | Yes | 2048×2048 |
| VC-1 | Yes | No | N/A |
| JPEG/MJPEG | Yes | Yes | 16384×16384 |
Note: AV1 decode requires 11th Gen+ (Tiger Lake). AV1 encode requires Arc GPUs (DG2+). This is relevant for Tdarr rules — don't target AV1 output on this hardware.
Based on community benchmarks with UHD 630 and Jellyfin:
| Scenario | Estimated Concurrent Streams |
|---|---|
| 4K HEVC → 1080p H.264 | 2–3 |
| 4K HEVC → 720p H.264 | 3–4 |
| 1080p H.264 → 720p H.264 | 5–8 |
| 1080p HEVC → 1080p H.264 | 4–6 |
| Direct play (no transcode) | Unlimited (network-bound) |
When Tdarr is actively batch-transcoding, real-time transcode capacity drops ~30–50%. Tdarr jobs should be scheduled for low-traffic hours (overnight).
Configure in Jellyfin Dashboard → Playback → Transcoding:
Tdarr runs as a Server Deployment + Worker DaemonSet. The worker lands on k3s-agent-4 via nodeSelector.
Recommended Tdarr rules for this hardware:
/dev/dri/renderD128) via intel-media-va-driver-non-freeAccess Tdarr at: https://tdarr.k3s.strommen.systems
Drivers installed on k3s-agent-4 as part of Ansible provisioning:
intel-media-va-driver-non-free
i965-va-driver-shaders
Pods using the GPU mount /dev/dri as a hostPath device. The media namespace service accounts have privileged: false but use device access via resource limits (not host PID).
| State | Estimated Power (M920q i7-8700T) |
|---|---|
| Idle (no transcode) | ~15W |
| 1× 4K HEVC transcode | ~25–30W |
| 2× 4K HEVC transcode | ~30–35W |
| Max QSV load | ~35–40W |
GPU utilization metrics exposed via intel-gpu-exporter DaemonSet on k3s-agent-4:
intel_gpu_video_engine_utilization — QSV video engine usage (%)intel_gpu_render_engine_utilization — 3D render engine (%)intel_gpu_frequency_mhz — current GPU frequencyGrafana: "Media Stack" dashboard → GPU panels
Alert: GPUTranscodeOverload fires when video engine utilization > 90% for 15 minutes
If concurrent transcode demand exceeds single UHD 630:
proxmox-gpu-prep.yml Ansible playbook + Terraform to configure VFIO on those hosts and rebuild their worker VMs. This would give 3–4 total GPU nodes. Jellyfin/Plex can't multi-GPU natively, but separate worker nodes would be assigned different Tdarr workers.