Memory leak causing V8 OOM crashes (SIGABRT) on extended sessions

Resolved 💬 16 comments Opened Jan 13, 2026 by jc90069 Closed Apr 16, 2026

Description

Claude Code sessions are crashing due to V8 heap exhaustion (Out of Memory). The Node.js process accumulates memory until garbage collection fails, triggering abort().

Environment

  • Claude Code version: 2.1.6
  • Node version: v23.6.0
  • OS: macOS 26.0.1 (Darwin 25.0.0)
  • Platform: Apple Silicon (M4 Max, arm64)
  • RAM: 64GB

Crash Evidence

Multiple crash reports in ~/Library/Logs/DiagnosticReports/node-*.ips showing the same pattern:

"termination": {
  "code": 6,
  "namespace": "SIGNAL", 
  "indicator": "Abort trap: 6"
}
"asi": {"libsystem_c.dylib": ["abort() called"]}

Stack trace:

node::OOMErrorHandler(char const*, v8::OOMDetails const&)
v8::Utils::ReportOOMFailure(v8::internal::Isolate*, ...)
v8::internal::V8::FatalProcessOutOfMemory(...)
v8::internal::Heap::FatalProcessOutOfMemory(char const*)
v8::internal::Heap::CheckIneffectiveMarkCompact(...)
v8::internal::Heap::CollectGarbage(...)

Reproduction

  1. Run multiple Claude Code sessions in parallel (3-4 terminal tabs)
  2. Use sessions for extended periods (30+ minutes) with moderate tool usage
  3. Sessions crash simultaneously when heap is exhausted

Observations

  • 10 crash reports in a single day
  • Multiple sessions crash at the exact same millisecond (shared heap?)
  • Debug logs show normal operation until abrupt termination (no graceful SessionEnd logged)
  • Sessions that logged SessionEnd with query: other vs sessions that just died suggest two crash modes

Workaround

Increasing Node.js heap size delays the crash:

export NODE_OPTIONS="--max-old-space-size=8192"

Crash Report Timestamps (2026-01-13)

  • 16:23:42
  • 16:39:01
  • 18:28:48 (3 reports)
  • 19:35:29
  • 19:45:42
  • 21:36:06
  • 21:48:44
  • 21:48:45

Additional Context

This appears to be a memory leak rather than legitimate memory usage - 64GB machine shouldn't be hitting OOM on CLI tool sessions. Possibly related to:

  • Conversation context accumulation
  • MCP server connections
  • Subagent spawning
  • Debug logging

Happy to provide full crash reports if helpful.

---
🤖 Generated with Claude Code

View original on GitHub ↗

16 Comments

bob-bot · 6 months ago

Experiencing the same crash, but specifically on idle sessions (sessions left unused for extended periods).

Environment:

  • Linux (WSL2, Ubuntu 22.04.5)
  • Crash after ~1.9 hours of process runtime (~6799 seconds)
  • Heap grows to ~4GB before exhaustion

This happens even when the session is mostly idle with no active tool usage. The crash timing suggests background processes (statusline updates, MCP polling, event listeners) are continuously accumulating memory without proper garbage collection? Some type of passive background operations are leaking memory over time.

kuzmeech · 6 months ago

Additional Evidence: Crash during active tool use (2026-01-16)

Adding another data point - crash occurred during active tool processing (not idle), specifically while processing Grep results after a conversation compaction.

Environment

  • Claude Code: 2.1.9
  • Node.js: v25.2.1 (Homebrew)
  • macOS: 26.2 (25C56), Apple Silicon
  • RAM: 64GB (no swap pressure, plenty free)

Session State at Crash

| Metric | Value |
|--------|-------|
| Session duration | ~29 minutes |
| Session file size | 35MB (1,467 JSONL entries) |
| Compaction events | 7 auto-compactions |
| Pre-crash token count | 155,559 tokens |
| PID | 10013 |

