Fixing MacBook Pro Sleep Problems


Apple Logo

One of the things I loved about my Powerbook was that it slept--and woke--reliably. I would go weeks without rebooting my machine and I bragged about it often to the poor saps who had to use XP on their laptops. I haven't been singing the praises of OS X stability as loudly lately because ever since I went to the Mac Book Pro (MBP), my machine has had issues with sleeping and waking to the point that it probably got rebooted once a day.

Well, no more! I tried something a few weeks ago that has made my MBP into a machine I can love again. Here's what I did.

When Apple shipped the MBP, they changed how sleep works. What? Mess with perfection? Yup, that's what they did, although they had a reason (I'm not saying it's a good one). The old Powerbooks could tolerate a battery switch when they were asleep without losing state. The MBPs can't. If you put your MBP to sleep, switch batteries, and then wake it, you'll note you've see a whited-out screen and a progress bar at the bottom. The machine is waking from hibernation. If you pop a battery out of a sleeping MBP, it automatically hibernates.

In order support this automatic hibernation, the machine has to write the contents of RAM to disk every time it goes to sleep. This is called "SafeSleep" by Apple. I call it "SureDeath." That's why putting a MBP to sleep takes to long. For whatever reason, that process seemed to be causing problems for me. Maybe because I've frequently got almost 4Gb of RAM in use with virtual machines, and so on. Often my machine would refuse to sleep or never wake up once it got there.

Here's the good news: Apple left the old mode in the OS and you can activate it if you want. You can also switch back to SafeSleep anytime you like. According to this MacWorld article, OS X supports five different sleep modes:

  • 0 - Old style sleep mode, with RAM powered on while sleeping, safe sleep disabled, and super-fast wake.
  • 1 - Hibernation mode, with RAM contents written to disk, system totally shut down while "sleeping," and slower wake up, due to reading the contents of RAM off the hard drive.
  • 3 - The default mode on machines introduced since about fall 2005. RAM is powered on while sleeping, but RAM contents are also written to disk before sleeping. In the event of total power loss, the system enters hibernation mode automatically.
  • 5 - This is the same as mode 1, but it's for those using secure virtual memory (in System Preferences -> Security).
  • 7 - This is the same as mode 3, but it's for those using secure virtual memory.
From Macworld: Mac OS X Hints: Set newer portable Macs' sleep mode
Referenced Wed Oct 17 2007 09:58:31 GMT-0600 (MDT)

The first step is to check which mode you're in now. Use this command from the terminal:

pmset -g | grep hibernatemode

Make a note of which mode it is (probably 3) so that you can return to it if you want.

Now, set your MBP to use mode 0:

sudo pmset -a hibernatemode 0

That's it. I rebooted. Not sure it that's necessary, but what the heck.

Now, you may be wondering...if my MBP was writing memory out to disk, is that stored somewhere, taking up precious disk space? Yes! Here's how to recover it:

sudo rm /var/vm/sleepimage 

My sleep image was 4Gb since that's how much memory I have. Nice to have it back.

Now, a word of warning: if you change to sleep mode 0 on a MBP, you lose the ability to do a battery swap without plugging the machine in. I only do that occasionally, so I'm happy to forego the feature if my machine works more reliably every day.

As I said, I made this change two weeks ago and my machine has been as stable as my old Powerbook every since. I'm happy to have solved one of the annoyances of my computing life. As always...YMMV.

Update: Bryan Morse made me aware of this Tidbits article that contains a script you can run as a cron job that will put you in hibernate mode when your battery gets low. Some people have reported that occasionally OS X will switch the mode back to 3 so you have to check to make sure you're still in 0 (and delete the sleepimage file). This script does that as well.