status: experimental shell: bash license: MIT

codex-vscode-healthStop the Codex sidebar from hitting renderer_ready_timeout

A health gate for the Codex VS Code extension on remote hosts. One bash script checks the memory, load and extension pile-up that starves the 30 second webview budget, then tells you what to fix.

git clone https://github.com/MHJoy99/codex-vscode-health.git

Not affiliated with OpenAI or Microsoft. The terminal shows an illustrative healthy run in the real output format of bin/vscode-health.sh.

The failure

The sidebar dies. The backend is fine.

Codex shows “could not start its user interface” on a VS Code Remote host, yet codex app-server answered its handshake. That mismatch is the signature this repo is built around.

Client log: webview dead

[CodexWebviewProvider] Webview renderer did not become ready after 30000ms
reason=renderer_ready_timeout

The renderer (Electron, on your local machine) never signalled ready within 30 s.

Server log: backend healthy

codex app-server: Initialize received id=1

Backend IPC works, and there is no webview deadline on this side. Investigate host pressure and client extension state, not the app-server protocol.

elapsedMs=30001A hard 30 second readiness timeout that does not stretch under load.
receivedWebviewMessage=trueThe webview ran some JS and posted a message, but never sent ready. A slow main thread, not a missing bundle.
codex in a terminalThe CLI fallback keeps working while the webview does not.

How it works

Catch the pressure before the 30 seconds run out.

Server-side memory and load pressure delays extension-host activation until the fixed webview budget expires. The gate reads those signals first and warns you while the sidebar still works.

From host pressure to renderer_ready_timeout, and where the health gate sits The script bin/vscode-health.sh reads host pressure. Unchecked, pressure starves the extension host, which makes the webview miss its 30 second budget and log renderer_ready_timeout. The codex app-server backend stays healthy throughout. bin/vscode-health.sh reads memory, load, disk, extensions exit 0 healthy / 1 warn / 2 critical warns here, before the budget runs out Host pressure load, memory, swap,duplicate helpers, AI extensions extensionHost starved activation slips pastthe webview budget Webview not ready renderer_ready_timeoutafter the 30 s budget codex app-server healthyInitialize received id=1 From host pressure to renderer_ready_timeout, and where the health gate sits The script bin/vscode-health.sh reads host pressure. Unchecked, pressure starves the extension host, which makes the webview miss its 30 second budget and log renderer_ready_timeout. The codex app-server backend stays healthy throughout. bin/vscode-health.sh reads memory, load, disk, extensions exit 0 healthy / 1 warn / 2 critical Host pressure load, memory, swap, helpers, AI extensions extensionHost starved activation slips past the webview budget Webview not ready after 30 s renderer_ready_timeout codex app-server healthy Initialize received id=1
Health gate reads the hostPressure buildsFailure signatureBackend unaffected

What it checks

Nine checks, thresholds tuned from a real incident.

Each check prints a cyan ▶ line with the measured value, then a green ✔, yellow ⚠ or red ✖ verdict. Warnings and criticals are counted into the exit code.

1

Memory and swap

Reads free -m. Low available memory is the first thing that starves the extension host.

warn avail < 2500Mcrit avail < 1500Mwarn swap used > 3000M
2

CPU load

Compares 1-minute load from /proc/loadavg to the core count.

warn > nproccrit > 1.5 x nproc
3

Disk /

Webview assets and sqlite need headroom. The failure host sat at 84%.

warn ≥ 80%crit ≥ 90%
4

Duplicate kilo serve

Counts kilo serve --port 0 processes leaked after reloads.

warn > 1--fix kills older
5

extensionHost count

More than one usually means a reload loop or a leaked window. It tells you to reload the window, never to pkill.

warn > 1
6

~/.codex bloat

Total size and logs_2.sqlite, plus a scan of Codex.log for stale_rollout_path_retained.

warn total > 400Mwarn sqlite > 100M
7

Codex extension installs

Looks for openai.chatgpt-* under ~/.vscode-server/extensions. Exactly one is healthy; leftovers cause version drift.

warn if 0 or > 1
8

AI extension pile-up

Tracks five AI extensions that all activate on startup and compete for the renderer budget.

warn > 3 of 5 tracked
9

Old VS Code logs

Log sets older than 14 days in ~/.vscode-server/data/logs. Safe to prune, never touches sessions.

warn > 14 days--fix prunes

The incident, against the thresholds

Observed on 2026-09-16 at failure time (6 vCPU, 7.8G RAM host). Every signal had already crossed its warning line. Thresholds are tuned from this one host, so adjust them for yours.

Memory available1.8G
0warn < 2500M, crit < 1500M4000M
Load (6 vCPU)7.2
0warn > 6, crit > 912
Swap used3.6G
0warn > 3000M5000M
Disk /84%
0warn ≥ 80%, crit ≥ 90%100%
~/.codex total459M
0warn > 400M600M
logs_2.sqlite136M
0warn > 100M200M

Safe by design

Read-only by default. --fix does three things.

Safe to run over SSH or from cron in check-only mode. The script never takes down the shared box your Codex session lives on.

0

Healthy

RESULT: HEALTHY — renderer budget looks safe.

1

Warning

Healthy enough now. Run with --fix and keep AI extensions to 1–2 per window.

2

Critical

Free RAM, reload the window. Prints client-side recovery steps too.

What --fix does

  • Kills older duplicate kilo serve --port 0, keeps the newest.
  • Prunes ~/.vscode-server/data/logs/20* older than 14 days.
  • Backs up, then runs VACUUM on ~/.codex/logs_2.sqlite, only when app-server is stopped.

What it never touches

  • php-fpm, mysql, nginx, reverb, queue workers, prod htdocs.
  • The newest kilo serve and any extensionHost (killing it would drop your SSH).
  • Codex session rows or files in ~/.codex. No rm -rf.

