Ресурсная чёрная дыра Claude Code: от 11,3 МБ однопакетного файла до 1,2 ТБ поглощения диска

На основе реальных пользовательских отчётов в GitHub Issues и обратного анализа сообщества, систематически рассматриваются недостатки управления ресурсами Claude Code в трёх измерениях — память, CPU и диск, раскрываются проблемы в архитектуре упаковки, дизайне хранилища и управлении жизненным циклом процессов.

Claude Code — клиентское приложение без управления жизненным циклом ресурсов: при запуске разбирает 11,3 МБ упакованный файл, во время работы без ограничений записывает на диск, а после закрытия терминала процесс остаётся живым и продолжает потреблять память, пока система не рухнет. На основе реальных пользовательских отчётов в GitHub Issues и обратного анализа сообщества, в этой статье систематически рассматриваются недостатки управления ресурсами в памяти, CPU и диске, а также раскрываются структурные проблемы в архитектуре упаковки, дизайне хранилища и управлении жизненным циклом процессов. Это не отдельные граничные случаи, а системные архитектурные дефекты, сообщаемые сообществом с августа 2025 по апрель 2026 года, но закрываемые ботом‑stale.

Архитектура упаковки: цена 11,3 МБ однопакетного файла

Ядром Claude Code является однопакетный файл cli.js размером около 11,3 МБ. Пользователь paultendo провёл подробный статический анализ в Issue #29481, выявив несколько серьёзных архитектурных проблем.

V8: 32 % времени запуска тратится на разбор

CPU‑профилирование показывает, что compileSourceTextModule занимает 31,7 % времени запуска. V8 требуется около 300 мс, чтобы разобрать этот 11,3 МБ файл, тогда как обычному скрипту Node.js требуется лишь 23 мс. Дополнительные 7,3 % тратятся на вызов spawnSync, 3,5 % — на сборку мусора. Это значит, что более 40 % времени запуска теряется на чистый разбор до того, как пользователь введёт любую команду.

Полная загрузка: только 20 динамических import

Весь пакет полностью разбирается и исполняется при запуске, содержащий лишь 20 выражений import(). Каждый пользователь платит цену за все функции, независимо от их использования. Ниже перечислены компоненты, которые должны были загружаться по требованию, но попали в полный пакет:

pie title Состав упакованного файла (≈ 13,5 МБ)
    "Основная логика приложения" : 7540
    "AWS Bedrock SDK" : 1100
    "highlight.js (182 языка)" : 1000
    "OpenTelemetry" : 900
    "Google Vertex + gRPC + Protobuf" : 800
    "RxJS" : 300
    "Прочее (Ink, Zod, Ajv, Axios и др.)" : 1807

Помощнику кодера необходимо подсвечивание для 182 языков, включая Brainfuck, MIPS assembly, Flix, Zephir, Inform7, Lasso и др., что уже демонстрирует грубость стратегии упаковки. Сократив набор до ~40 популярных языков, можно сэкономить около 786 KB разбираемого кода.

Избыточные зависимости: четыре HTTP‑клиента, три библиотеки валидации

Разные SDK добавляют собственные зависимости, в результате в пакете одновременно присутствуют четыре HTTP‑клиента (Axios, Undici, Got, нативный fetch) и три библиотеки валидации (Zod, Ajv, JSON Schema). В среде Node 18+ нативный fetch полностью доступен, поэтому дополнительные HTTP‑клиенты не нужны.

413 синхронных вызовов файловой системы

Пакет содержит 196 вызовов existsSync, 109 statSync, 108 readFileSync, 58 mkdirSync и т.д., всего 413 синхронных вызовов. Каждый из них блокирует цикл событий. Часто используется шаблон existsSync(path) && readFileSync(path), который можно заменить на один асинхронный try { await readFile(path) } catch {}.

1087 обёрток CJS/ESM

Для каждого CommonJS‑модуля, упакованного в ESM, генерируются совместимые патчи __toESM/__commonJS/__require, всего 1087 штук. Эти патчи увеличивают вес разбора и добавляют небольшие накладные расходы во время выполнения.

Необходимый polyfill Node 20

В пакете присутствует 62 полифила Promise (поддерживается нативно с Node 0.12), 57 полифилов Symbol (Node 4), 57 вспомогательных функций async (Node 8) и 3 полифила AbortController (Node 15). Они пришли из транзитивных зависимостей, собранных для старых версий Node или браузеров, и полностью избыточны в целевой среде.

ripgrep: упаковка всех 6 платформных бинарников — 61 МБ

Все шесть бинарников ripgrep включены в пакет, суммарно 61 МБ. В отличие от этого, sharp правильно использует optional dependencies и устанавливает только бинарник текущей платформы. Таким образом каждый установочный пакет теряет около 51 МБ дискового пространства.

Производительность Ink деградирует с ростом длины диалога

