Getting More Computing Time on the Road

When you put your macintosh laptop on several hours of sleep, did you notice that the battery decreases? I noticed this as well. On my old (about five years) MacBook Pro, I dismissed it and thought that it was due to an aging battery. But when I see this happening to a one day old MacBook Pro, I began to take notice. Something was up and consuming the laptop’s energy.

On further investigation, I found out that the unit woke up every half an hour or so, each with a duration of a few seconds. This is when it was supposed to be sleeping with the lid closed. Although there were some hours where it didn’t woke up — skipped wake-up hours. But there were some times in which the time between wake-up intervals were within 10 minutes of one another. Of course when this is happening, the battery gets taxed quite a bit — even when the display is off.

What has been causing this? Stay tuned for the root cause and solution.

Diagnosis

How I came to know that the unit woke up often during sleep was from the Power Management Log. You can see this from the macOS’ built-in Console application. Open the Applications folder and then Utilities — the Console app should be there unless you have moved it.

In the Console application, expand the /var/log group and then select powermanagement. It should have messages created within the last week or so – view a day’s worth of log messages by selecting an entry there.

Power Management logs in Console

I’ve looked at my system’s Power Management Log messages and saw that there are some messages at times in which the unit should be sleeping. A wake up cycle typically looks like this:

10:05:37.494346 +0800   powerd  Entering Sleep state due to 'Clamshell Sleep':TCPKeepAlive=active
10:05:42.503966 +0800   powerd 
10:05:42.504349 +0800   powerd 
10:59:04.521246 +0800   powerd 
10:59:04.544943 +0800   powerd  [System: DeclUser kDisp]
10:59:04.552876 +0800   powerd  [System: PrevIdle DeclUser kDisp]
10:59:05.404497 +0800   powerd  [System: DeclUser kDisp]
10:59:05.404828 +0800   powerd  DarkWake from Normal Sleep [CDN] due to EC.ARPT/Maintenance:
10:59:05.404952 +0800   powerd  hibmode=3 standbydelay=10800
10:59:05.405748 +0800   powerd 
10:59:15.851603 +0800   powerd  [System: PrevIdle DeclUser kDisp]
10:59:15.856435 +0800   powerd  Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active
10:59:20.873056 +0800   powerd 
10:59:20.873989 +0800   powerd 
11:00:03.763165 +0800   powerd 
11:00:03.768219 +0800   powerd  [System: PrevIdle DeclUser kDisp]
11:00:03.801981 +0800   powerd  [System: PrevIdle DeclUser kDisp]
11:00:04.625249 +0800   powerd  [System: PrevIdle DeclUser kDisp]
11:00:04.625493 +0800   powerd  DarkWake from Normal Sleep [CDN] due to EC.ARPT/Maintenance:
11:00:04.625575 +0800   powerd  hibmode=3 standbydelay=10800
11:00:04.626759 +0800   powerd 
11:00:14.070033 +0800   powerd  [System: PrevIdle DeclUser kDisp]
11:00:14.075280 +0800   powerd  Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active
11:00:19.092870 +0800   powerd 
11:00:19.093685 +0800   powerd 
12:48:12.255426 +0800   powerd 
12:48:12.257769 +0800   powerd  [System: PrevIdle DeclUser kDisp]

The above Power Management log excerpts shows two wake-up cycles spanning about one minute and each instance woke the system for about 15 seconds. The first wake-up cycle was at 10:59 and the second one was at 11:00. Then the system slept for about 48 minutes to be waken up again at 12:48. Similarly it had 54 minutes of sleep between 10:05 before the wake-up at 10:59.

These wake-ups consumed a good amount of percentage points in my relatively high-powered 2018 MacBook Pro when in stand-by for about eight hours. I forgot how much percentage points, but it was more than I was willing to “let go” for a new laptop with a new battery. Also either the more power-hungry DDR4 RAM or having 32 GiB of it seems more taxing on the battery as well.

Now that I knew what’s eating the battery — 30 second wake-ups every hour or so — I began to investigate what may be causing it.

Bluetooth

