Documentation

Configure and deploy Pulse for macOS performance monitoring.

Getting Started

Built with Native Swift & SwiftUI

Pulse is built entirely in Swift and SwiftUI — no Electron, no external runtimes, no web views.

  • Minimal CPU and memory footprint
  • Optimized for Apple Silicon and Intel Macs
  • No data leaves your device without explicit configuration

Requirements

  • macOS 14.0 (Sonoma) or later
  • For Splunk (optional): Enterprise or Cloud with HEC enabled

Quick Start

  1. 1Download Pulse from the Mac App Store
  2. 2Launch Pulse — it appears in your menu bar
  3. 3Open Settings and enable Local Storage (or optionally configure Splunk)
  4. 4Click Start to begin monitoring

File Locations

FilePath
Metrics~/Library/Application Support/Pulse/*.jsonl
Logs~/Library/Logs/Pulse/pulse.log
User Preferences~/Library/Preferences/com.qlabs.pulse.plist
MDM Preferences/Library/Managed Preferences/com.qlabs.pulse.plist

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 3 CLI-only settings.

CLI-only settings (--interval, --duration, --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)
--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

Features

  • • Time range: 1h, 6h, 24h, 7d, all
  • • Interactive zoom (click + drag)
  • • Auto-refresh toggle
  • • Process tooltips on hover

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
--quitQuit immediately without uploading
--statusPrint current status and exit
--interval <sec>Set collection interval (one-shot, cleared after session starts)
--duration <min>Set capture duration (one-shot, cleared after session starts)
--headlessEnable headless mode (persists until --no-headless)
--no-headlessDisable headless mode
--helpShow help message
Example Usage
# Start monitoring with 8-hour limit
/Applications/Pulse.app/Contents/MacOS/Pulse --start --duration 480

# Start with 10-second collection interval for 1 hour
/Applications/Pulse.app/Contents/MacOS/Pulse --start --interval 10 --duration 60

# Check current status
/Applications/Pulse.app/Contents/MacOS/Pulse --status

# Stop and upload pending logs
/Applications/Pulse.app/Contents/MacOS/Pulse --stop

# Switch to headless mode
/Applications/Pulse.app/Contents/MacOS/Pulse --headless --start

Running from Jamf or MDM Scripts

Jamf and most MDM tools run scripts as root, but Pulse must run as the logged-in user to access their preferences and display in the menu bar. Use launchctl asuser or open -a to run Pulse in the correct user context.

Jamf Policy Script (Recommended)
#!/bin/bash
# Get the logged-in user
CONSOLE_USER=$(stat -f "%Su" /dev/console)
CONSOLE_UID=$(id -u "$CONSOLE_USER")

# Start Pulse as the logged-in user for 8 hours
launchctl asuser $CONSOLE_UID /Applications/Pulse.app/Contents/MacOS/Pulse --start --duration 480
Alternative: Using open command
#!/bin/bash
# The open command automatically runs as the GUI user
open -a Pulse --args --start --duration 480
Stop Monitoring Script
#!/bin/bash
CONSOLE_USER=$(stat -f "%Su" /dev/console)
CONSOLE_UID=$(id -u "$CONSOLE_USER")

launchctl asuser $CONSOLE_UID /Applications/Pulse.app/Contents/MacOS/Pulse --stop

Important Notes for Enterprise Admins

  • User must be logged in — The script will fail if no user is at the console (e.g., at login window)
  • CLI settings are one-shot--interval and --duration values are cleared after the session starts, so they don't persist to future sessions
  • MDM settings take precedence — If you deploy settings via Configuration Profile, those values cannot be overridden by CLI arguments
  • Headless mode persists — Unlike interval/duration, --headless remains enabled until explicitly disabled with --no-headless

Troubleshooting

App doesn't appear in menu bar

  • Check headless mode: defaults read com.qlabs.pulse headlessMode
  • Disable headless: 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: 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

Enable Debug Logging

defaults write com.qlabs.pulse verboseLogging -bool true
killall Pulse && open -a Pulse
tail -f ~/Library/Logs/Pulse/pulse.log