Терминальный UI построен на Ink (React for Terminal). Анализ показывает 6457 вызовов createElement, 578 хуков useState, но лишь 11 обёрток React.memo(), что составляет 1,9 %. В Ink каждый апдейт состояния приводит к полной согласовке виртуального DOM. Во время потоковой генерации каждый токен вызывает обновление состояния, что приводит к ненужному повторному рендерингу. По мере роста диалога объём вывода растёт, и каждый ререндер требует всё больше диффов терминального контента. Это согласуется с наблюдением в Issue #22265 о «замедлении по мере продолжения сессии».

Поглощение диска: от ГБ к ТБ без ограничений

Проблемы с диском — самые тяжёлые недостатки управления ресурсами Claude Code, охватывающие наибольший спектр и имеющие самые серьёзные последствия.

Утечка нативного модуля .node в Windows: 20 ГБ в неделю

Issue #23095 фиксирует проблему, существующую несколько месяцев: в Windows нативный бинарник (claude.exe) каждый сеанс извлекает плагины Node.js в системный временный каталог, но никогда их не удаляет. Каждый файл весит ~6,6 МБ; пользователь SlothKing16 за 4 дня накопил 2813 файлов — около 18 ГБ. Пользователь kolkov измерил более 20 ГБ в неделю, а тяжёлые пользователи достигают 100 ГБ/неделю. Проблема сообщалась с начала 2025 года, но бот‑stale многократно закрывал её как дублирующую.

Каталог ~/.claude: более 3 ГБ без управления

Пользователь kolkov провёл аудит машины, использующей Claude Code 8 месяцев подряд, в Issue #5024:

pie title Использование каталога ~/.claude (≈ 3,1 ГБ)
    "projects/ (история сессий)" : 2500
    "debug/ (журналы отладки)" : 303
    "file-history/ (снимки файлов)" : 232
    "history.jsonl (глобальная история)" : 10
    "Прочее" : 55

Ключевые цифры: крупнейший файл JSONL‑сессии — 203 МБ, крупнейший под‑агент — 72 МБ, history.jsonl содержит более 37 000 записей. Данные не ротируются, не сжимаются и не очищаются. Снимки в file-history/ не дедуплицируются: один и тот же файл, отредактированный 10 раз, хранит 10 полных копий. Журналы в debug/ никогда не удаляются.

Файлы фоновых задач: 1,2 ТБ самореферентного цикла

Issue #32282 раскрывает невероятный дефект дизайна. Когда Claude Code запускает несколько фоновых агентов и автоматически исполняет bash‑команду для проверки прогресса, вывод этой команды записывается в тот же каталог, который затем попадает в glob‑шаблон, создавая бесконечный цикл обратной связи:

flowchart LR
    A["bash: for f in tasks/*.output; tail -5 $f"] --> B["вывод записывается в tasks/task-A.output"]
    B --> C["glob захватывает сам task-A.output"]
    C --> D["tail -5 читает собственный вывод"]
    D --> E["добавляет запись в себя"]
    E --> C

Множество пользователей сообщали о схожих проблемах: 1,2 ТБ, 460 ГБ, 303 ГБ, 235 ГБ, 480 ГБ, 36 ГБ. Комментарий к issue подсчитал 70 связанных открытых вопросов, разбитых на 15 групп; только в первых двух группах суммарное потребление диска достигло ~9,5 ТБ. Скорость записи достигала 425 МБ/с в течение 18 минут, пока диск не исчерпал место.

Каскадные отказы: необратимый крах после заполнения диска

Issue #24207 описывает катастрофическую цепочку событий после заполнения диска:

flowchart TD
    A["Дисковое пространство = 0"] --> B["не удалось записать .claude.json"]
    B --> C["создаётся нулевой файл"]
    C --> D["чтение приводит к недействительному JSON"]
    D --> E["перезаписываются все настройки проекта"]
    E --> F["повреждаются токены OAuth/API"]
    F --> G["требуется повторная аутентификация"]
    G --> H["остановка всех работающих агентов/сессий"]
    H --> I["даже после освобождения места восстановление невозможно"]

Нет предупреждений, нет плавного деградационного режима, нет пути восстановления. Пользователю приходится вручную завершать все процессы, освобождать место, восстанавливать конфигурацию и повторно аутентифицироваться.

Конкурентные записи: без блокировок, без транзакций, без координации

В каталоге ~/.claude/ единственный файл‑блокировка — .update.lock (5 байт). Все остальные файлы пишутся без какой‑либо защиты. При одновременной работе нескольких процессов (агент + под‑агент, обычный сценарий) записи в общие файлы происходят без координации:

