Surfmon¶
Surface Monitor for Windsurf IDE — a performance monitoring and diagnostics tool for Windsurf (Stable, Next, and Insiders).
Table of Contents¶
- Installation
- Quick Start
- Why Use Surfmon?
- Commands
- check — Quick Performance Snapshot
- watch — Live Monitoring Dashboard
- analyze — Historical Trend Analysis
- compare — Before/After Diff
- cleanup — Remove Orphaned Processes
- prune — Deduplicate Watch Reports
- What It Monitors
- Target Selection
- Exit Codes
- Common Issues
- Development
- Package Structure
- Running Tests
- Dependencies
- Requirements
- Creating Screenshots
Installation¶
pip install surfmon
Or with uv:
uv tool install surfmon
Or run directly without installing:
uvx surfmon check -t stable # Using uvx
pipx run surfmon check -t stable # Using pipx
For development:
git clone https://github.com/detailobsessed/surfmon.git
cd surfmon
uv sync
Quick Start¶
# One-shot health check (--target is required)
surfmon check -t stable
# Verbose output with all process details
surfmon check -t stable -v
# Save reports (auto-named with timestamp, enables verbose output)
surfmon check -t next -s
# Target Windsurf Insiders
surfmon check -t insiders

Why Use Surfmon?¶
- 🔍 Debug Performance Issues — Identify memory leaks, CPU spikes, and resource bottlenecks
- 📊 Monitor Over Time — Track resource usage trends with watch sessions and historical analysis
- 🧹 Clean Up Resources — Remove orphaned processes and duplicate reports
- 🔧 Troubleshoot Crashes — Detect extension host crashes, language server issues, and PTY leaks
- 📈 Visualize Trends — Generate matplotlib plots showing resource usage over time
Commands¶
check — Quick Performance Snapshot¶
The main command. Shows system resources, Windsurf memory/CPU, active workspaces, top processes, and language servers in consistent fixed-width tables.
surfmon check -t stable # Basic check
surfmon check -t stable -v # Verbose (all processes)
surfmon check -t next -s # Auto-save JSON + Markdown reports (enables verbose)
surfmon check -t stable --json report.json # Save JSON to specific path
surfmon check -t stable --md report.md # Save Markdown to specific path
surfmon check -t stable --json r.json --md r.md # Save both formats with custom names
watch — Live Monitoring Dashboard¶
Continuously monitors Windsurf with a live-updating terminal dashboard. Saves periodic JSON snapshots for historical analysis.
surfmon watch -t stable # Default: 5s interval, save every 5min
surfmon watch -t next -i 10 -s 600 # Check every 10s, save every 10min
surfmon watch -t insiders -i 10 -n 720 # 720 checks = 2 hours
surfmon watch -t stable -o ~/reports # Custom output directory

analyze — Historical Trend Analysis¶
Analyzes JSON reports from watch sessions (or any directory containing JSON reports) to detect memory leaks, process growth, and performance degradation. Optionally generates a 9-panel matplotlib visualization.
surfmon analyze reports/watch/20260204-134518/
surfmon analyze reports/watch/20260204-134518/ --plot
surfmon analyze reports/watch/20260204-134518/ --plot --output analysis.png
Terminal Output:

Generated Matplotlib Visualization:

compare — Before/After Diff¶
surfmon check -t stable --json before.json
# ... make changes ...
surfmon check -t stable --json after.json
surfmon compare before.json after.json

cleanup — Remove Orphaned Processes¶
Detects and kills orphaned chrome_crashpad_handler processes left behind after Windsurf exits. Windsurf must be closed for this command to work.
surfmon cleanup -t stable # Interactive (asks for confirmation)
surfmon cleanup -t next --force # No confirmation
prune — Deduplicate Watch Reports¶
Removes duplicate/identical JSON reports that accumulate during watch sessions when nothing changes.
surfmon prune reports/watch/20260204-134518/ --dry-run
surfmon prune reports/watch/20260204-134518/
What It Monitors¶
System — Total/available memory, memory %, swap, CPU cores
Windsurf Processes — Process count, total memory & CPU, top 10 by memory, thread counts
Language Servers — Detects and tracks basedpyright, JDT.LS, Codeium language servers, YAML/JSON servers
MCP Servers — Lists enabled MCP servers from Codeium config
Workspaces — Active workspace paths and load times
PTY Usage — Windsurf PTY allocation vs system limits
Issues — Orphaned crash handlers, extension host crashes, update service timeouts, telemetry failures, logs directory in extensions folder
Target Selection¶
Surfmon requires you to specify which Windsurf installation to monitor. Use --target (-t) with one of stable, next, or insiders:
surfmon check -t stable # Windsurf Stable
surfmon check -t next # Windsurf Next
surfmon check -t insiders # Windsurf Insiders
Alternatively, set SURFMON_TARGET in your environment to avoid passing -t every time:
export SURFMON_TARGET=insiders
surfmon check
The --target flag is required for check, watch, and cleanup. Commands that operate on saved files (compare, prune, analyze) do not require it.
Exit Codes¶
0— No issues detected1— Issues detected (see output)130— Interrupted (Ctrl+C)
Common Issues¶
| Issue | Cause | Fix |
|---|---|---|
| Orphaned crash handlers | Crash reporters not cleaned up on exit | surfmon cleanup -t stable --force |
logs directory error | Marimo extension creates logs in wrong place | Move ~/.windsurf/extensions/logs |
| Update service timeouts | DNS or firewall blocking update checks | Check DNS/firewall settings |
| High memory usage | Too many language servers or extensions | Disable unused extensions |
Development¶
Package Structure¶
src/surfmon/
__init__.py # Version
cli.py # Typer CLI — check, watch, compare, cleanup, prune, analyze
config.py # Target detection, paths, environment config
monitor.py # Core data collection — processes, language servers, MCP, PTYs
output.py # Rich terminal display and Markdown export
compare.py # Report comparison with colored diffs
tests/
conftest.py # Shared fixtures
test_bugfixes.py # Regression tests
test_cli.py # CLI command tests
test_compare.py # Report comparison tests
test_config.py # Configuration and target detection tests
test_monitor.py # Core monitoring logic tests
test_output.py # Display and formatting tests
Running Tests¶
poe test # Run tests
poe test-cov # Run with coverage
poe lint # Ruff check
poe typecheck # ty check
Dependencies¶
- psutil — Cross-platform process and system monitoring
- typer — CLI framework
- rich — Terminal output with tables and colors
- python-decouple — Environment configuration
- matplotlib — Visualization for
analyzeplots
Requirements¶
- Python 3.14+
- macOS (tested), Linux (untested), Windows (untested) though it should work
- Windsurf IDE installed
Creating Screenshots¶
Screenshots in this README were created using:
- Static images (termshot) - Captures terminal output as PNG
- Animated GIF (vhs) - Records terminal sessions as GIF
To recreate the watch GIF:
brew install vhs gifsicle
# Create tape file
cat > watch-demo.tape << 'EOF'
Output docs/screenshots/watch.gif
Set FontSize 13
Set Width 900
Set Height 400
Set Theme "Catppuccin Mocha"
Set BorderRadius 10
Set WindowBar Colorful
Set WindowBarSize 30
Type "uvx surfmon watch --interval 2 --max 15"
Enter
Sleep 32s
EOF
# Generate and optimize
vhs watch-demo.tape
gifsicle -O3 --colors 256 docs/screenshots/watch.gif -o docs/screenshots/watch.gif