
Have you ever noticed your Mac's fan spinning wildly but couldn't quickly identify which process was consuming all your CPU?
As a developer who uses Visual Studio Code daily, I rely heavily on its rich ecosystem of extensions to boost my productivity. But over time, I started noticing my MacBook Air heating up, the fans spinning loudly, and my system becoming sluggish — all while I was just editing code. When I opened the Activity Monitor, I saw one or more mysterious "Code Helper (Plugin)" processes consuming 90–100% CPU, but there was no clear indication of which extension was responsible.
VS Code spawns multiple helper processes, and most of them are generically named, making it incredibly difficult to trace high CPU usage back to a specific extension. This left me guessing — was it Copilot? ESLint? Live Server? I needed a way to monitor these extensions intelligently, without sacrificing performance or productivity.
That's what led me to build a solution — a lightweight tool that monitors CPU usage in real time, maps it to the responsible extension, and alerts me before things spiral out of control. Today, I'll walk you through building a lightweight, real-time CPU monitoring tool that lives in your macOS menu bar and sends notifications when processes exceed your defined thresholds.
What We're Building
Our CPU monitor will:
Display CPU status directly in the menu bar
Alert you when any process exceeds 80% CPU usage
Send native macOS notifications for high CPU processes
Provide special handling for VS Code extensions and helpers
Show detailed process information (PID, name, command)
Indicate when all processes are running normally
Prerequisites
Before we start, you'll need:
macOS (this guide is macOS-specific)
xbar installed (formerly BitBar)
Basic familiarity with shell scripting
The Architecture
Our solution uses a simple but effective approach:
xbar Integration: The script runs every 5 minutes (indicated by the
.5m.
in the filename)Process Monitoring: We use
ps
to capture all running processes with their CPU usageThreshold Detection: Any process using more than 80% CPU triggers an alert
Native Notifications: We leverage macOS's
osascript
for system notificationsFallback Support: Includes support for
terminal-notifier
as a backup
The Complete Script
Here's the full vscode-ext-monitor.5m.sh
script:
#!/bin/bash
CPU_THRESHOLD=80.0
HIGH_CPU_FOUND=0
# Menu Bar Title
echo "🖥️ CPU Monitor"
# Store process information in a temporary file to avoid subshell issues
TEMP_FILE=$(mktemp)
ps -Ao pid,%cpu,command | grep -v "ps -Ao" | grep -v grep > "$TEMP_FILE"
# Read from the temporary file
while IFS= read -r line; do
if [ -z "$line" ]; then
continue
fi
cpu=$(echo "$line" | awk '{print $2}')
pid=$(echo "$line" | awk '{print $1}')
command=$(echo "$line" | cut -d ' ' -f3-)
# Skip if CPU is not a valid number or is 0.0
if ! echo "$cpu" | grep -q '^[0-9]*\.[0-9]*$' || [ "$cpu" = "0.0" ]; then
continue
fi
is_high=$(echo "$cpu > $CPU_THRESHOLD" | bc)
if [ "$is_high" -eq 1 ]; then
HIGH_CPU_FOUND=1
echo "---"
echo "⚠️ High CPU ($cpu%)"
echo "PID: $pid"
# Get process name from command
process_name=$(echo "$command" | awk '{print $1}' | xargs basename 2>/dev/null || echo "Unknown")
echo "📱 Process: $process_name"
# Show truncated command
echo "💻 ${command:0:60}..."
notification_title="From CPU Monitor"
# Special handling for different process types
if echo "$command" | grep -q ".vscode/extensions"; then
ext=$(echo "$command" | grep -o "/Users/[^ ]*\.vscode/extensions/[^ ]*")
echo "🧩 VS Code Extension: $(basename "$ext")"
notification_message="High CPU: ${cpu}% by VS Code extension $(basename "$ext")"
elif echo "$command" | grep -q "Code Helper"; then
echo "🔧 VS Code Helper Process"
notification_message="High CPU: ${cpu}% by VS Code Helper"
else
notification_message="High CPU: ${cpu}% by $process_name"
fi
# Desktop notification (macOS only) - with error handling
if command -v osascript >/dev/null 2>&1; then
osascript -e "display notification \"$notification_message\" with title \"$notification_title\"" 2>/dev/null || {
# Fallback: try using terminal-notifier if available
if command -v terminal-notifier >/dev/null 2>&1; then
terminal-notifier -title "$notification_title" -message "$notification_message" 2>/dev/null
fi
}
fi
fi
done < "$TEMP_FILE"
# Clean up temporary file
rm -f "$TEMP_FILE"
if [ "$HIGH_CPU_FOUND" -eq 0 ]; then
echo "---"
echo "✅ All processes under ${CPU_THRESHOLD}%"
fi
Key Technical Decisions
1. Avoiding Subshell Issues
Initially, we faced a common bash pitfall where notifications wouldn't work because the while
loop was running in a subshell:
# This doesn't work for GUI operations
ps ... | while read line; do
osascript -e "display notification ..."
done
Solution: We use a temporary file approach to avoid the subshell:
TEMP_FILE=$(mktemp)
ps -Ao pid,%cpu,command > "$TEMP_FILE"
while read line; do
# Process data and send notifications
done < "$TEMP_FILE"
rm -f "$TEMP_FILE"
2. Robust CPU Validation
We validate CPU values to ensure we're working with actual numeric data:
if ! echo "$cpu" | grep -q '^[0-9]*\.[0-9]*$' || [ "$cpu" = "0.0" ]; then
continue
fi
This prevents errors from malformed process data.
3. Smart Process Classification
The script intelligently categorizes processes:
VS Code Extensions: Detected by
.vscode/extensions
in the command pathVS Code Helpers: Identified by "Code Helper" in the command
General Processes: Everything else gets generic handling
4. Notification Reliability
We implement a two-tier notification system:
osascript -e "display notification ..." 2>/dev/null || {
# Fallback to terminal-notifier if available
if command -v terminal-notifier >/dev/null 2>&1; then
terminal-notifier -title "..." -message "..."
fi
}
Installation and Setup
Install xbar if you haven't already:
brew install --cask xbar
Create the plugin directory:
mkdir -p "$HOME/Library/Application Support/xbar/plugins"
Save the script as
vscode-ext-monitor.5m.sh
in the plugins directoryMake it executable:
chmod +x "$HOME/Library/Application Support/xbar/plugins/vscode-ext-monitor.5m.sh"
Launch xbar and refresh to see your new CPU monitor
Customization Options
Adjust the CPU Threshold
Change the threshold by modifying this line:
CPU_THRESHOLD=80.0 # Change to your preferred percentage
Modify the Update Frequency
Rename the file to change how often it runs:
Add More Process Types
Extend the classification logic:
elif echo "$command" | grep -q "chrome"; then
echo "🌐 Chrome Process"
notification_message="High CPU: ${cpu}% by Chrome"
Troubleshooting
Notifications Not Appearing?
Check System Preferences: Ensure notifications are enabled for Terminal in System Preferences > Notifications & Focus
Test manually:
osascript -e 'display notification "Test" with title "Test"'
Install terminal-notifier as backup:
brew install terminal-notifier
Script Not Running?
Verify file permissions:
ls -la "$HOME/Library/Application Support/xbar/plugins/"
Check xbar is running and refresh the menu
Test the script manually:
cd "$HOME/Library/Application Support/xbar/plugins/" ./vscode-ext-monitor.5m.sh
What's Next?
This CPU monitor provides a solid foundation that you can extend further:
Memory Monitoring: Add RAM usage alerts
Network Activity: Monitor processes with high network usage
Historical Tracking: Log high CPU events to a file
Kill Process Feature: Add menu options to terminate problematic processes
Custom Thresholds: Different thresholds for different process types
Conclusion
Building system monitoring tools doesn't require complex frameworks or heavy applications. With a simple bash script and xbar, we've created a lightweight, effective CPU monitor that:
Provides real-time visibility into system performance
Sends proactive notifications before problems escalate
Offers detailed process information for quick troubleshooting
Runs efficiently with minimal system overhead
The beauty of this approach is its simplicity and customizability. You have full control over the monitoring logic, notification behavior, and display format. Plus, since it's just a bash script, you can easily modify it to suit your specific needs.
This CPU monitor has been tested on macOS Sequoia and later. The script should work on earlier versions but may require minor adjustments for notification handling.
I share tips on how to get started with freelancing, remote jobs, developer-related stuff, startup ecosystem, and lots of insider secrets with my subscribers.