First I checked Bluetooth settings. In System Preferences, Bluetooth, Advanced, I cleared out the Allow Bluetooth devices to wake this computer checkbox. I don’t have Bluetooth keyboard, mouse, or trackpad. However I do have a QC35 Bluetooth headset and there were a few times where the headset woke up my laptop while it was in my bag, causing other troubles. So clearing this would be useful in any case.

Yes, the previous MacBook Pro died overheating in my bag. Apparently it did not fully sleep (or otherwise it woke up) while the clamshell was closed. I have suspicions it was the Bluetooth headset that caused it, since I have the headset recently paired to it. But in any case I couldn’t prove whether that was the cause of that incident. But let’s set that aside.

Apparently disabling Bluetooth wake-ups did not stop the unit from periodically waking up while in sleep mode. Hence I continued my diagnostics.

Power Nap

Then I checked the Power Nap configuration. Activating Power Nap allows the mac to check for mail and synchronize calendar updates, among other things. I normally have it turned off when on battery. However since I setup this laptop by restoring from Time Machine backup of another one, I just activated it and de-activated it just to make sure.

Again, activating and the activating Power Nap didn’t fix the issue.

TCP Keep-Alive

Looking at the Power Management log messages, I’ve noticed that in the Entering sleep state messages, there’s a suffix TCPKeepAlive and the value is either active or inactive:

21:47:59.161933 +0800   powerd  Entering Sleep state due to 'Clamshell Sleep':TCPKeepAlive=inactive

That gave me something more to Google on. In turn I stumbled on a Stack Exchange question of someone having a similar issue and suspected that it was due to Find My Mac.

Find My Mac allows you to locate your Mac if it gets lost or remotely erase the unit. It works by maintaining connection to Apple’s servers in conjunction with Wi-Fi geo-location. This is almost the same functionality as Find My iPhone to locate or erase an iOS device. However Find My Mac primarily relies on Wi-Fi connectivity since these laptops do not have cellular data connectivity nor GPS receivers.

Disabling Find My Mac seems to stop waking the unit mid-sleep. I’ve done a few rounds of tests and the TCPKeepAlive value above was pretty much always inactive, indicating that the unit won’t wake up to maintain network connections.

However completely disabling Find My Mac seems like a missed opportunity. It might be useful in case the unit really gets stolen and I needed to disable or erase it remotely. The feature also serves as a deterrent for rookie laptop thieves from stealing any more Apple devices in the future. Why rookie? Professional Apple snatchers would already know that a stolen unit can only be repurposed as spare parts due to this feature alone.

But realistically when a Mac gets stolen, it won’t likely be brought into familiar turf — areas where it already has the necessary Wi-Fi credentials to make a connection. Hence the only likely way for a stolen Mac to reconnect to the Internet is when the villain uses the Safari-Only Guest Account and enters his/her Wi-Fi password to access the Internet.

Hence, it would be nice if we can just turn of TCPKeepAlive when sleeping but keep Find My Mac enabled in the off-chance that the thief isn’t also a professional spare parts dealer.

Solution

Fortunately after some more Googling, I’ve found another tip from Stack Exchange to deactivate TCPKeepAlive. It uses a command-line tool thus only accessible from the Terminal app.

To prevent the mac from waking up just to refresh network connections while powered by battery, type the following command in the Terminal.

sudo pmset -b tcpkeepalive 0

You will need to be logged in using an account with administrative privileges, and you might be asked for your password. Furthermore it would likely warn you that this would reduce the functionality of Find My Mac.

The -b option means battery mode. There’s also a -c option which refers to being connected to the charger. For more information, type the following command into Terminal which would show all the options of the pmset command as well as some usage examples.

man pmset

With TCPKeepAlive disabled and on battery, I did some further tests. I closed the laptop, waited about 20 seconds or so, and then reopen it again. Afterwards I looked up the Power Management log for the corresponding event — this is the Clamshell Sleep event. True enough, in the log message it read TCPKeepAlive=disabled like the following:

18:42:18.633099 +0800   powerd  Entering Sleep state due to 'Clamshell Sleep':TCPKeepAlive=disabled

