Documentation

Configure and deploy Pulse for macOS performance monitoring.

Getting Started

macOS 14.0 (Sonoma) or later
Apple Silicon or Intel Mac
Splunk HEC (optional)
For Individual Users

Quick Start

1

Install Pulse

Download and run the PKG installer

2

Start Monitoring

Click the menu bar icon and press Start. Metrics are saved locally by default.

3

View Your Data

Open the dashboard from the menu bar or via CLI:

/usr/local/bin/pulse --dashboard
For IT / Enterprise

Enterprise Quick Start

1

Deploy via MDM

Upload the PKG to Jamf, Kandji, Mosyle, or your MDM of choice

2

Configure via Profile

Deploy a Configuration Profile to customize settings across your fleet.

See MDM Settings & Downloads
3

Optional: Configure Splunk

Add HEC credentials to stream metrics to Splunk:

hecEndpoint: https://...hecToken: xxx-xxx
4

MDM Script Commands

Run via Jamf policy to start a timed monitoring session:

# 8-hour session with 10-second intervals
/usr/local/bin/pulse --headless --start --interval 10 --duration 480

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 icon

All 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.

CategoryKey Fields
CPUload_1m, load_5m, load_15m, cpu_user, cpu_sys, cpu_idle, thermal_state
Memorymem_total_mb, mem_free_mb, mem_active_mb, memory_pressure, swap_used_mb
Diskdisk_total_gb, disk_free_gb, disk_kb_read_sec, disk_kb_write_sec
Networknet_bytes_in, net_bytes_out, interface, internet_connected
GPUgpu_model, gpu_utilization_percent, top_gpu_processes
Powerbattery_percent, battery_state, on_ac, on_battery
Processesprocess_count, top_cpu_processes, top_mem_processes
Systemuptime_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 FlagPreference KeyDescription
--interval <sec>intervalSecondsCollection interval (one-shot, cleared after session starts)
--duration <min>captureDurationMinutesAuto-stop after N minutes (one-shot, cleared after session starts)
--watch <name>watchedProcessesWatch specific processes by exact name (one-shot, repeatable)
--headlessheadlessModeEnable headless mode (persists until --no-headless)
--no-headlessheadlessModeDisable headless mode

General

autoStart
Boolean

When enabled, Pulse automatically begins collecting metrics when the application launches. Useful for MDM deployments where monitoring should start without user interaction.

Default: false
Example: defaults write com.qlabs.pulse autoStart -bool true

User Interface

minimalUI
Boolean

Show the menu bar icon but hide the detailed metrics preview in the popover. Only status indicators are shown.

Default: false
Example: defaults write com.qlabs.pulse minimalUI -bool true
verboseLogging
Boolean

Enable detailed debug logging to ~/Library/Logs/Pulse/pulse.log. Includes per-collection timing, full configuration dumps, and detailed collector output. Disable after troubleshooting.

Default: false
Example: defaults write com.qlabs.pulse verboseLogging -bool true
uiRefreshIntervalSeconds
Integer

How often to refresh CPU, memory, and process metrics in the popup (1-10 seconds). Only applies when the popup is open.

Default: 2
Example: defaults write com.qlabs.pulse uiRefreshIntervalSeconds -int 5
showPIDsInUI
Boolean

Show process IDs in the process list UI. Disable for a cleaner display.

Default: true
Example: defaults write com.qlabs.pulse showPIDsInUI -bool false

Metric Collection Toggles

Each metric category can be independently enabled or disabled.

collectCPU
Boolean

Collect CPU load average (1m, 5m, 15m), usage breakdown (user, system, idle), and thermal throttle status. Essential for performance monitoring.

Default: true
Example: defaults write com.qlabs.pulse collectCPU -bool false
collectMemory
Boolean

Collect memory usage (active, wired, compressed, free), pressure level (normal, warning, critical), and swap activity. Critical for diagnosing slowdowns.

Default: true
Example: defaults write com.qlabs.pulse collectMemory -bool false
collectDisk
Boolean

Collect disk space usage (total, used, free) and I/O throughput (read/write KB/s). Useful for monitoring storage-intensive workloads.

Default: true
Example: defaults write com.qlabs.pulse collectDisk -bool false
collectNetwork
Boolean

Collect network interface statistics (bytes/packets in/out, errors) and connectivity status. Useful for diagnosing connectivity and bandwidth issues.

Default: true
Example: defaults write com.qlabs.pulse collectNetwork -bool false
collectProcesses
Boolean

Collect 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.

Default: true
Example: defaults write com.qlabs.pulse collectProcesses -bool false
aggregateProcesses
Boolean

Combine 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.

Default: false
Example: defaults write com.qlabs.pulse aggregateProcesses -bool true
collectGPU
Boolean

Collect GPU utilization percentage, memory usage, and top GPU processes. Keep enabled for creative/video workloads. Can disable for general office use.

