Recently I discovered that my MacBook Pro battery drains completely overnight. This started sometime after upgrading to macOS Catalina.
The TL;DR version is – disable TCP keepalive while asleep.
For the full details – read on.
I looked at the available power saving settings in the UI but did not find anything that would explain it. The Activity Monitor also did not provide any obvious clues.
This was a bit disappointing as the machine is a 2018 15″ MacBook, therefore I expected to the battery life to be really good.
There are plenty of threads on the internet with similar complaints, but they mostly suggest disabling things left and right, without really explaining why that should help.
And what puzzled (and still does) me the most was that how come it used to work just fine before, what is triggering it now?
Turns out that you can see the wake events in the logs by doing something similar to
log show --style syslog --last 300m | fgrep "Wake reason"
On my machine I saw bunch of lines like:
2020-01-03 07:44:33.103996+0200 localhost kernel[0]: (AppleTopCaseHIDEventDriver) [HID] [ATC] AppleDeviceManagementHIDEventService::processWakeReason Wake reason: Host (0x01) 2020-01-03 07:44:33.825185+0200 localhost kernel[0]: (AppleTopCaseHIDEventDriver) [HID] [ATC] AppleDeviceManagementHIDEventService::processWakeReason Wake reason: Host (0x01) 2020-01-03 07:45:26.413995+0200 localhost kernel[0]: (AppleACPIPlatform) AppleACPIPlatformPower Wake reason: EC.ARPT (Maintenance) 2020-01-03 07:45:26.413998+0200 localhost kernel[0]: (AppleACPIPlatform) AppleACPIPlatformPower Wake reason: EC.ARPT (Maintenance) 2020-01-03 07:45:51.486356+0200 localhost corespeechd[528]: [com.apple.corespeech:Framework] -[CSHostDaemonMac _isWakeReasonVoiceTrigger] Wake reason: <private> 2020-01-03 07:45:51.486367+0200 localhost corespeechd[528]: [com.apple.corespeech:Framework] -[CSHostDaemonMac _getPowerAssertionIfWakenByVoiceTriggerNotFromS3Sleep] Wake reason is not VoiceTrigger or it woke from S3
Note the reason – Wake reason: EC.ARPT
More googling told me that this means – Airport, which means something with wifi. OK, so the machine is waking up to do something with the network? Interesting.
Another useful command I discovered was pmset
, which had especially useful argument to show logs – pmset -g log
This one also showed that waking happens because of network:
2020-01-03 08:50:27 +0200 Assertions PID 246(mDNSResponder) Created MaintenanceWake "mDNSResponder:maintenance" 00:00:00 id:0x0xd0000a385 [System: No Assertions] 2020-01-03 08:50:27 +0200 Assertions PID 246(mDNSResponder) Released MaintenanceWake "mDNSResponder:maintenance" 00:00:00 id:0x0xd0000a385 [System: No Assertions] 2020-01-03 08:50:29 +0200 Assertions PID 125(powerd) Created InternalPreventSleep "PM configd - Wait for Device enumeration" 00:00:00 id:0x0xd0000a387 [System: No Assertions] 2020-01-03 08:50:29 +0200 DarkWake DarkWake from Normal Sleep [CDN] : due to EC.ARPT/Maintenance Using BATT (Charge:96%) 45 secs 2020-01-03 08:50:29 +0200 WakeDetails DriverReason:WLC_E_TKO - DriverDetails: 2020-01-03 08:50:29 +0200 HibernateStats hibmode=3 standbydelaylow=10800 standbydelayhigh=86400 6382 2020-01-03 08:50:29 +0200 WakeTime WakeTime: 2.367 sec
OK, the pmset
command also has quite useful manpage.
After seeing the output of pmset -g
, where it lists all the settings that are related to sleeping I was wondering what tcpkeepalive
has to do with sleeping. Why yes, I have noticed that whenever I open my macbook, the wifi works instantly and my SSH sessions are all still active, but I never put too much thought to the fact that in order for this all to work, of course a TCP keepalive is periodically sent out.
OK, so I disable tcpkeepalive
while sleeping with:
sudo pmset -b tcpkeepalive 0
And the problem disappeared.
How anticlimactic.
Now, of course, I cannot benefit from all the nice features that the keepalive was providing me and I still don’t understand what changed, why this always worked and now it does not?
However what disappoints me the most is that this is a problem for many users (lots of posts on forums), and Apple is just pretending not to see it.
I mean. It should “just work”. Why do I need to mess with my power settings on my 3K+ laptop?
If only I would not be invested into the Apple ecosystem…