Tracking down why Windows won't Sleep
Table of Contents
Backstory
As a new owner of an OLED PC monitor[1], I am trying my best to treat the display properly. It already has a pixel refresh function that appears after every 4 hours of screen on time, and I do my best to stick to that schedule. That also means I've implemented measures to turn my screen off after minimal away time, and decided putting the Windows 11 computer to sleep after 5 minutes was a good option.
And it works well... until it doesn't. There are times I would walk away from my computer after locking it, and the screen stayed on. There are even times I would put the computer to sleep from the start menu, saw it go to sleep, and woke up to my monitor being on (showing the lock screen).
How to Find Power Events
After some investigation, I discovered that multiple types of power events could be to blame, but there is a PowerShell command that you can use to identify each one. You can run the listed commands in an Admin PowerShell terminal.
-
Wake requests: Existing events that will prohibit your computer from sleeping. This could be something like an actively playing video. Check for wake requests with
powercfg /requests
. -
Wake Timers: These are scheduled tasks (which can be viewed in Task Scheduler) that will wake up the computer at a specified time or when a specified condition is triggered. They can run while the computer is asleep and wake it up. In addition to Task Scheduler, they can be viewed more easily with
powercfg /waketimers
. -
Wake-Armed Devices: These are devices that have the ability to wake the computer while it is asleep. The most common examples are USB devices like a keyboard that will wake the computer on key press, or a network device that utilizes Wake-On-LAN (AKA "magic packet"). You can view a list of them with
powercfg -devicequery wake_armed
. They can be disabled in Device Manager. -
Last Wake: This is mostly useful for diagnostic purposes, but you can see recently triggered events that have woken up the computer from sleep mode with
powercfg /lastwake
. I have had mixed results with this command - it doesn't seem to show every wake event.
Some Wake Timers Can't be Disabled
Windows Update
While it's no surprise that Windows Update has become more agressive as new OS versions are released, Windows 11 goes far enough to create wake timers that cannot be disabled. Based on the "inactive hours" you specify in the Windows Update settings, if updates have been downloaded that require a reboot, Windows will created a Scheduled Task to wake your computer during these hours. If you investigate the respective Scheduled Tasks, they run as a system account, and even administrative accounts cannot modify them.
I've explored other potential ways of changing this, such as group policy and registry edits. Currently, I do not see an effective way to do so that wouldn't hinder the Windows Update process as a whole. The best option seems to be manually restarting (or shutting off) your computer with the option to install updates. If you did a restart, you may need to log in and then manually put the computer to sleep.
Manually Keeping the Computer Awake
As a sidenote, with my aggressive screen off and sleep settings, I often want to extend the amount of time before it sleeps. However, I do not want to do anything that will make the computer permanently stay awake.
As a solution, I've implemented the CLI of PowerToys Awake, tailored to my needs. There are many useful utilities in Microsoft PowerToys, which is an open source project maintained by Microsoft. PowerToys Awake can be configured in the PowerToys settings, or, as in my case, run as a standalone executable.
NOTE 10/2/2024 on Previous PowerToys Bugs: PowerToys v0.84.0 (released 9/2/2024) introduced a bug with PowerToys Awake related to tray icon behavior, and it also caused some problems with my implementation below. PowerToys has since been updated to v0.85.0 (released 10/1/2024), which seems to have resolved the issues in my implementation. However, there may still be some other issues. I submitted an issue on the PowerToys GitHub repository on 10/2/2024, and I hope these bugs are squashed by the next release.
My PowerToys Awake Implementation
First, I have Awake disabled in the PowerToys settings, as I only trigger it manually.
Next, I created a custom action button on my Stream Deck[2] that runs the Awake executable in the background[3] with arguments. You could, of course, make this a shortcut on your desktop or start it some other way. It effectively runs the following:
"C:\Program Files\PowerToys\PowerToys.Awake.exe" --display-on true --time-limit 1800
As you may expect, this keeps your display on[4] for 1800 seconds, which equals 30 minutes. I've found 30 minutes to be an effective amount of time for me to do something away from my computer without it going to sleep. And if I'm away longer, or simply forget, it will still go to sleep after 30 minutes. And each time I press the button, it kills the existing process and restarts it, making sure it always keeps my computer awake 30 minutes from the time the button is pressed.
Additionally, I created another button action to cancel this keep awake functionality. It uses the "Process Killer" action to terminate any instances of PowerToys Awake. This allows my computer to sleep after the interval specified in system settings.
Summary / TL;DR
If your Windows computer is not going to sleep as expected, there are several PowerShell commands you can run to troubleshoot. To resolve these issues, you may have to close open media, or explore settings in Device Manager or Scheduled Tasks.
Windows Update is the exception - you cannot disable Windows Update related Scheduled Tasks.
If you use aggressive sleep settings, you may want to have to the ability to temporarily extend your computer's awake time. One solution for this is PowerToys Awake.
Commentary
If you have any thoughts on this article that you would like to share, please send me an email at [email protected] and I will get back to you. If new information is provided, I will update the article accordingly.
-
Alienware AW3423DWF, which has a detailed review on Rtings.com. ↩
-
Stream Deck Mini, available directly from Elgato or at many other retailers. I don't use it for the intended purpose (streaming on Twitch, YouTube, etc.) but instead as macro buttons for various purposes. ↩
-
I use a marketplace plugin called "Advanced Launcher" by BarRaider that allows for background execution. The author has a website with social links, including a Discord server where you can find pre-release versions of plugins as they are developed. ↩
-
You should be able to run this command without
--display-on true
if you only want to keep the computer from sleeping. For my use case, I want the display to remain on. ↩