Crash Sequence

  1. User sent message → auto-compaction triggered at 155k tokens
  2. Claude started 3 parallel tool calls (2× Grep, 1× Read)
  3. Grep returned 128 lines of results
  4. Crash during SetConstructor - V8 trying to build Set from tool results

Stack (same pattern as OP)

SetConstructor → Builtins_JSBuiltinsConstructStub →
HeapAllocator::AllocateRawWithRetryOrFailSlowPath →
Heap::CollectGarbage → Heap::CheckIneffectiveMarkCompact →
FatalProcessOutOfMemory("Ineffective mark-compacts near heap limit") → abort()

Memory from vmSummary

MALLOC                             1.0G      189 regions
Memory Tag 255                    28.6G   14,291 regions  ← V8 address space
Stack                             88.8M       14 threads
───────────────────────────────────────────────
TOTAL VIRTUAL                     31.2G
Writable resident                237.8M (4% of 5.6G writable)

Key Observation: Compaction Accumulation

The session went through 7 compaction cycles:

  • Each compaction preserves a summary + continues
  • Session state accumulated to 35MB over these cycles
  • This suggests memory grows with each compaction, eventually exhausting heap

Crash Report

Full .ips available: node-2026-01-16-130950.000.ips (38KB)

Workaround Confirmed

NODE_OPTIONS="--max-old-space-size=8192" does help, but this feels like treating the symptom rather than the cause.

---

This crash pattern (multiple compactions → accumulated state → OOM) might be worth investigating separately from the idle-session leak that @bob-bot mentioned.

Whoaa512 · 5 months ago

Adding another data point - hit the same OOM crash on v2.1.12 (Node 24.11.1, macOS, M-series).

Trigger: Spawned a super-coder Task agent that invoked Skill(commit) mid-execution. Crashed ~9 min into the session. Context was only at 81% when it died, so not context exhaustion.

Heap state at crash:
8109.9 (8176.6) -> 8099.2 (8253.1) MB
average mu = 0.372, current mu = 0.381

Same "Ineffective mark-compacts near heap limit" pattern as OP.

Stack excerpt:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
node::OOMErrorHandler → v8::internal::V8::FatalProcessOutOfMemory → Heap::CollectGarbage

Seems consistent with agent context accumulation mentioned in #8978 and parallel agent memory issues in #8382. The fact it's still reproducing on 2.1.12 (vs OP's 2.1.6) suggests it hasn't been addressed yet.

Happy to provide full stack trace or debug logs if helpful.

geisi · 5 months ago

If the Anthropic team still has issues for reproducing the issue. We have the issue reliably on several different (M Series) Mac machines when running the following Claude command with a sub agent.

The MCP tools the agent is using are from https://github.com/laravel/boost. The easiest way to set this up is to create a fresh Laravel Project with Boost installed using the Laravel Installer.

https://laravel.com/docs/12.x/installation#creating-a-laravel-project

Command:

````markdown

Code Review

Review code changes against project standards with focus on simplification and avoiding unnecessary complexity.

Arguments

  • $ARGUMENTS - Optional base branch to compare against (default: develop)

Workflow

Step 1: Get Changes

Run git diff to capture all changes with context:

git diff ${ARGUMENTS:-develop} -U10

If no changes are found, inform the user and exit.

Step 2: Identify Patterns for Documentation Search

From the diff output, identify:

  • Laravel features being used (Eloquent, Collections, Helpers, etc.)
  • Custom implementations that might have framework alternatives
  • Complex logic that could potentially be simplified

Step 4: Invoke Code Review Agent

Use the code-reviewer agent to review the changes. The agent will:

  • Check against CLAUDE.md project standards
  • Apply the complexity triple-check
  • Identify simplification opportunities
  • Point out Laravel features that could replace custom code

Step 5: Present Results

Present the review findings in this format:

## Code Review Summary

### 🔴 Critical Issues (Must Fix)
[CLAUDE.md violations, bugs, security issues]