Quick start

Clone it, run it, read the exit code.

Plain bash on the remote host. No dependencies beyond coreutils and procps.

git clone https://github.com/MHJoy99/codex-vscode-health.git
cd codex-vscode-health
chmod +x bin/vscode-health.sh

# read-only check, safe in cron/SSH
bin/vscode-health.sh

# check + safe fixes only
bin/vscode-health.sh --fix
# check-only from cron, every 15 minutes (never --fix unattended)
*/15 * * * * /root/codex-vscode-health/bin/vscode-health.sh >> ~/.codex/health.log 2>&1

Exit codes: 0 healthy, 1 warning, 2 critical.

  1. 1Run the check. It reads ~/.vscode-server and ~/.codex on the host the extension runs on.
  2. 2Fix the warnings. Use --fix for the safe three, and drop to 1–2 AI extensions per window.
  3. 3Reload the window. Developer: Reload Window, then retry with a single AI extension.
  4. 4Still failing? Follow the runbook below. If the server is green, the problem is on the client.

Runbook

Seven steps. Stop at the first fix.

Condensed from docs/RUNBOOK.md. Each step ends with the signal that tells you it worked.

  1. 1

    Confirm the backend is healthy

    Look for Initialize received id=1 and renderer_ready_timeout in Codex.log. Both present means this runbook applies.

    GreenInitialize received id=1
  2. 2

    Run the read-only check

    bin/vscode-health.sh; echo "exit=$?". If disk is at 90% or more, stop and free space before any update.

    GreenRESULT: HEALTHY, exit=0
  3. 3

    Apply the safe auto-fix

    bin/vscode-health.sh --fix. Removes older duplicate kilo serve and logs older than 14 days. If only one kilo is running, do not kill it.

    Green1x kilo, 0 old logs
  4. 4

    Reload and test one extension

    Developer: Reload Window, then Reload With Extensions Disabled and enable only Codex. Do not pkill the extension host.

    GreenSidebar loads in < 30s
  5. 5

    Reinstall on version drift

    More than one (or zero) openai.chatgpt-* installs, or a version mismatch: uninstall, reload, install one current version. Match client and server code --version.

    Greeninstalls: 1
  6. 6

    VACUUM, only while stopped

    Confirm app-server is stopped, back up logs_2.sqlite, then VACUUM. If it is running, close the Codex panel and retry.

    Greensqlite < 100M
  7. 7

    Clear the Windows client cache

    With VS Code closed, remove %APPDATA%\Code\Cache and GPUCache, then try code --disable-gpu. Do not delete all of %APPDATA%\Code.

    GreenSidebar renders

Safety: read first

  • Never kill or touch php-fpm, mysql, nginx, Reverb, queue workers or prod htdocs.
  • Never pkill -f extensionHost and never kill the newest kilo serve.
  • Never delete ~/.codex files or sqlite rows. VACUUM only with a backup, only while stopped.

FAQ

Questions, answered from the repo.

What is renderer_ready_timeout in the Codex VS Code extension?

It is the reason string logged when the Codex sidebar webview does not signal ready inside a fixed 30 second budget: [CodexWebviewProvider] Webview renderer did not become ready after 30000ms reason=renderer_ready_timeout. In the documented incident the backend was fine, with codex app-server: Initialize received id=1 in the server log, so the failure was in the webview handshake, not the app-server protocol.

What causes renderer_ready_timeout on a VS Code Remote host?

In the one incident this repo documents (2026-09-16), server-side memory and CPU pressure delayed extension-host activation past the 30 second budget: load 7.2 on 6 vCPU, about 1.8G memory available, 3.6G swap in use, duplicate extensionHost and kilo serve processes, a 459M ~/.codex and several AI extensions. DIAGNOSIS.md ranks resource starvation first, then extension-host contention, bloat, version drift and renderer throttling.

How do I run the health check?

Clone the repo, make the script executable and run it: bin/vscode-health.sh. It is read-only by default. The exit code is 0 for healthy, 1 for warning and 2 for critical.

What does --fix change? Is it safe?

Only three things: it kills older duplicate kilo serve --port 0 processes (keeping the newest), prunes ~/.vscode-server/data/logs/20* older than 14 days, and takes a backup then runs VACUUM on ~/.codex/logs_2.sqlite, but only when app-server is stopped. It never touches php-fpm, mysql, nginx, reverb, queue workers, prod htdocs, the newest kilo serve, extensionHost or Codex session rows.

Can I run it from cron?

Yes, in check-only mode. The prevention guide suggests */15 * * * * /root/codex-vscode-health/bin/vscode-health.sh >> ~/.codex/health.log 2>&1 and says never to run --fix unattended.

Does it fix the problem on my Windows machine?

Not directly. The renderer runs on the client, not the server. The script fixes and reports server-side pressure; on a critical result it prints client-side steps (reload with extensions disabled, update Codex and match local and remote VS Code versions, clear %APPDATA%\Code\Cache and GPUCache, try --disable-gpu). The runbook covers the same steps.

Does the Codex CLI still work when the sidebar fails?

Yes. Running codex in a terminal keeps working when the webview does not, so it is the fallback while you triage.

What does it need, and is it production-ready?

It is plain bash with no dependencies beyond coreutils and procps; the optional VACUUM path uses sqlite3. The project is labelled experimental: the shellcheck badge is still TODO and every threshold is tuned from a single incident on a 6 vCPU, 7.8G host, so adjust them for your machine and read DIAGNOSIS.md before changing them.

How do I report a new renderer_ready_timeout case?

Open a GitHub issue with the script output, free -m and the Codex extension version. Scrub Codex.log first and attach only a slice around the signature; never paste tokens or ~/.codex/auth.json.