Default: true
Example: defaults write com.qlabs.pulse collectGPU -bool false
collectPower
Boolean

Collect 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.

Default: true
Example: defaults write com.qlabs.pulse collectPower -bool false
collectSystem
Boolean

Collect uptime, macOS version, hardware model, CPU brand, and chip description. Low overhead, provides essential inventory data for fleet management.

Default: true
Example: defaults write com.qlabs.pulse collectSystem -bool false

Local Storage

storageEnabled
Boolean

Store collected metrics locally in JSONL format. This is the default and recommended option.

Default: true
Example: defaults write com.qlabs.pulse storageEnabled -bool true
maxStorageMB
Integer

Maximum disk space in megabytes for local metric storage. Oldest files are deleted when this limit is exceeded.

Default: 100
Example: defaults write com.qlabs.pulse maxStorageMB -int 500
retentionDays
Integer

Number of days to retain metric files before automatic deletion.

Default: 7
Example: defaults write com.qlabs.pulse retentionDays -int 30
rotationPolicy
String

How often to rotate metric files. Each rotation creates a new timestamped file.

Default: daily
Values: daily, hourly
Example: defaults write com.qlabs.pulse rotationPolicy -string hourly

Splunk 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_processes field, 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 host

Track a pinned app across all Macs:

sourcetype="macos:pulse" pinned_processes{}.name="Slack" | timechart avg(pinned_processes{}.cpu) by host

View all alert events:

sourcetype="macos:pulse" event_type="alert" | table _time host alert_type threshold value
uploadEnabled
Boolean

Optionally enable uploading metrics to Splunk via HTTP Event Collector. Requires hecEndpoint and hecToken to be configured.

Default: false
Example: defaults write com.qlabs.pulse uploadEnabled -bool true
hecEndpoint
String

Full URL to your Splunk HTTP Event Collector endpoint, including protocol, host, port, and path.

Default: ""
Example: defaults write com.qlabs.pulse hecEndpoint -string 'https://splunk.example.com:8088/services/collector/event'
hecToken
String

Authentication token for the Splunk HTTP Event Collector. Generated in Splunk under Settings > Data Inputs > HTTP Event Collector.

Default: ""
Example: defaults write com.qlabs.pulse hecToken -string 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
splunkIndex
String

Target Splunk index for metric events. The HEC token must have permission to write to this index.

Default: main
Example: defaults write com.qlabs.pulse splunkIndex -string 'macos_metrics'
sourcetype
String

Splunk sourcetype assigned to uploaded events. Useful for parsing and searching.

Default: macos:pulse
Example: defaults write com.qlabs.pulse sourcetype -string 'pulse:metrics'
verifySSL
Boolean

Validate the SSL certificate of the Splunk server. Disable for self-signed certificates in development environments.

Default: true
Example: defaults write com.qlabs.pulse verifySSL -bool false
uploadIntervalMinutes
Integer

How often to batch and upload metrics to Splunk, in minutes.

Default: 5
Example: defaults write com.qlabs.pulse uploadIntervalMinutes -int 1
uploadBatchSize
Integer

Maximum number of metric records to include in each upload batch.

Default: 100
Example: defaults write com.qlabs.pulse uploadBatchSize -int 50

Alerts

Native macOS notifications for high CPU usage and memory pressure events.

alertsEnabled
Boolean

Enable alert notifications. When disabled, no alerts are shown regardless of threshold violations.

Default: false
Example: defaults write com.qlabs.pulse alertsEnabled -bool true
alertCPUThreshold
Integer

CPU usage percentage that triggers a high CPU alert. Value from 0-100.

Default: 90
Example: defaults write com.qlabs.pulse alertCPUThreshold -int 80
alertSustainedSeconds
Integer

Number of seconds CPU must exceed threshold before triggering alert. Set to 0 for immediate alerts.

Default: 0
Example: defaults write com.qlabs.pulse alertSustainedSeconds -int 30
alertMemoryPressureLevel
Integer

Memory pressure level that triggers alerts. 0=disabled, 2=warning and critical, 4=critical only.

Default: 4
Values: 0 (disabled), 2 (warning+critical), 4 (critical only)
Example: defaults write com.qlabs.pulse alertMemoryPressureLevel -int 2
alertCooldownMinutes
Integer

Minimum time between repeated alerts of the same type to prevent notification spam.

Default: 15
Example: defaults write com.qlabs.pulse alertCooldownMinutes -int 30
alertInBackground
Boolean

Check thresholds even when monitoring is stopped. Uses 10-second check interval.

Default: false
Example: defaults write com.qlabs.pulse alertInBackground -bool true
alertMemorySustainedSeconds
Integer

Seconds memory pressure must persist before alerting. 0 = immediate.

Default: 0
Example: defaults write com.qlabs.pulse alertMemorySustainedSeconds -int 30
alertShowNotification
Boolean

Show macOS notification when alert fires. Disable for silent logging only.

