Почему Codex может открыть 100 вкладок браузера — и что происходит на самом деле
Persistent sessions, parallel QA, retries и Chromium process lifetime
Локальный evidence-based разбор memory pressure встроенного браузера
Практические safeguards для browser-heavy Codex workflows
Вкладки Codex, управление ресурсами, renderer processes, memory pressure и cleanup

$ inspect codex_browser --resource-lifecycle
> tabs: routes × viewports × iterations × agents × retries
> pressure: renderers / memory / swap / timeouts
> controls: reuse / ownership / cleanup / hard-limitПосле объединения ChatGPT Work, Codex, Computer Use и встроенного браузера в одном desktop-приложении Codex научился редактировать код, открывать страницы, проверять интерфейсы, делать screenshots, переходить между routes и выполнять несколько задач параллельно.
Это сильно расширяет возможности AI-ассистента, но создаёт проблему управления ресурсами: во время долгой работы встроенный браузер может накопить десятки или даже более ста вкладок. На MacBook с 16 ГБ unified memory это приводит к высокому memory pressure, активному swap, замедлению tool calls и снижению производительности всей системы.
> Ключевой вывод: локальная проверка показывает, что проблема связана не только с визуальным интерфейсом, а с тем, как Codex создаёт, хранит, переиспользует и освобождает browser sessions.
Наблюдения ниже относятся к одной проверенной установке и описывают вероятный механизм, а не универсальный benchmark для каждой версии Codex или Mac.
Встроенный браузер — полноценная Chromium-среда
Это не лёгкая preview-панель. В исследованной установке работали ChatGPT/Codex 26.707.61608, build 5200, Chromium Framework 150.0.7871.115, отдельные renderer/GPU/network/storage процессы и отдельный browser profile в ~/Library/Application Support/Codex.
Практически внутри ChatGPT работает полноценный Chromium runtime. Он хранит страницы, navigation state, site data, downloads, authentication state и rendering processes. OpenAI также указывает, что встроенный браузер использует собственное состояние, а не обычный Chrome profile пользователя, и предназначен для публичных сайтов, локальной разработки, visual review и frontend testing.
Как обычный QA-цикл превращается в 100 вкладок
Достаточно типичного цикла проверки сайта:
- Codex меняет страницу.
- Открывает локальный URL и делает screenshot.
- Находит проблему и снова меняет код.
- Повторно открывает страницу для desktop и mobile.
- Переходит на другой route и повторяет цикл.
Если каждая проверка создаёт новую вкладку вместо навигации в существующей, вкладки быстро умножаются:
5 routes × 2 viewport sizes × 3 iterations = 30 tabs
30 tabs × 3 parallel agents = 90 tabsНесколько retries после timeout легко поднимают число выше 100. Общая модель выглядит так:
routes × viewports × iterations × agents × retriesВкладки привязаны к задачам и сохраняются
Локальное состояние приложения показало, что browser tabs сохраняются между действиями и задачами. В исследованном состоянии находились 23 уникальных browserTabId, вкладки из 16 задач, до четырёх сохранённых вкладок в одной задаче, а также URLs, titles, navigation state, runtime state и conversation identifiers.
Это означает, что браузер не организован вокруг одной глобально переиспользуемой вкладки. Задача может сохранять собственные страницы. Persistence полезен: пользователь возвращается в старую задачу и продолжает с того же места. Но без эффективной cleanup policy количество вкладок растёт вместе с числом задач и verification cycles.
Некоторые browser sessions сохраняются намеренно
В логах была найдена важная запись:
IAB_LIFECYCLE captured session route ... disposeAfterSessionActivity=falseЗначение disposeAfterSessionActivity=false указывает, что соответствующая browser session не должна автоматически уничтожаться сразу после завершения активности. В логах также присутствовали lifecycle events регистрации, rebinding и удаления browser sidebar windows.
Механизм удаления существует, но cleanup не происходит после каждой проверки и не обязательно освобождает каждую отдельную вкладку.
Browser processes тоже накапливаются
На момент проверки приложение имело 11 активных процессов Codex (Renderer), около 33 связанных с ChatGPT/Codex процессов, несколько SkyComputerUseClient и процессы с разным временем запуска. Их общий resident memory составлял примерно 3.6 GiB RSS.
Это не значит, что каждая вкладка всегда создаёт ровно один renderer. Chromium может объединять страницы или изолировать их по site и origin. Но общая зависимость сохраняется:
> Больше вкладок → больше активного page state → больше renderer/helper processes → выше расход памяти.
Локальные React/Next.js приложения, WebGL, карты, видео, сложная анимация и постоянные WebSocket connections делают удерживаемые страницы особенно дорогими.
Параллельные агенты умножают проблему
Codex рассчитан на параллельное выполнение задач. Несколько агентов могут одновременно открывать страницы, проверять разные routes, делать screenshots и повторять проверки.
Сам по себе parallelism не является ошибкой. Проблема возникает, когда каждый агент создаёт собственные вкладки, а после завершения работы они остаются активными.
Retries могут создать feedback loop
Открытие страницы и получение подтверждения — разные события:
- Команда открытия успешно выполняется, вкладка появляется.
- Tool не получает подтверждение вовремя.
- Операция завершается timeout и повторяется.
- Появляется duplicate tab.
В логах было много ссылок на timeout и retry. Не все они относились к браузеру, поэтому нельзя утверждать, что каждый timeout создавал вкладку. Но этот механизм хорошо объясняет появление групп одинаковых страниц за несколько секунд.
Он способен образовать самоподдерживающийся цикл:
more tabs → memory/CPU pressure → slower operations → timeouts → retries → more tabsЭто не проблема производительности M4
Apple M4 способен одновременно запускать Codex, локальные dev tools и несколько browser pages. Ограничением в описанном сценарии становится unified memory, а не raw CPU performance.
На машине с 16 ГБ одновременно работают macOS, ChatGPT/Codex, Chromium renderers, IDE, dev servers, terminals, Docker, обычный браузер и другие приложения. При высоком memory pressure macOS активно использует swap. Быстрый процессор не устраняет задержку от перемещения memory pages между RAM и storage.
Та же архитектурная проблема возможна на более мощном Mac. Дополнительная память лишь откладывает момент деградации, но не исправляет lifecycle management.
Есть ли настраиваемый лимит вкладок?
В исследованной конфигурации Codex не найден пользовательский hard limit. Не было настроек, эквивалентных следующим:
browser.max_tabs = 10
browser.reuse_tabs = true
browser.close_tabs_on_task_end = trueВ проверенной публичной документации также не указан максимум in-app tabs, автоматический least-recently-used eviction, обязательный tab reuse, cleanup после завершения задачи, renderer-process limit или memory-pressure threshold, останавливающий создание вкладок.
Agent thread limits не являются browser-tab limits. Даже один агент способен создать десятки вкладок во время долгого verification loop.
Кто отвечает: модель или приложение?
Ответственность разделена между двумя уровнями.
Модель и инструкции выбирают стратегию
Они определяют, открыть ли новую страницу, переиспользовать существующую, проверить routes параллельно или повторить операцию.
Приложение и browser tooling управляют ресурсами
Они создают и хранят вкладку, назначают browserTabId, привязывают её к задаче, закрывают страницу, завершают renderers, освобождают inactive sessions и применяют resource limits.
Модель может выбрать неэффективную стратегию «новая вкладка для каждой проверки». Но накопление очень большого числа активных вкладок без надёжного cleanup остаётся проблемой application-level resource management.
Что должна обеспечивать более безопасная архитектура
Tab reuse
Если нужный origin уже открыт, Codex должен переходить в существующей вкладке, а не создавать новую.
Ясное ownership и hard limit
Приложение должно знать, какая задача создала вкладку и можно ли её закрыть. После определённого порога оно должно переиспользовать или приостанавливать вкладки либо запрашивать подтверждение.
Cleanup после завершения задачи
Временные страницы должны закрываться после verification, отмены или архивации задачи, а также после безопасного idle threshold.
Idempotent retries
Если navigation уже сработала, но acknowledgement потерялся, retry должен подключиться к существующей вкладке вместо создания duplicate.
Memory-pressure protection
При высоком pressure приложение должно приостанавливать background pages, выгружать renderers, предупреждать пользователя и останавливать неконтролируемое создание вкладок.
Временная защита на уровне инструкций
Пока приложение не применяет system-level limit, добавьте правила работы с браузером в инструкции проекта:
- Переиспользовать текущий browser binding и вкладку.
- Переходить в существующей вкладке вместо открытия новой.
- Держать не более трёх browser tabs на задачу.
- Закрывать временные вкладки сразу после проверки.
- Не запускать parallel browser QA без прямого запроса.
- Перед открытием проверять, не открыт ли target URL.
- После завершения или отмены задачи закрывать созданные ею вкладки.
Это уменьшает число лишних страниц, но не даёт системной гарантии: retries, restoration и lifecycle failures всё ещё могут создавать duplicates.
Вывод
Появление 50–100 вкладок лучше всего объясняется сочетанием факторов: создание новых вкладок вместо navigation, persistence на уровне задач, sessions с disposeAfterSessionActivity=false, удерживаемые renderer и Computer Use процессы, параллельные проверки, timeout retries и отсутствие найденного user-configurable hard limit.
Центральная проблема — не просто производительность MacBook и не только поведение модели. Это сочетание persistent browser sessions с недостаточным контролем количества вкладок и времени жизни ресурсов. Полноценной browser-среде нужны tab reuse, background suspension, idempotent navigation и предсказуемый cleanup.
Источники
Где это применимо
Browser lifecycle, Chromium resource pressure и безопасный Codex QA workflow
Материал полезен разработчикам, которые используют встроенный браузер Codex для долгих или параллельных frontend-проверок.
- Переиспользуйте текущую вкладку вместо открытия новой.
- Ограничивайте parallel browser QA и закрывайте временные tabs.
- Разделяйте instruction-level safeguards и системный lifecycle control.
tab_growth = routes * viewports * iterations * agents * retries;
if (target_url_open) navigate(existing_tab);
if (task_complete) close(temporary_tabs);