Documentation
Configure and deploy Pulse for macOS performance monitoring.
Getting Started
Quick Start
Install Pulse
Download and run the PKG installer
Start Monitoring
Click the menu bar icon and press Start. Metrics are saved locally by default.
View Your Data
Open the dashboard from the menu bar or via CLI:
/usr/local/bin/pulse --dashboardEnterprise Quick Start
Deploy via MDM
Upload the PKG to Jamf, Kandji, Mosyle, or your MDM of choice
Configure via Profile
Deploy a Configuration Profile to customize settings across your fleet.
See MDM Settings & DownloadsOptional: Configure Splunk
Add HEC credentials to stream metrics to Splunk:
MDM Script Commands
Run via Jamf policy to start a timed monitoring session:
Use --interval and --duration to control collection frequency and session length.
CLI and MDM Settings Are Separate
There is no overlap between CLI and MDM settings. This is intentional:
MDM Controls (34 settings)
autoStart, storageEnabled, uploadEnabled, Splunk config, alerts, metric toggles, etc.
CLI Controls (4 settings)
--interval, --duration, --watch (one-shot), --headless (persists)
Common CLI Commands
--startStart monitoring--stopStop, upload, and quit--statusCheck current state--dashboardOpen dashboard--interval 10Collect every 10 sec--duration 60Stop after 60 min--headlessHide menu bar icon--no-headlessShow menu bar iconAll commands use /usr/local/bin/pulse — see CLI Reference for full options
Metrics
Pulse collects system metrics at configurable intervals. Each category can be toggled via the collect* preferences.
| Category | Key Fields |
|---|---|
| CPU | load_1m, load_5m, load_15m, cpu_user, cpu_sys, cpu_idle, thermal_state |
| Memory | mem_total_mb, mem_free_mb, mem_active_mb, memory_pressure, swap_used_mb |
| Disk | disk_total_gb, disk_free_gb, disk_kb_read_sec, disk_kb_write_sec |
| Network | net_bytes_in, net_bytes_out, interface, internet_connected |
| GPU | gpu_model, gpu_utilization_percent, top_gpu_processes |
| Power | battery_percent, battery_state, on_ac, on_battery |
| Processes | process_count, top_cpu_processes, top_mem_processes |
| System | uptime_seconds, macos_version, hardware_model, chip_description |
Configuration Reference
Preference Domain: com.qlabs.pulse
All settings can be configured via the Settings UI, defaults command, or MDM Configuration Profile. Settings deployed via MDM are locked in the UI.
MDM vs CLI Settings
Pulse has 34 MDM-manageable settings and 4 CLI-only settings.
CLI-only settings (--interval, --duration, --watch, --headless) are intentionally excluded from MDM profiles so IT can override them during troubleshooting sessions without MDM interference.
| CLI Flag | Preference Key | Description |
|---|---|---|
--interval <sec> | intervalSeconds | Collection interval (one-shot, cleared after session starts) |
--duration <min> | captureDurationMinutes | Auto-stop after N minutes (one-shot, cleared after session starts) |
--watch <name> | watchedProcesses | Watch specific processes by exact name (one-shot, repeatable) |
--headless | headlessMode | Enable headless mode (persists until --no-headless) |
--no-headless | headlessMode | Disable headless mode |
General
autoStartWhen enabled, Pulse automatically begins collecting metrics when the application launches. Useful for MDM deployments where monitoring should start without user interaction.
falsedefaults write com.qlabs.pulse autoStart -bool trueUser Interface
minimalUIShow the menu bar icon but hide the detailed metrics preview in the popover. Only status indicators are shown.
falsedefaults write com.qlabs.pulse minimalUI -bool trueverboseLoggingEnable detailed debug logging to ~/Library/Logs/Pulse/pulse.log. Includes per-collection timing, full configuration dumps, and detailed collector output. Disable after troubleshooting.
falsedefaults write com.qlabs.pulse verboseLogging -bool trueuiRefreshIntervalSecondsHow often to refresh CPU, memory, and process metrics in the popup (1-10 seconds). Only applies when the popup is open.
2defaults write com.qlabs.pulse uiRefreshIntervalSeconds -int 5showPIDsInUIShow process IDs in the process list UI. Disable for a cleaner display.
truedefaults write com.qlabs.pulse showPIDsInUI -bool falseMetric Collection Toggles
Each metric category can be independently enabled or disabled.
collectCPUCollect CPU load average (1m, 5m, 15m), usage breakdown (user, system, idle), and thermal throttle status. Essential for performance monitoring.
truedefaults write com.qlabs.pulse collectCPU -bool falsecollectMemoryCollect memory usage (active, wired, compressed, free), pressure level (normal, warning, critical), and swap activity. Critical for diagnosing slowdowns.
truedefaults write com.qlabs.pulse collectMemory -bool falsecollectDiskCollect disk space usage (total, used, free) and I/O throughput (read/write KB/s). Useful for monitoring storage-intensive workloads.
truedefaults write com.qlabs.pulse collectDisk -bool falsecollectNetworkCollect network interface statistics (bytes/packets in/out, errors) and connectivity status. Useful for diagnosing connectivity and bandwidth issues.
truedefaults write com.qlabs.pulse collectNetwork -bool falsecollectProcessesCollect top CPU and memory consuming processes. This is the most resource-intensive metric as it spawns /bin/ps for system-wide process visibility. Disable to reduce overhead on resource-constrained systems.
truedefaults write com.qlabs.pulse collectProcesses -bool falseaggregateProcessesCombine related processes by app name in the UI (e.g., all Chrome helpers shown as one entry). Useful when browsers/apps spawn many helper processes.
falsedefaults write com.qlabs.pulse aggregateProcesses -bool truecollectGPUCollect GPU utilization percentage, memory usage, and top GPU processes. Keep enabled for creative/video workloads. Can disable for general office use.
truedefaults write com.qlabs.pulse collectGPU -bool falsecollectPowerCollect battery state (charging, discharging, charged), power source (AC/battery), charge percentage, and sleep prevention assertions. Keep enabled for laptops. Can disable for desktop-only fleets.
truedefaults write com.qlabs.pulse collectPower -bool falsecollectSystemCollect uptime, macOS version, hardware model, CPU brand, and chip description. Low overhead, provides essential inventory data for fleet management.
truedefaults write com.qlabs.pulse collectSystem -bool falseLocal Storage
storageEnabledStore collected metrics locally in JSONL format. This is the default and recommended option.
truedefaults write com.qlabs.pulse storageEnabled -bool truemaxStorageMBMaximum disk space in megabytes for local metric storage. Oldest files are deleted when this limit is exceeded.
100defaults write com.qlabs.pulse maxStorageMB -int 500retentionDaysNumber of days to retain metric files before automatic deletion.
7defaults write com.qlabs.pulse retentionDays -int 30rotationPolicyHow often to rotate metric files. Each rotation creates a new timestamped file.
dailydefaults write com.qlabs.pulse rotationPolicy -string hourlySplunk Upload (Optional)
When Splunk upload is enabled, Pulse sends all collected metrics to your Splunk instance via HTTP Event Collector. This allows you to build dashboards, run queries, and correlate Mac telemetry with other data sources.
What appears in Splunk
- System metrics — CPU, memory, disk, network, GPU, and power data for each collection interval
- Top processes — The top 5 CPU and memory consuming processes each interval
- Pinned processes — When you pin a process in the menu bar, its CPU and memory usage is tracked in a dedicated
pinned_processesfield, allowing you to monitor specific apps across your fleet - Alert events — When CPU or memory pressure alerts trigger, a separate event is logged with
event_type: "alert", the threshold that was exceeded, and the processes responsible - Host identification — Each event includes hostname, serial number, hardware model, and macOS version for fleet-wide queries
Example Splunk queries
Find hosts with high memory pressure:
sourcetype="macos:pulse" memory_pressure="critical" | stats count by hostTrack a pinned app across all Macs:
sourcetype="macos:pulse" pinned_processes{}.name="Slack" | timechart avg(pinned_processes{}.cpu) by hostView all alert events:
sourcetype="macos:pulse" event_type="alert" | table _time host alert_type threshold valueuploadEnabledOptionally enable uploading metrics to Splunk via HTTP Event Collector. Requires hecEndpoint and hecToken to be configured.
falsedefaults write com.qlabs.pulse uploadEnabled -bool truehecEndpointFull URL to your Splunk HTTP Event Collector endpoint, including protocol, host, port, and path.
""defaults write com.qlabs.pulse hecEndpoint -string 'https://splunk.example.com:8088/services/collector/event'hecTokenAuthentication token for the Splunk HTTP Event Collector. Generated in Splunk under Settings > Data Inputs > HTTP Event Collector.
""defaults write com.qlabs.pulse hecToken -string 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'splunkIndexTarget Splunk index for metric events. The HEC token must have permission to write to this index.
maindefaults write com.qlabs.pulse splunkIndex -string 'macos_metrics'sourcetypeSplunk sourcetype assigned to uploaded events. Useful for parsing and searching.
macos:pulsedefaults write com.qlabs.pulse sourcetype -string 'pulse:metrics'verifySSLValidate the SSL certificate of the Splunk server. Disable for self-signed certificates in development environments.
truedefaults write com.qlabs.pulse verifySSL -bool falseuploadIntervalMinutesHow often to batch and upload metrics to Splunk, in minutes.
5defaults write com.qlabs.pulse uploadIntervalMinutes -int 1uploadBatchSizeMaximum number of metric records to include in each upload batch.
100defaults write com.qlabs.pulse uploadBatchSize -int 50Alerts
Native macOS notifications for high CPU usage and memory pressure events.
alertsEnabledEnable alert notifications. When disabled, no alerts are shown regardless of threshold violations.
falsedefaults write com.qlabs.pulse alertsEnabled -bool truealertCPUThresholdCPU usage percentage that triggers a high CPU alert. Value from 0-100.
90defaults write com.qlabs.pulse alertCPUThreshold -int 80alertSustainedSecondsNumber of seconds CPU must exceed threshold before triggering alert. Set to 0 for immediate alerts.
0defaults write com.qlabs.pulse alertSustainedSeconds -int 30alertMemoryPressureLevelMemory pressure level that triggers alerts. 0=disabled, 2=warning and critical, 4=critical only.
4defaults write com.qlabs.pulse alertMemoryPressureLevel -int 2alertCooldownMinutesMinimum time between repeated alerts of the same type to prevent notification spam.
15defaults write com.qlabs.pulse alertCooldownMinutes -int 30alertInBackgroundCheck thresholds even when monitoring is stopped. Uses 10-second check interval.
falsedefaults write com.qlabs.pulse alertInBackground -bool truealertMemorySustainedSecondsSeconds memory pressure must persist before alerting. 0 = immediate.
0defaults write com.qlabs.pulse alertMemorySustainedSeconds -int 30alertShowNotificationShow macOS notification when alert fires. Disable for silent logging only.
truedefaults write com.qlabs.pulse alertShowNotification -bool falsealertLogEventsLog alert events to storage for upload to Splunk. When disabled, alerts only trigger notifications.
truedefaults write com.qlabs.pulse alertLogEvents -bool falseCustom Alert Messages
alertCPUNotificationTitleCustom title for CPU alert notifications. Leave empty for default ('High CPU Usage').
""defaults write com.qlabs.pulse alertCPUNotificationTitle -string 'IT Alert: High CPU'alertCPUNotificationBodyCustom body for CPU alert notifications. Placeholders: {value} = current CPU %, {threshold} = configured threshold.
""defaults write com.qlabs.pulse alertCPUNotificationBody -string 'CPU is at {value}%, exceeds {threshold}%'alertMemoryNotificationTitleCustom title for memory alert notifications. Placeholder: {level} = 'warning' or 'critical'.
""defaults write com.qlabs.pulse alertMemoryNotificationTitle -string 'Memory Alert ({level})'alertMemoryNotificationBodyCustom body for memory alert notifications. Placeholder: {level} = 'warning' or 'critical'.
""defaults write com.qlabs.pulse alertMemoryNotificationBody -string 'Memory pressure is {level}. Please close unused apps.'MDM Deployment
Deploy Pulse configuration via MDM using a Configuration Profile targeting the com.qlabs.pulse preference domain.
Jamf Pro
Navigate to Computers → Configuration Profiles → Application & Custom Settings → External Applications → Add → Custom Schema. Upload the JSON schema above.
Manual Configuration Profile
Download the example .mobileconfig above and customize for your environment, or use the excerpt below.
Auto-Start Options
There are several ways to ensure Pulse starts automatically:
Option 1: MDM Configuration (Recommended)
Set autoStart: true in your Configuration Profile. Pulse will automatically begin monitoring when launched.
Combine with macOS Login Items (via MDM) to launch Pulse at user login.
Option 2: macOS Login Items
Users can add Pulse to System Settings → General → Login Items manually, or deploy via MDM using the com.apple.loginitems.managed payload.
Option 3: LaunchAgent (Advanced)
For headless deployments or advanced use cases, deploy a LaunchAgent via PKG installer. (Coming soon)
Dashboard
Built-in SwiftUI dashboard for local metric visualization. Works standalone without any external dependencies.
How to Open
- • Click chart icon in menu bar popover
- • Or: Settings → About → Open Dashboard
- • Or:
/usr/local/bin/pulse --dashboard
Features
- • Time range selector (All, Today, Yesterday, past 7 days)
- • Quick zoom buttons (1h, 4h, 24h) and custom date picker
- • Click + drag to zoom any chart
- • Hover for top processes at each point
- • Load external .jsonl files for analysis
What's Included
Summary Stats (aggregated over selected time range)
Time-Series Charts
Process Tables
Shows: Process name, Avg usage, Peak usage, Presence %, and Impact badge
Process Impact Classification
The process tables aggregate data across all samples and classify each process by its resource consumption pattern:
| Badge | Criteria | Meaning |
|---|---|---|
| 🔴 Sustained | ≥50% presence AND high avg usage | Persistent resource hog requiring attention |
| 🟡 Recurring | 15-50% presence | Periodic consumer, may warrant investigation |
| 🟢 Spike | <15% presence | Brief burst, typically not concerning |
High usage thresholds: ≥20% CPU average or ≥200 MB memory average. Tables sorted by resource-hours (CPU-Hrs or GB-Hrs).
Thermal States
| State | Level | Meaning |
|---|---|---|
| Nominal | 0 | Normal operating temperature |
| Fair | 1 | Elevated temperature, minor throttling possible |
| Serious | 2 | High temperature, significant throttling |
| Critical | 3 | Maximum throttling engaged to prevent damage |
Understanding CPU Percentages
CPU percentages are displayed differently depending on context:
| Location | Scale | Description |
|---|---|---|
| System CPU (charts) | 0-100% | Total CPU time spent on work (user + system). Always 0-100% regardless of core count. |
| Menu bar process list | Can exceed 100% | Raw per-process CPU from macOS. 200% means using 2 full cores. |
| Dashboard tooltips | 0-100% | Normalized: raw CPU ÷ core count. Easier to compare across machines. |
Example: A process using 400% CPU on a 10-core Mac shows as 400% in the menu bar list but 40% in dashboard tooltips.
CLI
Control Pulse from the command line for scripted deployments, troubleshooting sessions, and MDM automation.
| Argument | Description |
|---|---|
--start | Start monitoring (launches app if not running) |
--stop | Stop monitoring, upload pending logs, and quit app |
--quit | Quit app immediately without uploading |
--status | Print current status and exit |
--dashboard | Open the dashboard window |
--interval <sec> | Set collection interval in seconds (one-shot) |
--duration <min> | Set capture duration in minutes (one-shot, 0 = unlimited) |
--watch <name> | Watch a process by exact name (case-sensitive, repeatable, one-shot) |
--headless | Enable headless mode (persists until --no-headless) |
--no-headless | Disable headless mode |
--help | Show help message |
# Start monitoring with 8-hour limit
/usr/local/bin/pulse --start --duration 480
# Start with 10-second collection interval for 1 hour
/usr/local/bin/pulse --start --interval 10 --duration 60
# Watch specific processes (exact name, case-sensitive)
/usr/local/bin/pulse --start --watch "Google Chrome" --watch "zoom.us"
# Check current status
/usr/local/bin/pulse --status
# Open the dashboard
/usr/local/bin/pulse --dashboard
# Stop monitoring, upload pending logs, and quit
/usr/local/bin/pulse --stop
# Switch to headless mode (with 8-hour limit)
/usr/local/bin/pulse --headless --start --duration 480Running from Jamf or MDM Scripts
The pulse CLI wrapper at /usr/local/bin/pulse automatically handles user context elevation when run as root. This means Jamf and MDM scripts can call it directly without manual launchctl asuser handling.
#!/bin/bash
# Start an 8-hour monitoring session
# The pulse wrapper handles user context automatically
/usr/local/bin/pulse --start --duration 480#!/bin/bash
# Stop monitoring and upload pending logs
/usr/local/bin/pulse --stopImportant Notes for Enterprise Admins
- User context handled automatically — The
/usr/local/bin/pulsewrapper detects when run as root and automatically elevates to the logged-in user context - One-shot settings —
--interval,--duration, and--watchare cleared after monitoring starts. They apply only to the current session and won't persist after a restart - Headless mode persists — Unlike one-shot settings,
--headlessremains enabled until explicitly disabled with--no-headless - Headless requires a destination — In headless mode, monitoring only auto-starts if local storage or Splunk upload is configured. Without a destination, the app launches but won't collect
- Duration expiry — When
--durationexpires, monitoring stops automatically. The app remains running (useful for viewing collected data) but won't collect new metrics until restarted
Files & Logging
Pulse stores metrics, logs, and preferences in standard macOS locations. Understanding these paths is essential for troubleshooting and log management.
File Locations
~/Library/Application Support/Pulse/JSON files containing collected metrics. One file per collection session.
~/Library/Logs/Pulse/pulse.logRuntime logs including errors, warnings, and debug info when enabled.
com.qlabs.pulseUserDefaults domain for all configuration. Managed via MDM or CLI.
/usr/local/bin/pulseWrapper script for Jamf/MDM. Handles user context elevation automatically.
Logging
Pulse writes runtime logs to ~/Library/Logs/Pulse/pulse.log. By default, only warnings and errors are logged. Enable verbose logging to include debug and info messages.
Enable Verbose Logging
Verbose logging includes debug and info messages for detailed troubleshooting. Enable it in the app or via command line.
defaults write com.qlabs.pulse verboseLogging -bool trueView Logs
Use standard macOS tools to view and monitor logs in real-time.
tail -f ~/Library/Logs/Pulse/pulse.loggrep -i "error\|warn" ~/Library/Logs/Pulse/pulse.log | tail -20open -a Console ~/Library/Logs/Pulse/pulse.logLog Format
Each log entry includes timestamp (local time), level, category, and message.
Managing Logs
Logs are written to a single file that grows over time. To clear logs, delete the file manually:
rm ~/Library/Logs/Pulse/pulse.logTroubleshooting
App doesn't appear in menu bar
- Check headless mode:
defaults read com.qlabs.pulse headlessMode - Disable headless:
/usr/local/bin/pulse --no-headless - Verify running:
pgrep -x Pulse
No metrics being collected
- Verify monitoring started (button shows "Stop")
- Check destination configured (local storage or Splunk)
- Check status:
/usr/local/bin/pulse --status
Can't connect to Splunk
- Verify HEC URL format:
https://host:8088/services/collector/event - Test token:
curl -k $URL -H "Authorization: Splunk $TOKEN" -d '{"event":"test"}' - Try
verifySSL: falsefor self-signed certificates
See Files & Logging for information on enabling verbose logging, log format, and file locations.