Manjaro on a laptop with both an Intel iGPU and an Nvidia dGPU (the typical "Optimus" setup) has one annoying default: the discrete card never fully sleeps. The driver itself idles down to power-state P8, but the PCI link stays at D0 forever, and the card keeps drawing a couple of watts even when nothing is using it. On battery, that's real. This guide turns on the missing piece — PCI runtime power management — so the dGPU actually reaches the lowest sleep state (D3cold, ~0 W). It also covers the right way to run an app on the dGPU on demand, and the wrong way that breaks on Wayland.
Who this is for: a Manjaro laptop using video-hybrid-intel-nvidia-prime (the mhwd profile installed automatically on Intel+Nvidia notebooks). Desktops with only an Nvidia card don't need any of this — there's no other GPU to fall back to.
Step 1: Confirm the mhwd profile
Check what mhwd installed and which driver each card is using:
mhwd --listinstalled
inxi -G # which renderer is active
If you see video-hybrid-intel-nvidia-prime in the list and inxi -G shows Intel as the active renderer with the Nvidia card present but idle, you're in the right setup. If mhwd --listinstalled shows the bare video-nvidia driver instead, that profile runs everything on the dGPU all the time — runtime PM doesn't apply to it.
Step 2: Verify the driver-side power-management knob
The Nvidia driver has a runtime-PM mode that has to be opted into via a module option. mhwd usually does this for you, but check:
grep -r NVreg_DynamicPowerManagement /etc/modprobe.d/ /usr/lib/modprobe.d/
You should see options nvidia NVreg_DynamicPowerManagement=0x02 somewhere. If it's missing, add it and rebuild the initramfs:
echo 'options nvidia NVreg_DynamicPowerManagement=0x02'
| sudo tee /etc/modprobe.d/nvidia-pm.conf
sudo mkinitcpio -P
Reboot afterwards so the new module option takes effect.
Step 3: Install the udev rule
This is the missing piece. Without it, Linux never tells the dGPU's PCI link that it's allowed to autosuspend. The rule flips power/control from on to auto on each Nvidia function as soon as its driver binds at boot.
Use sudoedit rather than a heredoc — pasting these long lines through a heredoc can silently line-wrap and quietly break the file. Each rule must be one physical line:
sudoedit /etc/udev/rules.d/80-nvidia-pm.rules
Paste these exactly six lines:
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", TEST=="power/control", ATTR{power/control}="on"
The three classes are the three PCI functions of a typical dGPU: 0x030000 is the VGA controller, 0x030200 is the 3D controller, 0x040300 is the HDA audio function that drives HDMI/DisplayPort audio.
Verify the file is exactly six lines — if it's more, your terminal wrapped one of them and the rule will silently not match:
wc -l /etc/udev/rules.d/80-nvidia-pm.rules
# expect: 6
Step 4: Reboot and verify
The rule fires on driver bind, which only happens at boot. Setting power/control=auto on an already-running device doesn't initialise Nvidia's runtime-PM machinery — you have to reboot.
After reboot, let the machine sit idle for ten seconds, then check four things:
cat /sys/bus/pci/devices/0000:01:00.0/power/control
# expect: auto
cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
# expect: suspended
cat /proc/driver/nvidia/gpus/0000:01:00.0/power | grep "Video Memory"
# expect: Video Memory: Off
nvidia-smi --query-gpu=pstate,power.draw --format=csv
# expect: P8, ~0 W (and nvidia-smi may refuse to talk to the card at all
# when it is suspended — that is the real success signal)
The Video Memory: Off line is the one that matters. runtime_status: suspended means Linux thinks the device is asleep; Video Memory: Off confirms the card actually reached D3cold rather than just driver-side idle.
One quirk: cat /sys/bus/pci/devices/0000:01:00.0/power/autosuspend_delay_ms returning Input/output error is normal. Nvidia's driver manages its own suspend timing instead of using the generic PCI autosuspend timer.
Step 5: Run an app on the dGPU on demand
Now that the card sleeps, you need a way to wake it for the apps that should use it (games, CUDA, Blender, video editors). The right tool is prime-run:
sudo pacman -S nvidia-prime
prime-run glxinfo | grep "OpenGL renderer" # should mention Nvidia, not Intel
prime-run blender # any app you want on the dGPU
Under the hood, prime-run sets a few environment variables (__NV_PRIME_RENDER_OFFLOAD=1, __GLX_VENDOR_LIBRARY_NAME=nvidia, and friends) so OpenGL and Vulkan calls go to the Nvidia card. When the app exits, the card goes back to sleep on its own.
Step 6: Don't use optimus-manager on Wayland
The older optimus-manager tool used to be the standard answer for hybrid graphics in the X11 era. On Wayland it's broken: its state machine waits for an Xorg start that never comes, so the daemon hangs in pending_post_xorg_start and the Qt UI fatals when you open it. prime-run is the modern replacement and works fine on Wayland.
If you already have optimus-manager installed, migrate off it cleanly:
sudo systemctl disable --now optimus-manager.service
sudo pacman -Rns optimus-manager optimus-manager-qt
sudo rm -f /etc/X11/xorg.conf.d/10-optimus-manager.conf
sudo rm -rf /var/lib/optimus-manager /var/log/optimus-manager
sudo find /etc /usr/lib -name "*optimus-manager*" # confirm nothing remains
Substitute optimus-manager-git in the -Rns line if you installed the AUR -git variant.
Further tweaks worth a pass
Not Nvidia-specific, but they tend to come up in the same "make this laptop quieter" sweep:
- Stale
/etc/modules-load.d/entries. Ifsystemctl --failedshowssystemd-modules-load.servicein red, look at the files under/etc/modules-load.d/— one of them is asking the kernel to load a module the kernel rejects. A common culprit on MSI laptops is a leftovermsi-ec.conf. Delete the offending file, runsudo systemctl restart systemd-modules-load.service, and re-checksystemctl --failed. NetworkManager-wait-online.serviceblocksnetwork-online.targetfor up to 30 seconds on boot. Most server-style daemons (docker, mariadb, sshd) have their own reconnect logic and don't need it.sudo systemctl disable --now NetworkManager-wait-online.serviceshaves a noticeable chunk off boot time on a laptop that connects to Wi-Fi after login anyway.- Btrfs
noatimemount option. The Btrfs default ofrelatimewrites access-time updates on every read past a threshold. Addnoatimeto your Btrfs entries in/etc/fstab, thensudo mount -o remount /(and the same for any other Btrfs mounts). Slightly less SSD wear, slightly faster reads.
What NOT to install
optimus-manageron Wayland — see step 6.tlp/auto-cpufreq— both conflict withpower-profiles-daemon, which is what KDE's battery widget integrates with on a default Manjaro install. Pick one. PPD is the modern recommendation; the other two are vestiges from before KDE picked up native PPD support.thermald— superseded by the kernel's ownintel_pstatethermal handling on any reasonably recent kernel. Only worth installing if you actually observe sustained thermal throttling.
That's the whole pass. On a typical Intel+Nvidia laptop expect ~2–3 W of continuous savings on battery, and the dGPU only wakes when you actively ask for it via prime-run.