Skip to content

Instantly share code, notes, and snippets.

@johnlindquist
Created November 29, 2025 01:18
Show Gist options
  • Select an option

  • Save johnlindquist/7e5ff79a2fe0df13ad320b5f39d5f69c to your computer and use it in GitHub Desktop.

Select an option

Save johnlindquist/7e5ff79a2fe0df13ad320b5f39d5f69c to your computer and use it in GitHub Desktop.
Bun 1.3.3 WebSocket 100% CPU Investigation - Lootbox Server

Bun WebSocket 100% CPU Spin Investigation

Date: 2025-11-28 Bun Version: 1.3.3 Platform: macOS Darwin 24.6.0 (ARM64)

Problem

Lootbox server running at 100% CPU for 9+ hours. Main server process only - worker processes at 0% CPU.

Evidence

Process Stats

PID 30968 - 100% CPU, 1786MB RSS, running for 566 minutes
Workers (3 active) - all at 0% CPU

Health Endpoint

{
  "status": "degraded",
  "healthy": false,
  "warnings": [
    "High CPU usage: 100.0%",
    "High memory usage: 1785.7MB RSS"
  ],
  "metrics": {
    "eventLoopLagMs": 0,
    "activeHandles": 0,
    "activeRequests": 0
  }
}

Stack Trace (sampled)

829 samples total (100% CPU time)
├── 796 samples in socket/recv handling
│   ├── 526 in recvfrom (network receiving)
│   └── 231 in kevent64 (event polling)

Key observation: 0ms event loop lag with 100% CPU indicates busy-polling, not blocked I/O.

Network State

3 established WebSocket connections (MCP bridge clients)
tcp6 ::1.3456 <-> ::1.51358 ESTABLISHED
tcp6 ::1.3456 <-> ::1.62716 ESTABLISHED  
tcp6 ::1.3456 <-> ::1.61599 ESTABLISHED

Server Configuration

// websocket_server.ts line 244-248
websocket: {
  // DEBUG: Testing WebSocket options to fix CPU spin
  idleTimeout: 0, // Disable idle timeout to prevent keep-alive polling
  perMessageDeflate: false, // Disable compression
  sendPings: false, // Disable automatic pings

These options were already attempted as mitigations but didn't resolve the issue.

Related Bun Issues

Workarounds

Immediate

pkill -f "lootbox-cli.ts server" && sleep 2 && lootbox server

Scheduled Restart (cron)

# Add to crontab -e
0 */8 * * * pkill -f "lootbox-cli.ts server" && sleep 5 && cd ~/dev/lootbox-bun && lootbox server

Supervisor Script

#!/bin/bash
while true; do
  lootbox server
  echo "Server exited, restarting in 5s..."
  sleep 5
done

Potential Fixes to Investigate

  1. Upgrade Bun - Test with latest version
  2. HTTP Long-Polling - Replace WebSocket with HTTP for MCP bridge
  3. Different WebSocket library - Use ws or uWebSockets.js directly
  4. Connection timeout - Auto-close idle WebSocket connections
  5. Process isolation - Run WebSocket server in separate process

Reproduction

  1. Start lootbox server: bun run src/lootbox-cli.ts server --port 3456
  2. Connect 2-3 MCP bridge clients (Claude Code sessions)
  3. Wait 6-12 hours
  4. Observe: CPU climbs to 100%, stays there indefinitely

Environment

OS: macOS 15.6.1 (Darwin 24.6.0)
Arch: ARM64 (Apple Silicon)
Bun: 1.3.3
Node: (via Bun compatibility)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment