Skip to content

Instantly share code, notes, and snippets.

@msimperi
Last active January 10, 2026 18:02
Show Gist options
  • Select an option

  • Save msimperi/b55c05f00691f99bb187f5ff054fbcf1 to your computer and use it in GitHub Desktop.

Select an option

Save msimperi/b55c05f00691f99bb187f5ff054fbcf1 to your computer and use it in GitHub Desktop.
macOS Sleep Battery Draining Temporary Fix (Turn Wifi + Bluetooth off when sleeping)

macOS Sleep Battery Draining Temporary Fix

This guide provides a workaround for macOS battery drain issues during sleep by automatically disabling Bluetooth and WiFi when the system sleeps and re-enabling them on wake.

Problem

macOS currently has issues with battery draining during sleep when Bluetooth and WiFi remain active.

Solution Overview

Use sleepwatcher to run scripts that:

  • Disable Bluetooth and WiFi when the system goes to sleep
  • Re-enable Bluetooth and WiFi when the system wakes up

Prerequisites

Install Required Tools

  1. Install Homebrew (if not already installed):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. Install sleepwatcher:
brew install sleepwatcher
  1. Install blueutil (for Bluetooth control):
brew install blueutil

Setup Instructions

Step 1: Create Sleep Script

Create ~/.sleep file:

cat > ~/.sleep << 'EOF'
#!/bin/bash
exec >> ~/lid-events.log 2>&1

echo "Lid closed or system sleeping at $(date)"

# Print battery level
echo "Battery level $(pmset -g batt | grep -Eo '\d+%' | cut -d% -f1)%"

# Run commands in background with nohup to avoid blocking sleep
nohup sh -c '/opt/homebrew/bin/blueutil --power 0 2>/dev/null; networksetup -setairportpower en0 off 2>/dev/null' &>/dev/null &

# Exit immediately to let system sleep
exit 0
EOF

Step 2: Create Wake Script

Create ~/.wakeup file:

cat > ~/.wakeup << 'EOF'
#!/bin/bash
exec >> ~/lid-events.log 2>&1

echo "Lid opened or system woke up at $(date)"

# Print battery level
echo "Battery level $(pmset -g batt | grep -Eo '\d+%' | cut -d% -f1)%"

/opt/homebrew/bin/blueutil --power 1; networksetup -setairportpower en0 on
EOF

Step 3: Set Permissions

Make scripts executable:

chmod +x ~/.sleep ~/.wakeup

Step 4: Start Sleepwatcher Service

Start and enable the service to run at login:

brew services start sleepwatcher

Step 5: Verify Service is Running

Check that sleepwatcher is active:

brew services list | grep sleepwatcher

You should see:

sleepwatcher started         [username] ~/Library/LaunchAgents/homebrew.mxcl.sleepwatcher.plist

Important Notes

First-Time Execution Permissions

⚠️ On first execution, macOS will likely prompt for permissions:

  1. Terminal/iTerm Access: You may need to grant Terminal or your terminal app permission to control system settings

    • Go to System Settings → Privacy & Security → Accessibility
    • Add and enable your terminal application
  2. Network Configuration Access: The networksetup command may trigger a permission dialog

    • Click "Allow" when prompted
  3. Automation Permissions: You might need to approve automation access

    • Go to System Settings → Privacy & Security → Automation
    • Enable necessary permissions for Terminal

Monitoring

Check the log file to verify it's working:

tail -f ~/lid-events.log

You should see entries like:

Lid closed or system sleeping at [timestamp]
Lid opened or system woke up at [timestamp]

Verify Bluetooth and WiFi Status

After sleep/wake, verify the radios are being controlled:

# Check Bluetooth status
blueutil --power

# Check WiFi status
networksetup -getairportpower en0

Troubleshooting

If Scripts Don't Execute

  1. Check sleepwatcher is running:
brew services list | grep sleepwatcher
  1. Restart the service:
brew services restart sleepwatcher
  1. Check for errors in system log:
log show --predicate 'process == "sleepwatcher"' --last 1h

If System Wakes Immediately After Sleep

This setup uses nohup and background execution to prevent immediate wake. If you still experience issues:

  1. Verify the .sleep script has the correct content with background execution
  2. Ensure you're using the exact script format provided above
  3. Check that blueutil is installed at /opt/homebrew/bin/blueutil

To Disable This Fix

If you want to stop using this workaround:

brew services stop sleepwatcher

To completely uninstall:

brew services stop sleepwatcher
brew uninstall sleepwatcher
rm ~/.sleep ~/.wakeup

Why This Works

  • sleepwatcher: Monitors system sleep/wake events and triggers scripts
  • Background execution: Using nohup and & prevents the commands from blocking the sleep process
  • Immediate exit: The script exits quickly, allowing the system to complete the sleep transition
  • Logging: All events are logged to ~/lid-events.log for troubleshooting

Note

This is a temporary workaround until Apple fixes the underlying battery drain issue in macOS. The solution has been tested and confirmed to work without causing immediate wake issues.

@pothi
Copy link

pothi commented Jan 10, 2026

Thanks for putting this together.

Instead of /opt/homebrew/bin/blueutil --power 1 && networksetup -setairportpower en0 on, it could be /opt/homebrew/bin/blueutil --power 1; networksetup -setairportpower en0 on so that if there is any issue turning on the Bluetooth, the next step goes on, like how the turn-off events run.

@msimperi
Copy link
Author

Thanks for putting this together.

Instead of /opt/homebrew/bin/blueutil --power 1 && networksetup -setairportpower en0 on, it could be /opt/homebrew/bin/blueutil --power 1; networksetup -setairportpower en0 on so that if there is any issue turning on the Bluetooth, the next step goes on, like how the turn-off events run.

Thanks @pothi for the comment! I agree fully. Changed the gist based on your suggestion 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment