Open-source project
Askannz/optimus-manager avatar
Askannz/optimus-manager

optimus-manager: the daemon that decides when your laptop uses which GPU

A Linux program to handle GPU switching on Optimus laptops.

2,444 stars185 forksPythonMIT

At a glance

What is it?
A Python service for Linux laptops with two GPUs that switches the whole graphics stack between them at login, wraps Prime offloading so it survives a reboot, and gets out of the way on Wayland.
Who is it for?
optimus-manager solves a problem that looks trivial until you try it by hand: on a laptop with two GPUs, choosing one is not a driver setting but a coordinated teardown of the display server, the compositor, the NVIDIA kernel module and a pile of client libraries, in the right order, every time. The project does that job for X11 with three modes and a schema-validated config file, and it declines to try on Wayland because the compositor owns too much of the decision there.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 143 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem underneath the problem

The README states the function in one line: it enhances performance and power management on Nvidia Optimus laptops by properly selecting when to use each GPU. The second paragraph is the part that explains why a dedicated program exists. The Nvidia GPU runs the whole desktop, while the Intel or AMD GPU acts as a relay between the Nvidia GPU and the screen.

That topology is the whole difficulty. On a discrete GPU laptop the panel is usually wired to the integrated GPU, not to the Nvidia card, so rendering on Nvidia means copying frames outward. The kernel module has to be loaded, the display server has to start with the right clients, the power state of the card has to be managed, and clients need to know whether they may offload. Miss any one of those and you get a black screen, a login loop, or a session that renders correctly until a browser opens a GL surface and the display drops out.

The result is that this is not a case of flipping a boolean in a settings panel. It is a sequencing problem, and the sequencing is what the package's hook scripts are for. The `setup.py` at the root registers three console entry points that map the design directly: `optimus-manager` for the client, `prime-switch` as a pre-Xorg-start hook, and `prime-offload` as a post-Xorg-start hook. One is what a human runs, the other two are what the display manager runs for you.

Three modes and what each one actually does

The mode vocabulary is small and the definitions matter more than they look. `nvidia` switches to the Nvidia GPU. `integrated` switches to the integrated GPU and powers the Nvidia GPU off entirely. `hybrid` switches to the integrated GPU but leaves the Nvidia GPU available for on-demand offloading, which the README describes as similar to how Optimus works on Windows.

The distinction between `integrated` and `hybrid` is the useful one. Powering the discrete card off is the state you want on battery, and it is also the state that guarantees nothing can accidentally use it. Keeping it powered but unused is the state you want when you will occasionally launch something that needs real GPU compute or a game engine, and you do not want a full logout to get there.

Two warnings are attached to this section of the README and both are worth internalizing. In the configuration file, if `auto_logout=yes`, switching will log out and close all applications. And switching to and from integrated mode can be unstable. That second warning is not a hedge, it is a description of the failure mode where the sequence completes but the display server comes back in a bad state.

The configuration lives in `/etc/optimus-manager/` on X11, and the README frames the default as a deliberate choice: on X11 the Nvidia GPU is used for everything, giving maximum performance and ease of use at the expense of power consumption. If you want to try to optimize that, the config directory is where you start. The README also points at `man optimus-manager` for the terminal reference, which is the better first stop than reading scripts.

Wayland gets one behaviour, and it is not configurable

The Wayland story is short enough to state plainly and different enough to deserve its own section. On Wayland the Nvidia GPU is used for high performance apps which use GLX or Vulkan, while the integrated GPU handles the less demanding apps which use EGL, such as the desktop itself and the web browser. And then: this behavior is not configurable.

That sentence is not a limitation the author apologizes for, it is a consequence of the architecture. Under Wayland the compositor owns the display pipeline, and optimus-manager is a session-level switcher rather than a compositor. The list of supported graphics protocols names Xorg explicitly and then says Wayland without configurable options, which is the same statement in a different place.

The practical reading is that if you want per-application GPU control, optimus-manager gives it to you on X11 and leaves it to the desktop environment on Wayland. GNOME users have their own route to a tray interface, listed separately in the system tray section. Anyone hoping to reproduce a hand-tuned X11 config on Wayland should not expect this package to be the tool.

