One click tunes your NVIDIA graphics card: a little faster, on less power, with quieter fans.
Then it keeps it that way. You do not have to think about it again.
Download · What one click does · How it works · Command line · FAQ
- You press one button. Optimize GPU, with All in one already selected. There are no values to enter and nothing to read up on. In about 35 minutes the app measures your card at stock, finds its overclock, puts an undervolt on top of it, measures the quietest fan curve that keeps it cool, and tests the result as a whole for five minutes.
- It shows you what you got. Your card at stock next to your card now: score, power, temperature and fan speed, each measured for five minutes.
- It stays that way. From then on the result is applied at every logon; the run switches that on itself, and one tick declines it. The tray app puts the tune back within half a minute after a driver reset, runs the fan curve, and says so with one quiet line when a new version is out.
It cannot leave you worse off than stock:
- Verified, not trusted. Every value written to the driver is read back and checked, and a failed apply ends at stock.
- A crash is remembered. A journal on disk records each setting before it is tried, so one that froze the machine is never tried again.
- It gives up before you have to. Three logons in a row that crash switch apply-at-logon off; four driver resets within an hour with the tune applied put the card back at stock.
- It plays fair. If MSI Afterburner or another tool changes the settings, it steps aside instead of fighting over them.
The one time it asks for you again is after a driver update: a tune belongs to the driver it was tested on, so the app does not apply it, says so, and one more click tests it on the new driver: five minutes, instead of a whole new run.
What else is in it:
- Five more profiles for when you want one thing only: Best of my GPU, Cool & efficient, Quiet, Max performance and Undervolt.
- You see what it does: during a run the window draws the card's voltage/frequency curve as the run writes it, over the card's own, says which step the run is at, and counts every long one down.
- Fan curves: the measured one, Silent, Normal, Cool or Aggressive, or your own; fans stop at idle without cycling on and off, the app learns the lowest speed your fans can actually hold, and the fans go back to the driver on exit, sleep, logoff and crashes.
- Native and small: two C++ programs, under 2 MB together, with no installer, no runtime and no driver or service.
All in one is the default: it overclocks, undervolts on top of that, measures the quietest fan curve and tests the whole for five minutes. One run on the reference card, both columns five minutes of full load (the picture above is of an earlier run and shows that run's numbers):
| Stock | After one click | |
|---|---|---|
| Stress-test score | 5309 it/s | 5353 it/s (+0.8 %) |
| Power under load | 185 W | 166 W (−10.3 %) |
| Fan speed | 70 % | 52 % |
| Temperature | 66 °C | 70 °C |
| Core clock under load | 2787 MHz | 2835 MHz |
| Memory clock under load | 10474 MHz | 11051 MHz |
As fast or a little faster, on a tenth less power, with much slower fans. The card is warmer because the fans are allowed to be: the fan tune aims for 70 °C, 5 °C under the profile's limit, and found that 52 % holds it. Before the fan tune, with the fans on the profile's own curve, the same settings ran at 66 °C on 163 W. The run took 31 minutes. Two earlier runs gave 1.6 % more score on 8.2 % less power with the fans at 62 %, and 0.9 % more on 10.8 % less with the fans at 55 %. How much memory offset a run finds differs from run to run on this card (+550 in this one, +1500 in the first of those); the score barely moves with it.
The gains are smaller than those of the two sections below, and that is the point of it. An overclock and an undervolt do not add up: an overclock moves the whole voltage/frequency curve, so at every clock the card already runs on less voltage, and with the same safety margin there is nothing left to take off. They are two ends of one line. All in one takes the middle, where the card beats stock on both counts; Best of my GPU and Undervolt are the ends.
Note
Close games and other programs that use the graphics card before a run. In an earlier run an emulator on 11 % of the card cost 6 % of the score; the run now says so when its final test does not match the step before it. The logs are in docs/hardware-checks.md (checks 75, 76 and 94).
One run of Best of my GPU on the reference card, an RTX 4070, with nothing else to set:
| Stock | After one click | |
|---|---|---|
| Stress-test score | 5736 it/s | 5996 it/s (+4.5 %) |
| Core clock under load | 2766 MHz | 2899 MHz (offset +135 MHz) |
| Memory clock under load | 10355 MHz | 12100 MHz (offset +1600 MHz) |
| Power under load | 187 W | 204 W (power limit 105 %) |
The search raised each clock until the card computed a wrong value (core +225 MHz, memory +2550 MHz), confirmed the last values that held (+210 and +2300 MHz) and applied them minus a safety margin. The result then had to pass a five-minute soak before it was saved. The whole run took 11.7 minutes.
Note
The score is the app's own stress test, a DirectX 11 compute load. Games gain a different amount, and every card has its own limits. The log of this run is in docs/hardware-checks.md (check 52, fourth run).
One run of Undervolt on the same card. Clocks and power limit stay stock; the card reaches the same clock on less voltage:
| Stock | After one click | |
|---|---|---|
| Power under load | 195 W | 155 W (−20.5 %) |
| Temperature | 67 °C | 59 °C |
| Fan speed | 72 % | 64 % |
| Stress-test score | 5732 it/s | 5708 it/s (−0.4 %) |
| Core clock under load | 2788 MHz | 2778 MHz |
| Voltage the card reaches that clock at | 1100 mV | 990 mV |
Both columns are five minutes of full load, so the card is heated through on both sides and the temperatures compare; in this run the fans were left to the NVIDIA driver's own curve (the search now keeps them on the fan curve in use). The search lowered the voltage one curve point at a time until the card computed a wrong value (940 mV), confirmed the lowest value that held for 30 s (950 mV) and applied it with the safety margin (990 mV). The result then had to pass the five-minute soak before it was saved. The whole run took 12 minutes.
Note
An undervolt is saved in place of an overclock, not next to it, so this is the other choice, not an extra. Every card has its own limits. The log of this run is in docs/hardware-checks.md (check 72).
- Download
GpuAutoOptimizer-<version>-win-x64.zipfrom the latest release and unzip it anywhere. - Start
GpuAutoOptimizer.exe. - Open Optimize and press Optimize GPU: All in one is selected, and you can pick another profile first. Close games and other programs that use the graphics card before you do, and the tools that tune or draw on it: close MSI Afterburner and RivaTuner, switch Automatic Tuning off in the NVIDIA app (System, Performance), and keep the NVIDIA overlay (Alt+Z) closed during the run. The app asks for administrator rights, because it changes clocks and power limits. The run looks for itself first: when other programs are using the card it names them (an editor or a browser that stands open is enough to cost several percent) and asks whether to check again, go on anyway or cancel. It closes nothing for you.
- That is all. When the run is done the result is applied, saved, and kept at every logon. Untick Keep the result applied at every logon before the run if you only want to try it.
Note
The executables are not code-signed yet, so Windows SmartScreen may warn on the first start. Choose More info, then Run anyway. To check the download first:
(Get-FileHash .\GpuAutoOptimizer-<version>-win-x64.zip -Algorithm SHA256).Hash # compare with the .sha256 file
gh attestation verify .\GpuAutoOptimizer-<version>-win-x64.zip --repo Rovey/gpu-auto-optimizerKeeping the result applied copies the app to %ProgramFiles%\GpuAutoOptimizer\ and starts it in the tray at logon, so the unzipped folder can be deleted afterwards. Apply at logon on the dashboard switches it off again.
| OS | Windows 10 (version 1803 or later) or 11, 64-bit |
| GPU | NVIDIA, Pascal (GTX 10-series) or newer, with a current driver |
| Rights | Administrator to optimize or apply; reading telemetry does not need them |
| Profile | Goal | Temperature limit | Tunes |
|---|---|---|---|
| All in one (default) | More speed than stock on less power: the overclock below, an undervolt on top of it at a clock half-way back to stock, and the quietest fan curve that holds the temperature | 75 °C | power, core, memory, the voltage/frequency curve, fans |
| Best of my GPU | Highest confirmed clocks with a safety margin, most power the card allows | 75 °C | power, core, memory |
| Cool & efficient | Lowest power limit that costs under 2 % speed; clocks stay stock | 65 °C | power |
| Quiet | Milder clocks and the lowest power limit that costs under 2 % speed | 80 °C | power, core, memory |
| Max performance | Highest confirmed clocks minus one step, highest power limit | 83 °C | power, core, memory |
| Undervolt | The clock the card runs under load at stock, on the lowest stable voltage plus the same margin; clocks and power limit stay stock | 75 °C | the voltage/frequency curve |
The safety margin: the search finds the highest stable offset and applies a fraction of it (70 % for Best of my GPU), always at least one step below the edge.
Best of my GPU and Max performance promise speed, so they keep a result only when it is at least as fast as the card was at stock (within 1 %, the scatter of two five-minute runs). On a card that is warmer at stock than the profile allows, the power limit has to come down to meet the temperature, and that can cost more than the clocks win back. The run then says so, applies and saves nothing, and leaves the card at stock; Undervolt is the profile for such a card. Quiet and Cool & efficient give a little speed away on purpose and are not judged this way.
The undervolt is saved in place of an overclock, not next to it: on the card a core offset and the curve are one table. The card's built-in curve moves with temperature, so the points above the one the card runs on are stored a little lower than it: a warm card then gives up one 15 MHz clock step instead of going to a higher voltage, which had cost about 12 W. During a run the window draws the curve as the run writes it:
flowchart LR
S[Stock<br/>300 s: the "before",<br/>and what probes are judged by] --> B[Power limit]
B --> C[Memory offset<br/>bandwidth peak, confirmed,<br/>safety margin]
C --> D[Core offset<br/>single steps, confirmed,<br/>safety margin]
D --> G[Soak<br/>300 s]
G --> H[Save profile]
- Every run starts with the card at stock for five minutes, as long as the result is tested at the end, with the fans left to the NVIDIA driver. That is the "before" of the result: a card is not heated through after 30 s, so a shorter run would make every result look warmer and louder than stock. Some cards get hot there: the driver's own fan control lets them (a 3080 Ti reached 85 °C with its fans at 65 %). The measurement stops at 85 °C, what it measured until then is the "before", and the run goes on. From there every step keeps the fans on a curve that reaches 100 % at the profile's temperature limit.
- Stress test. A DirectX 11 compute load in which the GPU checks every value it computes against a known answer. Each probe ends in a verdict:
STABLE,WRONG RESULT,DEVICE LOST,STALLED(the values were right but the card computed almost nothing),TOO HOTorNO TELEMETRY. - Memory comes first and stops at the bandwidth peak, not at the first error. GDDR6 and GDDR6X retry failed transfers, so an overclocked memory bus loses speed long before it returns a wrong result. The search raises the offset 50 MHz at a time, measures bandwidth at each step until a step fails or has clearly lost bandwidth, then measures again from 200 MHz below that point down and keeps the lowest offset within 1 % of the best. Where the memory gave out is remembered for that card and driver, so a later run stays below it without going there again. Where bandwidth cannot be measured, the memory is left at stock: without that measurement nothing says where to stop, and the first wrong result comes far too late.
- The core search climbs from stock. With the chosen memory offset applied, it raises the core offset 15 MHz at a time until a probe fails, and keeps the last value that passed. How far it may go comes from the range the driver reports for your card, so a card that can hold more is not stopped at a fixed limit.
- Each edge is confirmed. The value a search ends on gets a 30 s probe, and a lower value is tried if it does not hold. The safety margin is applied to the confirmed value, and the result as a whole must pass the 300 s soak.
- A driver reset ends that clock's search. On a card the search can push past its edge, a search resets the driver: the screen goes black for a moment. The run then reconnects to the driver, sets the card to stock, leaves it without load for 20 seconds and checks with a short probe at stock that it computes normally again. After that the search tries no new values for that clock: it keeps the last value that passed and confirms four steps below it. Each clock has its own search, so a reset in the memory search does not keep the core from being searched; a run can therefore reset the driver twice, once per clock. One reset more than that ends the run at stock with nothing saved, and so does a card that does not come back. Results on real cards are in docs/hardware-checks.md, checks 51 and 52.
- The undervolt search descends. It measures the card at stock for five minutes, as long as the result is soaked later, so that the two compare: the clock it runs under load, and where on its voltage/frequency curve that clock sits. Then it raises a point one step lower on the curve to that clock and keeps every point above it below that, so the card has no reason to ask for more voltage, and tests that; then the next point down, until one fails. The lowest point that passed gets the 30 s probe, the margin is applied to how far that point was raised, and the result must pass the 300 s soak. No voltage is locked and the points below stay as they are, so idle clocks do not change.
- All in one runs the others in a row. Five minutes at stock to compare with; the overclock of Best of my GPU; an undervolt on top of it; the fan tune; five minutes with everything applied. An overclock and an undervolt do not add up: an overclock moves the whole curve, so at every clock the card already runs on less voltage, and with the same safety margin there is nothing left to take off (on the reference card: 5 W of 201). They are two ends of one line. All in one takes the middle: a clock half-way between stock and the overclock, on the lowest voltage the margin allows for it. The fan tune then sets the fans by hand under that load, lets the temperature settle and goes 5 % lower until the card gets warmer than 5 °C under its limit; the lowest speed that held becomes a point of the fan curve.
- Crash journal. Before a candidate touches the hardware, a
beginline is flushed to disk. If the machine freezes, the unmatchedbeginbecomes a ceiling the next run stays below. - Apply at logon. A scheduled task starts the app in the tray at logon, which applies the saved profile. It refuses when the driver version or the card changed since tuning, and it stops after three logons in a row that crashed within two minutes.
- Tune watchdog. Every 30 seconds the tray app reads back what the driver reports. It re-applies after a reset, and backs off when another program changed the settings. Four resets within an hour, of the tune or of the driver with the tune applied, are a sign it is not stable: the card is set to stock and the tune is no longer re-applied.
gao.exe ships next to the app and drives the same engine. Commands that write to the GPU need an elevated shell.
| Command | What it does |
|---|---|
gao --optimize best|quiet|cool|max [--fan-curve silent|normal|cool|aggressive] |
Runs the search; exit code 0 when saved, 2 when applied but not saved |
gao --optimize all |
All in one: stock measured, overclock, undervolt on top, fan tune, final test; about 35 minutes |
gao --undervolt |
Runs the undervolt search; saved like --optimize, in place of a saved overclock |
gao --undervolt --on-overclock |
The undervolt searched on top of the saved overclock and saved into it |
gao --apply |
Re-applies the saved profile |
gao --reset |
Returns to stock clocks and the default power limit |
gao --boot on|off |
Turns apply-at-logon on or off |
gao --fan auto |
Hands every fan back to the NVIDIA driver, whatever set it (a running tray app takes them again on its next tick; switch Fan control off to keep the driver in charge) |
gao --status |
Saved profile, what is applied now, apply-at-logon state |
gao --probe |
Live telemetry: clocks, temperature, fan, power, clock-offset ranges |
gao --curve |
Prints the voltage/frequency curve as the driver reports it; changes nothing |
gao --stress <seconds> |
Runs the stress test alone and prints its verdict; changes nothing |
gao --bandwidth [--after-load <sec>] |
Measures the current memory bandwidth and shows every run of the measurement; with --after-load, right after that many seconds of the stress load, as a run measures it |
gao --busy |
Shows the other programs that use the card right now, as a run looks for them before it starts; changes nothing |
gao --update |
Installs the latest release into the folder gao.exe is in, if there is a newer one |
gao --stress-recreate |
Runs the stress test, rebuilds its GPU device, runs it again; prints both scores and the rebuild time; changes nothing |
Ctrl+C during --optimize restores stock.
Does it connect to the internet?
Only to look for a new version: one request to api.github.com when the app starts and once a day after that. Nothing but the request itself is sent. You can switch it off under About. An update is downloaded only when you click Update available (or run gao --update): the zip comes from this project's GitHub releases over HTTPS and is installed only when its SHA-256 matches the one GitHub publishes for it.
How do I move to a new version?
From 0.3.1 on, click Update available at the bottom left of the window. From an older version, download the zip and start GpuAutoOptimizer.exe from it: it offers to replace the older copy that runs in the tray, and then updates the copy that starts at logon.
Does it work alongside MSI Afterburner or the NVIDIA app?
Not during a run: a run does not start while MSI Afterburner or RivaTuner Statistics Server (MSIAfterburner.exe, RTSS.exe) is running, and says which one to close. Close it completely, also its icon in the notification area, and switch off its start with Windows if it applies settings there. Outside a run they can coexist as long as only one of them applies settings: if Afterburner applies an offset while GPU Auto Optimizer keeps its tune applied, the watchdog notices, says so in a notification and leaves the settings alone. Other programs that merely use the card (a browser, an editor, a video) are a different matter: they change nothing on it, so a run is not refused next to them. It names them and asks, because they make everything it measures lower and less steady. On the command line it stops with that list; add --busy-ok as the last argument to go on as it is.
The NVIDIA app can stay installed. Two of its features get in the way of a run: Automatic Tuning (System, Performance) applies an overclock of its own and scans again from time to time, so switch it off, for a run and for as long as you keep a tune of this app applied; and the overlay (Alt+Z) draws on programs that use the card, so leave it closed while a run is going. A run does not start while Automatic Tuning is on, and gao --status shows what the app reads (nvidia app: Automatic Tuning off). The overlay it cannot see: that one is yours to keep closed.
What happens after a driver update?
The saved profile is tied to the driver version it was tuned on, because a new driver can change what is stable. After an update it is not applied: the app says so at logon, and the dashboard shows Test the tune (5 min). That loads the card for five minutes with the tune on it. If it holds, the tune is applied again and belongs to the new driver; if it does not, the card goes back to stock and you optimize again. The test never starts by itself. On the command line: gao --retest.
What if a setting crashes my PC?
During a search, the crash journal makes sure that setting is never tried again, and the next run stays below it. At logon, three crashes in a row within two minutes of applying switch apply-at-logon off.
The run failed a probe or reset the driver. Is that normal?
Yes. The edge of a card is found by crossing it. A probe that computes a wrong value ends in WRONG RESULT, and the search keeps the last value that passed. A probe that ends in DEVICE LOST, STALLED or NO TELEMETRY is treated as a driver reset.
A search may reset the driver once: the screen goes black for a moment. The run then reconnects, sets the card to stock, rests for 20 seconds, checks that the card computes normally again, and stops exploring that clock: it tries no new values for it, and confirms a little below the last value that passed. The memory search and the core search each get one, so a run can reset the driver twice. One more ends the run at stock with nothing saved, and so does a card that does not come back. Nothing about a reset is remembered, so the next run on such a card crosses the edge again. Results on real cards are in docs/hardware-checks.md, checks 51 and 52.
A driver reset also reaches the other programs on the desktop. In a test during development, with an earlier build that put the load back on the card right after a forced reset, no application window could be opened or seen afterwards and one application crashed; the user had to sign out and in. The rest after a reset was added since; whether it prevents this has not been tested. Save your work before a run.
If the machine freezes instead, the crash journal makes sure the next run stays below that setting.
Can it control the fans?
Yes. Each profile comes with a fan curve, and you can pick another (Silent, Normal, Cool, Aggressive) for a run or afterwards. The Fan page lets you edit it: drag the points, and choose a temperature below which the fans stop once the card is cool and idle (the NVIDIA driver controls them there, so a crash or a killed app can never leave them stopped). The optimize run uses the profile's curve, so the tune is tested at the temperatures that curve produces; a quieter curve afterwards shows a warning. The curve runs while the tray app runs with administrator rights; otherwise the driver controls the fans.
Does it undervolt?
Yes, with the Undervolt profile. It does not lock a voltage (that froze the reference card during development): it reshapes the voltage/frequency curve so that the card reaches its stock clock at a lower voltage and nothing above it runs faster. It is found, tested and kept applied like an overclock, and it replaces one: the two cannot be saved together yet.
Where does it keep its data?
In %ProgramData%\GpuAutoOptimizer: gao.json (the saved profile), journal.jsonl (the crash journal), boot.log, and run.log (every line a run showed, written as it happened, so that it is still there after a crash; send it along with a problem report). Users can read the folder; only administrators can write it, because the logon task runs with administrator rights.
Visual Studio 2026 with the C++ and CMake components. From a Developer PowerShell in the repository root:
cmake --workflow --preset ci # configure, build Release, run the testsThis produces build\Release\GpuAutoOptimizer.exe and build\Release\gao.exe. See docs/development.md for the code layout, the test setup and the hardware checklist.
MIT © Rovey. The executables contain Dear ImGui and JSON for Modern C++, both under the MIT License; their notices are in THIRD-PARTY-NOTICES.md and in every release zip.