Default: true
Example: defaults write com.qlabs.pulse alertShowNotification -bool false
alertLogEvents
Boolean

Log alert events to storage for upload to Splunk. When disabled, alerts only trigger notifications.

Default: true
Example: defaults write com.qlabs.pulse alertLogEvents -bool false

Custom Alert Messages

alertCPUNotificationTitle
String

Custom title for CPU alert notifications. Leave empty for default ('High CPU Usage').

Default: ""
Example: defaults write com.qlabs.pulse alertCPUNotificationTitle -string 'IT Alert: High CPU'
alertCPUNotificationBody
String

Custom body for CPU alert notifications. Placeholders: {value} = current CPU %, {threshold} = configured threshold.

Default: ""
Example: defaults write com.qlabs.pulse alertCPUNotificationBody -string 'CPU is at {value}%, exceeds {threshold}%'
alertMemoryNotificationTitle
String

Custom title for memory alert notifications. Placeholder: {level} = 'warning' or 'critical'.

Default: ""
Example: defaults write com.qlabs.pulse alertMemoryNotificationTitle -string 'Memory Alert ({level})'
alertMemoryNotificationBody
String

Custom body for memory alert notifications. Placeholder: {level} = 'warning' or 'critical'.

Default: ""
Example: 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)

Avg CPU IdleAvg CPU UsagePeak ThermalPeak Mem PressureAvg SwapAvg BatteryAvg GPUAvg Disk Free

Time-Series Charts

CPU UsageMemoryThermal StateMemory PressureSwapDisk I/ONetworkGPUBattery

Process Tables

Top CPU ProcessesTop Memory ProcessesTop Network Processes

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:

BadgeCriteriaMeaning
🔴 Sustained≥50% presence AND high avg usagePersistent resource hog requiring attention
🟡 Recurring15-50% presencePeriodic consumer, may warrant investigation
🟢 Spike<15% presenceBrief 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

StateLevelMeaning
Nominal0Normal operating temperature
Fair1Elevated temperature, minor throttling possible
Serious2High temperature, significant throttling
Critical3Maximum throttling engaged to prevent damage

Understanding CPU Percentages

CPU percentages are displayed differently depending on context:

LocationScaleDescription
System CPU (charts)0-100%Total CPU time spent on work (user + system). Always 0-100% regardless of core count.
Menu bar process listCan exceed 100%Raw per-process CPU from macOS. 200% means using 2 full cores.
Dashboard tooltips0-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.

ArgumentDescription
--startStart monitoring (launches app if not running)
--stopStop monitoring, upload pending logs, and quit app
--quitQuit app immediately without uploading
--statusPrint current status and exit
--dashboardOpen 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)
--headlessEnable headless mode (persists until --no-headless)
--no-headlessDisable headless mode
--helpShow help message
Example Usage
# 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 480

Running 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.

Jamf Policy Script
#!/bin/bash
# Start an 8-hour monitoring session
# The pulse wrapper handles user context automatically
/usr/local/bin/pulse --start --duration 480
Stop Monitoring Script
#!/bin/bash
# Stop monitoring and upload pending logs
/usr/local/bin/pulse --stop

Important Notes for Enterprise Admins

  • User context handled automatically — The /usr/local/bin/pulse wrapper detects when run as root and automatically elevates to the logged-in user context
  • One-shot settings--interval, --duration, and --watch are 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, --headless remains 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 --duration expires, 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

Metrics Data
~/Library/Application Support/Pulse/

JSON files containing collected metrics. One file per collection session.

Application Logs
~/Library/Logs/Pulse/pulse.log

Runtime logs including errors, warnings, and debug info when enabled.

Preferences
com.qlabs.pulse

UserDefaults domain for all configuration. Managed via MDM or CLI.

CLI Binary
/usr/local/bin/pulse

Wrapper 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.

In the app: Settings → General → Verbose Logging
Or via command line
defaults write com.qlabs.pulse verboseLogging -bool true

View Logs

Use standard macOS tools to view and monitor logs in real-time.

Follow logs in real-time
tail -f ~/Library/Logs/Pulse/pulse.log
View recent errors
grep -i "error\|warn" ~/Library/Logs/Pulse/pulse.log | tail -20
Open in Console.app
open -a Console ~/Library/Logs/Pulse/pulse.log

Log Format

Each log entry includes timestamp (local time), level, category, and message.

# Default (warnings and errors only)
[2026-01-21T14:31:00.789] [WARN] [network] ⚠️ Retrying upload in 30 seconds
[2026-01-21T14:31:05.123] [ERROR] [network] ❌ Splunk upload failed: connection timeout
# Verbose (adds info and debug)
[2026-01-21T14:30:15.123] [INFO] [general] Monitoring started with 60s interval
[2026-01-21T14:30:15.456] [DEBUG] [collection] Collecting CPU metrics

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.log

Troubleshooting

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: false for self-signed certificates
Need more details?

See Files & Logging for information on enabling verbose logging, log format, and file locations.