Ресурсная чёрная дыра Claude Code: от 11,3 МБ однопакетного файла до 1,2 ТБ поглощения диска
Categories:
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 ситуация хуже: обходные схемы атомарной записи (.tmp → rename()) часто падают, потому что 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. Если место на диске внезапно исчезает, теперь вы знаете, где искать причину.