With this in mind, I’ve let the system to sleep for a few hours. When I woke it up, there were no messages from in the Power Management Log between roughly the time I’ve closed the lid forcing the system to go to sleep and the time I began using it again a few later. There was no noticeable battery drain as well.

Other Configuration Options

While investigating this, I found some interesting options in the power management configuration that’s somewhat useful to prolong battery life even further. These are centered on the mac’s many modes of sleeping.

  • Standby Delay
  • Hibernate Mode

By default, modern portable Macintosh systems uses safe sleep. When the laptop is put into sleep mode, it also saves the main memory contents into persistent storage. So that you don’t lose work just in case the battery runs out during sleep. It’s a combination of sleep and hibernation. If there’s enough remaining battery power, the system would quickly wake up from sleep. But if power was lost during sleep, it would resume from hibernation.

Standby Delay

Recent Macintosh portables with solid-state drives (SSD) adds another sleeping mode, which is called standby. In addition to safe sleep, if the unit hasn’t been used for a long time then it would enter hibernation automatically to preserve battery power for even longer. Resuming from SSD is pretty fast, and this feature could be useful when the laptop is put in storage over the weekend, for example.

Standby is controlled by the standby configuration of the pmset command. By default this should be 1 for SSD laptops — and I believe you shouldn’t change it unless you have a really good reason.

The time in which the laptop moves from sleep into standby is controlled by the standbydelayhigh and standbydelaylow parameters. Both are specified in seconds. The standbydelayhigh parameter specifies the time between sleep and standby (automatic hibernation) when the battery level is high — the default value is 24 hours or 86400 seconds. Whereas standbydelaylow is a similar time interval but when the battery level is low — default being three hours or 10800 seconds.

I couldn’t find any percentage values for the “high” nor “low” battery levels. In any case if you decide to change these values, be sure to have standbydelaylow to be much lower than standbydelayhigh and not swap the order of those time intervals. Also note that it takes a little bit longer to wake up from standby rather than regular sleep since the unit needs to read the memory contents from persistent storage.

For example if your laptop’s batteries are really old such that a night’s worth of sleep mode already takes 10% or more of your battery power, shorter standby delays would probably be useful. You can the following two commands to set the standby delays to one and four hours for the low and high battery levels, respectively. You might be asked for your administrative account’s password.

sudo pmset -b standbydelaylow 3600
sudo pmset -b standbydelayhigh 14400

You can see if the laptop woke up from hibernation when it shows the Apple logo just after you open the lid.  Furthermore after you enter your password, there would be a progress bar shown as it is loading memory contents from persistent storage.  This process would take almost as long as if you start the machine from a powered-down state.

Hibernate Mode

If you need your laptop to last longer in sleep mode, you could force it to hibernate each time you close the lid. The corresponding parameter in pmset controlling this is hibernatemode and has three useful values:

  • hibernatemode 0 — standard sleep, the default on Mac desktops. If power was cut off during sleep (or ran out of batteries for portables), the system would need to restart after power is restored.
  • hibernatemode 3 — safe sleep, the default on Mac portables. If the battery gets completely drained during sleep, the system would resume from hibernation after power is restored.
  • hibernatemode 25 — always hibernate. The system always goes to hibernation and do not require power. In this mode it always resumes from hibernation.

The always hibernate option is only configurable from pmset — there is no option in System Preferences to activate or de-activate it. Hence tread with care.

Run this command to enable the always hibernate option:

sudo pmset -a hibernatemode 25

Note that resuming from hibernation takes longer and consumes more energy than resuming from sleep — almost as long as a cold start. Therefore only set this if you really need it.

To get back to the default setting, run the following command on Mac desktops — iMac, iMac Pro, Mac Mini, or Mac Pro:

sudo pmset -a hibernatemode 0

Whereas the following command would set it back to default for Mac portables — MacBook, MacBook Air, or MacBook Pro:

sudo pmset -a hibernatemode 3

Anything Missing?

Any other energy-related toggles that you found useful and I haven’t covered? Please let me know.

Tags: , ,