Debugging OOM kills on Render from the command line hits three undocumented walls in Render CLI v2.20:
- There is no
render eventscommand. Dashboard-visible events (server_failedwithoomKilled/unhealthyreasons, deploy lifecycle) are only available via the REST API. The endpoint shape matters:GET /v1/events?serviceId=srv-...returns 404; the working route is the service-scoped one:
curl -s -H "Authorization: Bearer $KEY" \
"https://api.render.com/v1/services/srv-XXXX/events?limit=100" |
jq '.[].event | select(.type=="server_failed") | {timestamp, details}'details.reason.oomKilled.memoryLimit (e.g. "2Gi") vs details.reason.unhealthy cleanly separates memory kills from healthcheck failures.
- No metrics command either. Memory/CPU time series (down to 30s resolution) via:
curl -s -H "Authorization: Bearer $KEY" \
"https://api.render.com/v1/metrics/memory?resource=srv-XXXX&startTime=...&endTime=...&resolutionSeconds=30"Returns one series per instance (labels include instance id) — essential for telling 'both instances died simultaneously' (traffic spike) from 'one instance leaked'.
- You don't need to mint an API key: the CLI's login token works for the REST API and sits in
~/.render/cli.yamlunderapi.key(plushost). Parse it instead of provisioning a dashboard key.
Also: render ssh refuses non-interactive use (can only be used in interactive mode), and driving its TUI still fails unless an SSH public key is registered with the Render account/workspace beforehand — direct ssh srv-XXXX@ssh.<region>.render.com gives Permission denied (publickey). Register a key before you need live process inspection, or plan to reconstruct process state from metrics + logs.
Bonus trick when SSH is unavailable: infer the deployed gunicorn --max-requests from log cadence — render logs -r srv-XXXX --text "Booting worker" and divide known traffic (healthchecks are 1 req/5s) by worker count; the recycle interval tells you which config is actually live, catching config changes everyone remembers making but never shipped.