The supported display managers are listed just as plainly: SDDM, LightDM, GDM, plus links in the wiki for a custom one and for none at all, covering people who start their session with startx or xinit. Naming the no-display-manager case in the README is a small courtesy that signals the author has met the failure it describes.

Boot entries for choosing a GPU before the desktop starts

The boot entry feature exists because session switching is not always the right moment. The README frames it as useful if you want different entries for different GPU startup modes, and adds the important constraint that this only affects which GPU your desktop session starts with, nothing prior to that.

The mechanism is a kernel parameter. You edit your boot loader config to add `optimus-manager.startup=[nvidia\integrated\hybrid]`, choosing one of the three values. Since this is a boot-time decision, it also means an entry that always boots into integrated mode, which is the configuration most people running on battery actually want and the one a session-level switch cannot give you without logging out first.

For GRUB specifically there is a separate helper, `optimus-manager-grub`, linked from the README and credited to another maintainer. The kernel parameter is the portable form and the helper is the convenience form.

The kernel parameter syntax also explains a line in the installation steps: if you are not using the standard `linux` kernel, you must install the `linux-headers` package variant matching your kernel name. That requirement exists because a parameter consumed early in boot is not something a generic udev rule can intercept, so the mechanism has to be compiled in.

Installing it and the one thing the README insists on first

Installation is three steps, and the ordering is the interesting part. Match the `linux-headers` package to your kernel if you are not on the standard one. Install the appropriate `nvidia` package, linking to the Arch wiki page for installation. Then install `optimus-manager` itself, with `optimus-manager-git` named as the AUR package.

Note what step two is not. It is not a version of the driver bundled with this project. The package depends on a working NVIDIA driver installation being present already, which is why the guides section above installation sends you to the Arch NVIDIA driver installation and troubleshooting pages and only then to the project FAQ. The README's framing is direct: most issues are due to the Nvidia driver itself, and if you are experiencing any, try those three links first.

The Python side is a conventional setuptools package. The console scripts and package data declared in `setup.py`:

python
entry_points={
    'console_scripts': [
        'optimus-manager=optimus_manager.client:main',
        'prime-switch=optimus_manager.hooks.pre_xorg_start:main',
        'prime-offload=optimus_manager.hooks.post_xorg_start:main'
    ],
},
+

+ +The three entry point names tell you the shape of the implementation. `prime-switch` lives in `optimus_manager.hooks.pre_xorg_start` and runs before the display server starts, which is the only time module load order and client selection can still be changed. `prime-offload` lives in `optimus_manager.hooks.post_xorg_start` and runs afterwards, which is when the NVIDIA offload service can be published and clients can discover it. The keywords list in `setup.py` names the lineage: optimus, nvidia, bbswitch, prime, gpu. The tree confirms the structure with `login_managers/`, `modules/`, `completion/`, `profile.d/`, and init system directories for systemd, s6, runit and openrc, which is unusually broad coverage for a project of this size.

Reading the layout to predict where a problem lives

The repository tree is short enough to read as a map of the problem space. `optimus_manager/` holds the package itself, with `client.py` for the user-facing command and a `hooks/` subpackage containing the two lifecycle scripts. `modules/` is where kernel module handling lives, `login_managers/` is where display manager integration sits, and `config/` holds the configuration schema. `completion/` is shell completion, `profile.d/` sets environment variables for the session, and `package/` holds the packaging scripts that the contributing guide tells you to use.

That last point is the answer to a question every contributor asks first. Step four of the contributing section says to thoroughly test that the program still works and points at the scripts in `package`, and step five is the commit. Step seven says accepted in two days, which is an unusually concrete turnaround promise and a useful signal about how the project is maintained.

There are no tagged releases in the repository data, so distribution happens through the packaging layer rather than versioned artifacts. That is consistent with an Arch-first audience: the AUR package `optimus-manager-git` tracks the git tree, and the wiki carries the documentation. The terminal reference is a man page, `optimus-manager.1`, listed in the tree alongside the default `optimus-manager.conf`.

