Session resume freezes with 100% CPU due to redundant progress events in session files

Resolved 💬 9 comments Opened Jan 31, 2026 by asem89 Closed Mar 11, 2026

Describe the bug

Claude Code freezes with 100% CPU when attempting to resume conversations. The UI becomes unresponsive and the process must be killed.

Root Cause Analysis

Investigation revealed that session .jsonl files grow to hundreds of megabytes due to progress events storing the entire conversation history in normalizedMessages on every event.

Evidence from a 193MB session file:

  • 500 lines total
  • 426 progress events = 191.6 MB (99.9% of file)
  • Actual conversation (user/assistant/system) = 0.16 MB
  • Each progress event contains full normalizedMessages array (2264 messages in longest case)
  • Individual lines up to 1.4 MB each

The duplication pattern:

Early events:   progress with ~140 messages  → 0.72 MB
Middle events:  progress with ~500 messages  → 0.85 MB  
Late events:    progress with ~2264 messages → 1.44 MB

Every progress event duplicates the entire conversation history up to that point.

Impact

  • Session files grow to 100MB-400MB for long conversations
  • Resume picker must parse all these files → 100% CPU freeze
  • Storage waste: 99.9% of session files is redundant data

Expected behavior

progress events should either:

  1. Not include normalizedMessages (it's redundant - the conversation is already stored in user/assistant events)
  2. Store only a delta/reference
  3. Be excluded from session files entirely (they're only needed for live streaming UI)

Workaround

Strip progress events from session files:

import json

def clean_session(filepath):
    with open(filepath) as f:
        lines = [l for l in f if json.loads(l).get('type') != 'progress']
    with open(filepath, 'w') as f:
        f.writelines(lines)

Environment

  • Claude Code version: 2.1.27
  • OS: Linux

View original on GitHub ↗

This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