ФайлЗаписываютМеханизм блокировкиИзвестные последствия
sessions-index.jsonкаждый сеанс проектанетгонки
{uuid}.jsonlосновной сеанс + сжатиенетпотеря записей
.claude.jsonкаждый процесснетповреждение конфигурации (8 сообщений)
file-history/*каждый Edit/Writeнетбесконечный рост

В Windows ситуация хуже: обходные схемы атомарной записи (.tmprename()) часто падают, потому что rename() возвращает EPERM, если целевой файл занят, полностью разрушая атомарность.

Память и CPU: от 13 ГБ RSS до паники ядра

Экстремальное потребление памяти в Windows

Issue #24840 фиксирует случай в Windows с RSS = 13,21 ГБ, виртуальной памятью = 47,17 ГБ, при общей оперативке машины = 42,56 ГБ. Ошибок страниц = 3,75 млн, указывающих на постоянный диск I/O. За 347 секунд работы пользовательское CPU‑время составило лишь 35 секунд — ≈ 90 % времени ушло на ожидание I/O и swap, из‑за чего другие приложения (например, браузер Opera) полностью перестали отвечать.

Паника ядра macOS

Issue #39253 описывает более тяжёлый исход: на MacBook Pro M3 Pro (18 ГБ RAM) запуск нескольких экземпляров Claude Code приводит к панике ядра macOS. Наблюдались два типа паники: Jetsam OOM kill (операционная система убивает процесс watchdogd из‑за нехватки памяти) и watchdog timeout (watchdogd не отчитывается более 90 секунд). Система перезагружается без предупреждения, без диалогов об ошибке и без возможности сохранить работу.

Оставшиеся «сиротские» процессы после закрытия терминала

Issue #44507 (апрель 2026, несколько дней назад) фиксирует базовый дефект управления жизненным циклом: после закрытия терминального окна процесс Claude Code продолжает работать. Один «сиротский» процесс за 21 день потребил 35,4 ГБ RSS, CPU = 95,5 %. Причина — отсутствие обработчика process.stdin.on("end") в главной точке входа CLI и более 55 таймеров setInterval (опрос, телеметрия, обновление статус‑бара и т.п.), удерживающих цикл событий Node.js живым. Куча V8 растёт без ограничений, нет нагрузки GC в простое, нет ограничения --max-old-space-size и нет «самоубийственного» watchdog.

100 % CPU «зависание»

Issue #27415 сообщает о 100 % загрузке CPU, вызванной бесконечным циклом posix_spawn в среде Bun. Issue #26224 описывает зависание Claude Code на 5–20 минут при обработке большого количества подсказок.

Системные провалы плоской файловой архитектуры

Выделение без очистки: повторяющийся паттерн во всех issue

Участник сообщества kolkov неоднократно подчёркивал, что все эти проблемы имеют одну общую причину:

Этот .node‑утечка — не отдельный баг, а симптом повторяющегося архитектурного паттерна, когда Claude Code выделяет ресурсы и не очищает их.

С 2025 по 2026 год проблема эволюционировала от единственного файла .claude.json к разросшимся JSONL‑файлам, но базовая архитектура осталась прежней: плоские файлы, отсутствие блокировок, отсутствие транзакций, отсутствие очистки и сжатия.

SQLite и локальный демон как альтернативные решения

Сообщество неоднократно предлагало заменить плоские файлы на SQLite. База данных SQLite обеспечивает атомарность записи (WAL‑режим), транзакции, встроенное сжатие, TTL‑очистку, дедупликацию контента и кроссплатформенную согласованность.

Другой совет — ввести локальный демон (подобно LSP‑серверу или Docker‑архитектуре), к которому все процессы Claude Code будут обращаться через IPC, обеспечивая координацию без изменения хранилища.

Сравнение обратного анализа сообщества и бота‑stale

Комментарий участника gebeer точно резюмирует ситуацию:

Спасибо за ваш детальный анализ. Это должно было быть сделано поддержкой давно.

kolkov добавил:

Ирония в том, что сообщество фактически делает отладку за них — обратный анализ, трассировка путей ошибок, предложения исправлений с кодом — а реакция — бот, закрывающий всё через 60 дней.

Сравнение с другими инструментами управления ресурсами

GitHub Copilot работает как расширение VS Code, подпадающее под ограничения памяти и управления жизненным циклом хоста; Cursor, форк VS Code, наследует ту же модель; оба используют SQLite или аналогичную базу данных, естественно поддерживая конкуренцию и транзакции. Claude Code выбрал отдельный процесс + плоские файлы, но не реализовал типичные механизмы управления ресурсами — нет ограничения памяти, нет квот диска, нет watchdog‑процесса, нет плавного завершения. Его поведение ближе к прототипу, а не к готовому к продакшн решению.

Парадокс между способностями модели и качеством инженерии

11,3 МБ однопакетный файл, 413 синхронных вызовов ФС, 1087 обёрток CJS/ESM, отсутствие очистки ресурсов, отсутствие контроля конкуренции, отсутствие мониторинга дискового пространства — это не редкие случаи, а системные архитектурные дефекты. С августа 2025 (Issue #5024) по апрель 2026 (Issue #44507) сообщество постоянно сообщает о тех же типах проблем, предлагает детальные анализы и решения, но многие issue помечаются как «не планируется» или автоматически закрываются ботом‑stale. Инструмент AI‑кодинга, чья собственная кодовая база требует аудита и исправления со стороны сообщества, представляет собой интересный парадокс.

Если вы используете Claude Code, рекомендуется регулярно проверять размер каталога ~/.claude, очищать временные .node‑файлы и перед закрытием терминала корректно завершать процесс через Ctrl+C. Если место на диске внезапно исчезает, теперь вы знаете, где искать причину.