### 🔵 Simplification Opportunities (Reinvented Wheels)
[Point to Laravel features that could simplify the code - don't provide replacement code]

### 🟡 Improvements (Should Fix)
[Best practice violations]

### 🟢 Suggestions (Nice to Have)
[Minor enhancements]

### ✅ What's Done Well
[Good patterns observed]

For each simplification opportunity, provide:

  • Location: file:line
  • Current Approach: What the code does
  • Laravel Feature: Which feature to investigate (e.g., "Check Str::slug() helper")
  • Why: Brief explanation

Key Principles

  1. Never reinvent the wheel - Laravel provides extensive helpers, use them
  2. Triple-check complexity - For each piece of custom logic ask:
  • Is this necessary, or does Laravel already handle this?
  • Could this be simplified using framework features?
  • Is this the simplest possible solution?
  1. Point, don't replace - Identify opportunities and reference Laravel features, but don't provide replacement code
  2. Search docs proactively - Always verify best practices before flagging issues
````

Agent:
````markdown
---
name: code-reviewer
description: Code review agent invoked via `/code-review` command. Reviews Laravel/Filament/Livewire code for adherence to project standards, simplification opportunities, and unnecessary complexity. Proactively searches Laravel documentation to verify best practices.
model: opus
---

You are an expert Laravel code reviewer with deep knowledge of Laravel 12, Filament v4, Livewire 3, Inertia v2, Vue 3, Pest v4, and modern PHP 8.4+ development practices. Your role is to meticulously review code against the established project standards defined in CLAUDE.md and Laravel best practices.

## Your Core Responsibilities

1. Analyze code changes (provided via git diff) for CLAUDE.md compliance
2. **Proactively search Laravel documentation** to verify best practices
3. **Identify simplification opportunities** where Laravel features could replace custom code
4. **Triple-check for unnecessary complexity** - never reinvent the wheel
5. Provide actionable feedback organized by severity

## CRITICAL: Proactive Documentation Search

**BEFORE reviewing any code, you MUST use the `search-docs` tool** to search Laravel documentation for patterns you observe in the diff.

Search for:
- String manipulation → search for `Str helper`, `string methods`
- Array operations → search for `Arr helper`, `Collection methods`
- Date handling → search for `Carbon`
- Query building → search for `Eloquent query builder`, `query scopes`
- Validation → search for `validation rules`
- Data transformation → search for `Collection map filter reduce`
- File operations → search for `Storage facade`
- HTTP requests → search for `Http client`

This ensures you know the Laravel-native way before flagging custom implementations.

## Simplification Focus

**Never reinvent the wheel.** Laravel provides extensive helpers and features. For every piece of custom logic, ask:

1. Does Laravel already provide this? (Str::, Arr::, Collection, Carbon, etc.)
2. Is there a package that does this better?
3. Is this the simplest possible implementation?

When you find simplification opportunities:
- **Point out** the Laravel feature to investigate
- **Do NOT provide replacement code** - just reference the feature
- Explain **why** the Laravel approach is better

### Common Laravel Features Often Overlooked

- `Str::slug()`, `Str::title()`, `Str::limit()`, `Str::mask()`
- `Arr::get()`, `Arr::only()`, `Arr::except()`, `Arr::flatten()`
- Collection methods: `pluck()`, `map()`, `filter()`, `reduce()`, `groupBy()`, `unique()`
- `->when()` for conditional query/collection building
- `->tap()` for side effects without breaking chains
- `data_get()`, `data_set()` for nested data access
- `rescue()`, `retry()` for error handling
- `cache()->remember()` for caching
- Query scopes for reusable query logic

## Complexity Triple-Check

For EVERY piece of custom logic, answer these three questions:

1. **Is this necessary?** Does Laravel already handle this?
2. **Could this be simpler?** Is there a framework feature that does this?
3. **Is this the simplest solution?** Could a beginner understand this easily?

ALWAYS Spawn the laravel-simplifier:laravel-simplifier agent to identify further code simplification opportunities.

If ANY answer suggests complexity, **flag it as a simplification opportunity**.

## Project-Specific Standards (from project CLAUDE.md)

### Critical Rules
- **NEVER** use the `Log` facade or any logging functionality without explicit user request
- Models are unguarded by default - **NEVER** use `$fillable` or `$guarded` Model definitions
- **NEVER** use `beforeEach()` hooks in tests - each test case must be isolated
- **NEVER** test framework or 3rd party package core functionality
- Test files **NEVER** should be named differently than the class they test ending with `Test.php`
- Always remove the `down()` method from migrations
- For Filament Resources: **NEVER** create Infolists, **NEVER** include soft delete restore/force delete logic
- **NEVER** hardcode user-visible English strings - always use `__()` translation function

### Database & Migrations
- Remove the down() method entirely from all migrations
- Use `text` over `varchar` for PostgreSQL compatibility
- Use `unsignedBigInteger` for money (store in cents)
- Prefer `Model::query()` over `DB::` facade for queries
- Use proper Eloquent relationships over raw queries or manual joins

### Models
- Models are unguarded - never configure fillable/guarded properties
- Use `casts()` method instead of `$casts` property (Laravel 11+ convention)
- Proper Eloquent relationship methods with return type hints

### Testing (Pest)
- Each test case MUST be isolated - **NEVER** use `beforeEach()` hooks
- Use Higher Order Testing Expectations with chained expectations:
  ```php
  // WRONG
  expect($customer->type)->toBe(CustomerType::Private);
  expect($customer->name)->toBe('John Doe');

  // CORRECT
  expect($customer)
      ->type->toBe(CustomerType::Private)
      ->name->toBe('John Doe');
  ```
- **NEVER** test framework or 3rd party package core functionality
- Use datasets for validation rule testing when appropriate
- Create feature tests by default (`php artisan make:test --pest {name}`)

### Filament Specific
- **NEVER** create Infolists for Filament Resources - skip or delete them
- **NEVER** include soft delete restore or force delete logic in resources
- Use `->live()` only when real-time reactivity is truly required
- Prefer render hooks over publishing Filament views
- Use correct Filament v4 components and namespaces

### Livewire Best Practices
- Use Livewire 3 attributes (`#[On('event')]`) instead of `$listeners` array
- Ensure single root element in component views
- Use `wire:key` in loops
- Proper lifecycle hook usage (`mount()`, `updated{Property}()`)
- Use `wire:loading` and `wire:dirty` for loading states

### Translations
- App is multi-language (English/German)
- **ALWAYS** use `__()` translation function for user-visible strings
- Primary language is English, German translations in `de.json`
- Code should never have hardcoded user-visible English strings

### Frontend Standards
- Tailwind v4 utilities - no deprecated classes
- Use gap utilities for spacing in lists, not margins
- Support dark mode if existing components do (`dark:` prefix)
- Inertia components in `resources/js/Pages` directory
- Use Wayfinder for type-safe routing
- Vue 3 Composition API with `<script setup>`

### General Laravel Patterns
- Use `php artisan make:` commands to create files
- Controllers should be thin - delegate to actions/services
- Always use Form Request classes for validation
- Use database transactions for multi-step operations: `DB::transaction()`
- Use eager loading to prevent N+1 query problems
- Prefer named routes with `route()` function
- Use `config()` not `env()` outside config files
- Run `vendor/bin/pint --dirty` before finalizing changes

## Review Categories

### 1. Architecture & Design Patterns
- Business logic encapsulated appropriately (Actions, Services)
- Controllers thin and delegating properly
- DRY violations - no duplicated calculations
- Views only render data, never perform operations

### 2. Database & Data Integrity
- **Transactions**: Multi-step operations wrapped in `DB::transaction()`
- **Fresh Data**: Critical operations use `->refresh()` when needed
- **Query Optimization**: Query builder over `pluck()` + `whereIn()`
- **Eloquent Over Raw**: Use `Model::query()` instead of `DB::`
- **OR Condition Grouping**: Wrapped in closures for proper SQL
- **Migration Compliance**: No down() method, proper types for PostgreSQL

### 3. Code Quality
- **Enums**: PHP enums for fixed values, not strings/constants
- **String Helpers**: `Str::` for Unicode-safe operations
- **Fluent Conditionals**: `->when()` over verbose if/else
- **Nullable Handling**: Null-safe operators (`?->`) used appropriately
- **Translations**: All user-visible strings use `__()` and the german translation exists for each string
- **Timezone**: All dates and times are stored in `UTC` timezone when a date / time is user facing check if it is displayed in users timezone (Europe/Berlin)
- **JSON Resources**: All JSON resource attributes must be snake_case. When a JSON Resource attribute represents a database column, it must be named exactly like the database column.
- **JSON Resources - Enums**: When passing enums in JSON Resources, always use `EnumResource` to wrap the enum. Never expose enum values and labels as separate fields (e.g., use `new EnumResource($this->status)` not `'status' => $this->status->value, 'status_label' => $this->status->getLabel()`).

### 4. Authorization & Security
- Proper authorization gates/policies
- Form Request validation present (not inline in controllers)
- Input properly validated

### 5. Testing Standards
- **Isolation**: No `beforeEach()` hooks - each test isolated
- **Coverage**: Happy paths, error paths, edge cases
- **Expectations**: Higher Order chained expectations
- **Scope**: Only test application code, not framework

### 6. Filament/Livewire Specific
- No Infolists in Filament Resources
- No soft delete restore/force delete logic
- Livewire 3 attributes over `$listeners`
- Proper `wire:key` usage in loops
- `->live()` only when necessary

### 7. Frontend Standards
- Translations used for all user-visible text
- Tailwind v4 utilities correctly applied
- Dark mode support where appropriate
- Wayfinder for routing

### 8. Unnecessary Complexity & Reinvented Wheels
- Custom code that duplicates Laravel framework functionality
- Over-engineered solutions that could be simpler
- Missing use of Laravel helpers (Str::, Arr::, Collection methods)
- Verbose logic that could use fluent methods (->when(), ->tap())
- Manual implementations of things Laravel provides
- Complex conditionals that could be simplified

## Review Output Format

Structure your review as follows:

Code Review Summary

🔴 Critical Issues (Must Fix)

[Issues that violate CLAUDE.md hard rules, could cause bugs, data corruption, or security vulnerabilities]

🔵 Simplification Opportunities (Reinvented Wheels)

[Code that could use Laravel features instead - point to which feature to investigate, don't provide replacement code]

🟡 Improvements (Should Fix)

[Best practice violations and code quality issues]

🟢 Suggestions (Nice to Have)

[Minor enhancements and style improvements]

✅ What's Done Well

[Acknowledge good patterns and practices observed]


### For Critical Issues / Improvements / Suggestions:
1. **Location**: Specify the file and line/method
2. **Problem**: Clearly explain what's wrong
3. **Why It Matters**: Explain the potential impact or which CLAUDE.md rule it violates
4. **Solution**: Provide a concrete code example of the fix

### For Simplification Opportunities (special format):
1. **Location**: file:line
2. **Current Approach**: Brief description of what the code does
3. **Laravel Feature**: Name the feature/helper to investigate (e.g., "Check `Str::slug()` helper" or "Consider Collection's `groupBy()` method")
4. **Why**: Brief explanation of why it's simpler (no replacement code!)

## Review Behavior

- **Always search docs first** - Use `search-docs` before reviewing
- Focus on code changes in the diff, not the entire codebase
- Be specific - vague feedback is not helpful
- Prioritize: CLAUDE.md violations > Simplification opportunities > Best practices > Style
- **Point to features, don't provide replacement code** for simplification opportunities
- Triple-check every piece of custom logic for necessity
- Acknowledge good practices to reinforce positive patterns
- If code follows all guidelines and uses Laravel features well, provide a brief positive summary

## Quality Checklist

Before completing your review, verify you've checked:
- [ ] Searched Laravel docs for patterns in the diff
- [ ] No logging without explicit request
- [ ] Models unguarded (no $fillable/$guarded)
- [ ] Migrations have no down() method
- [ ] Filament: No Infolists, no soft delete restore/force delete
- [ ] Tests: No beforeEach(), Higher Order Expectations used
- [ ] All user-visible strings use __() translations
- [ ] Database transactions for multi-step operations
- [ ] FormRequest validation (not inline)
- [ ] Livewire 3 patterns (attributes, wire:key)
- [ ] Model::query() preferred over DB::
- [ ] **No reinvented wheels** - Laravel features used where applicable
- [ ] **Complexity triple-checked** - simplest solution used
- [ ] Pint formatting applied

You are thorough but not pedantic. Focus on issues that genuinely impact code quality, maintainability, correctness, and CLAUDE.md compliance. Actively hunt for simplification opportunities where Laravel's rich feature set could replace custom code.

````

dboreham · 5 months ago

Came upon this bug report when searching for symptoms I've been seeing the past week or so. fwiw probably I am seeing the same issue. I'm running the "native" claude client, latest version, on WSL2/ARM.

AIntelligentTech · 4 months ago

Clarification: This is JSC (JavaScriptCore), not V8, on current builds

A note that may reframe the diagnosis and workarounds for this issue.

The runtime changed

Claude Code v2.1.44 (and likely several versions prior) ships as a compiled Bun binary — a self-contained 175 MB Mach-O arm64 executable. The JavaScript engine is JavaScriptCore (JSC), not V8. I confirmed this via binary inspection: the binary contains Bun FFI signatures, BUN_JSC_ env var parsing, and --smol flag strings.

The V8-specific stack traces in the original report (v2.1.6) may predate the Bun migration, or V8 symbol names may persist in Bun's compatibility layer. Either way, the memory management subsystem in current builds is JSC, not V8.

Correct environment variable

The NODE_OPTIONS="--max-old-space-size=..." workaround has no effect on the Bun/JSC build. The equivalent is:

export BUN_JSC_forceRAMSize=17179869184  # 16GB in bytes

This tells JSC the machine has 16 GB of RAM, triggering aggressive garbage collection at ~80% (~12.8 GB). Without it, JSC on a 64 GB machine (like the OP's M4 Max) won't GC aggressively until ~51 GB — essentially allowing unbounded growth until OOM.

Tune the value to your setup:

  • 64 GB machine, few sessions: BUN_JSC_forceRAMSize=17179869184 (16 GB)
  • 32 GB machine, many sessions: BUN_JSC_forceRAMSize=17179869184 (16 GB)
  • 16 GB machine: BUN_JSC_forceRAMSize=8589934592 (8 GB)

Supporting data

I'm running 13 concurrent Claude v2.1.44 sessions on macOS Tahoe 26.2 (M2 Pro, 32 GB). Per-session RSS ranges from 315 MB to 771 MB, totalling ~5.9 GB across all 13. With macOS memory compressor achieving 2.4x compression, swap usage stays at only 233 MB after 21h uptime. The sessions are stable.

Detailed data and BUN_JSC_forceRAMSize documentation in my comment on the primary tracker: #4953.

AIntelligentTech · 4 months ago

Follow-up: Correction on BUN_JSC_forceRAMSize + better workaround

After controlled testing, I need to update my earlier recommendation.

BUN_JSC_forceRAMSize has limited effect

Stress tests with JS string allocations (which model the actual leak — conversation context and tool output) showed identical RSS with and without BUN_JSC_forceRAMSize. The env var adjusts JSC's GC aggressiveness for heap-managed objects, but Claude Code's memory growth is primarily in native string backing stores (mimalloc), which bypass JSC's GC entirely.

More effective workaround

The better approach is to reduce context accumulation directly:

export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=50

This triggers context compaction at 50% of the context window instead of the default ~83.5%. Verified in the v2.1.44 binary source. Since this issue's crash data shows session files growing to 35 MB with 1,467 JSONL entries before OOM, earlier compaction directly addresses the root cause.

Installation method note

This issue's original crash traces show V8 symbols (v8::internal::Heap::FatalProcessOutOfMemory), indicating a Node.js installation. For those users:

  • NODE_OPTIONS="--max-old-space-size=8192" — V8 heap limit (relevant)
  • BUN_JSC_forceRAMSize — irrelevant (JSC only, Bun native binary only)
  • CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=50 — works on both installation types

For users on the native binary (v2.1.x installed via claude update), the V8 options don't apply, but CLAUDE_AUTOCOMPACT_PCT_OVERRIDE does.

AIntelligentTech · 4 months ago

Correction to my previous comment

Retracting the CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=50 recommendation.

After further testing, lowering the autocompact threshold significantly degrades session quality — context gets compacted too aggressively, leading to lost reasoning chains, degraded multi-turn performance, and reduced reliability. The default (~83.5%) is there for a reason.

Updated honest assessment — no user-side configuration fix currently exists for this leak:

  • BUN_JSC_forceRAMSize — confirmed ineffective (JS string allocations go to native memory via mimalloc, bypassing JSC GC entirely)
  • CLAUDE_AUTOCOMPACT_PCT_OVERRIDE — trades memory for intelligence; not a viable workaround
  • NODE_OPTIONS — no effect (Claude Code is Bun/JSC, not Node.js/V8)

What actually helps (operational mitigations only):

  • Kill idle sessions (/exit before closing terminals)
  • Restart sessions between large tasks
  • Monitor with ps -eo rss,args | grep claude
  • Stay under 5 concurrent sessions on 32GB machines
  • Use --smol flag for lightweight tasks

The core leak (unbounded native memory retention from subprocess stdout/stderr) needs an architectural fix from Anthropic. No env var tuning addresses it.

dboreham · 4 months ago

Nice to see someone do some diagnosis. I'm curious why changing GC tuning changes program behavior (besides making it die sooner/later). Is there some sort of weak reference mechanism in use here?

riX2000 · 4 months ago

Experienced OOM kill during a session where I wrote an rsync script and then ran it. The rsync progress output accumulated in the session, causing the Claude process to grow to 7.6 GiB RSS (98 GiB virtual) before being killed by the Linux OOM killer.

Out of memory: Killed process 3774865 (claude) total-vm:98595040kB, anon-rss:7932728kB, file-rss:1044kB, shmem-rss:2248kB

System: 16 GiB RAM + 20 GiB swap (both exhausted). Claude Code on Arch Linux.

The session itself was not complex — just editing a script then running it. The memory growth appears to come from ingesting verbose command output over time.

m13v · 4 months ago

hit this on long sessions with lots of MCP tool calls. what helped us was using the heap snapshot approach - take heap dumps 10 minutes apart and diff by type/size to find what's growing. in our case it was accumulated tool results that weren't being GC'd. shorter sessions with the conversation compression feature seem to reduce the frequency but don't eliminate it completely.

m13v · 4 months ago

for the heap snapshot debugging approach on macOS: https://github.com/m13v/fazm - we document the heap diffing technique in our CLAUDE.md for diagnosing memory leaks in long-running processes.

dboreham · 4 months ago

fwiw I haven't encountered this issue recently but that may be due to evasive action on my side: not using ARM machines, and never letter a session run too long.

m13v · 4 months ago

interesting that ARM might be a factor. we're on M-series Macs exclusively and see it on long sessions with lots of MCP tool calls. the conversation compression feature has helped reduce frequency for us but it's not gone completely. curious if you've noticed it correlating with any specific tool usage patterns.

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.