The project also asks contributors and reporters to do something specific before opening an issue: isolate which config is causing the problem, then collect system information with a one-liner that writes to a file you attach. The README notes that a report may be closed while more information is requested, and that you just reopen it when done, which is a small workflow detail that tells you what the maintainer's time actually looks like.

What optimus-manager replaced and where it still hurts

The context matters for judging long term risk. This project exists because the upstream service it replaced was deprecated by NVIDIA in 2021. In other words, this is the community continuation of a vendor component, which is why the interface is shaped around the behavior users had rather than around a fresh design.

That cuts both ways. On the positive side it means the modes, the config layout and the kernel parameter are shaped by years of real use on real hardware, and the fact that only 3 issues are open against 2,444 stars suggests the sequence works on most machines most of the time. On the negative side, it is a Python program in a boot-adjacent path on a machine whose display stack depends on a proprietary driver, and both of those things are places where an ordinary Python exception turns into a machine that will not show a login screen.

The integration surface also widens with each supported environment. Shell completion, systemd units, s6, runit and openrc directories, SDDM, LightDM, GDM, custom display managers and bare startx, plus separate community tray front ends for all desktops and two GNOME-specific ones. Each of those is a small compatibility promise, and the wiki is where the custom and none cases are documented rather than the README, which suggests the main file is the happy path.

The honest summary is that this is a mature solution to a problem no general-purpose tool solves well, with an obvious dependency on driver quality that it cannot control. If your laptop is Nvidia Optimus hardware and you are on X11, it is the package people use. If you are on Wayland and want per-app switching, the desktop environment's own control panel is the tool, and this project only tells you which GPU handles which rendering path.

Editorial conclusion

optimus-manager solves a problem that looks trivial until you try it by hand: on a laptop with two GPUs, choosing one is not a driver setting but a coordinated teardown of the display server, the compositor, the NVIDIA kernel module and a pile of client libraries, in the right order, every time. The project does that job for X11 with three modes and a schema-validated config file, and it declines to try on Wayland because the compositor owns too much of the decision there. Two things to weigh before adopting it. First, the project's own guidance is that most reported problems originate in the NVIDIA driver, not in this code, so the README sends you to the Arch driver installation and troubleshooting pages before the issue tracker. Second, the upstream Primelink service it replaces was deprecated in 2021, which means the wheel it sits on is no longer being turned. At 2,444 stars, 185 forks, only 3 open issues, MIT licensed with the last push on 2026-05-16, this is a mature project rather than a neglected one. Read `/etc/optimus-manager/` and run `man optimus-manager` before your first reboot, and leave `auto_logout` alone until you know what your session does when it disappears.

Frequently asked questions

What is NVIDIA Optimus?

It is the dual-GPU design used in many gaming laptops, where an integrated Intel or AMD GPU drives the display panel and a discrete Nvidia GPU is added for heavy work. Because the screen is wired to the integrated chip, rendering on the discrete card requires copying frames, which is why the design trades power for performance. optimus-manager exists to decide when that switch should happen, and its three modes, `nvidia`, `integrated` and `hybrid`, correspond to always using the discrete card, powering it off entirely, or keeping it powered for on-demand offloading.

How do I install optimus-manager on Arch?

Three steps in order. If you do not run the standard `linux` kernel, install the `linux-headers` package that matches your kernel name. Install the appropriate `nvidia` package, which is a separate step this project does not handle for you. Then install the `optimus-manager` package itself, available in the AUR as `optimus-manager-git`. Read the configuration files in `/etc/optimus-manager/` before rebooting, and note that setting `auto_logout=yes` in the config file makes switching log you out and close every running application.

Can I control GPU switching on Wayland?

Not through this package. The README lists Xorg as a supported graphics protocol and describes Wayland as having no configurable options. What you get on Wayland is fixed behaviour: the Nvidia GPU handles high performance apps using GLX or Vulkan, while the integrated GPU handles EGL clients such as the desktop and the web browser. For per-application control on Wayland you want your desktop environment's own settings instead, and on GNOME there are separate tray front ends listed in the README for that purpose.

Official sources

  1. Askannz/optimus-manager on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/askannz-optimus-manager.svg)](https://hysenlabs.com/projects/askannz-optimus-manager)