Health Checks skill for Codex

Probes that heal instead of causing outages. Codex gives liveness, readiness and startup checks distinct jobs, keeps database and downstream calls out of liveness so a dependency blip cannot trigger a restart storm, and sets probe budgets from measured startup times. It adds a readiness flip and preStop delay for clean rollouts, and proves the design by killing a dependency and freezing a process in staging.

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- health-checks

Installs to ~/.agents/skills/health-checks/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $health-checks, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Implements liveness, readiness and startup checks that help instead of causing outages - separate endpoints with distinct semantics, dependency checks only where they belong, Kubernetes probe timings, graceful shutdown that drains traffic, load balancer and Docker HEALTHCHECK settings, and gRPC health. Use when adding /healthz or /readyz endpoints, writing Kubernetes probes, debugging restart loops or 502s during deploys, or reviewing health checks that call the database.

Use it when

  • A service needs health endpoints and probe configuration
  • Pods restart in loops during dependency outages
  • Deploys produce 502s or dropped requests
  • Slow-starting apps get killed before they finish booting

Use something else when

How to check the result

In staging, stopping the database causes no pod restarts and fast 503s, a frozen process is restarted by liveness, and a rolling deploy under load shows zero 5xx at the load balancer.

The mistake it prevents

Checking the database from the liveness probe, so a short database outage restarts every replica at once.

~/.agents/skills/health-checks/SKILL.md

--- name: health-checks description: Implements liveness, readiness and startup checks that help instead of causing outages - separate endpoints with distinct semantics, dependency… license: MIT ---

Done well means: a process is restarted only when restarting fixes it, traffic is routed only to instances that can serve it, slow starters are not killed while booting, and a dependency outage degrades the service instead of making the orchestrator kill every replica at once.

Inspect first

  1. Read AGENTS.md; find existing endpoints (rg -n "healthz|readyz|livez|/health|HEALTHCHECK|livenessProbe|readinessProbe|startupProbe").
  2. Read the Kubernetes manifests or Helm values, ECS task definitions, load balancer target group settings and Dockerfile for current probe config.
  3. Measure startup: how long from process start to first successful request (kubectl logs timestamps, or run locally and time it). Note the p99, not the best case.
  4. List dependencies and decide which are hard (cannot serve any request without it) versus soft (feature degraded without it).

Semantics

CheckQuestionFailure actionShould include dependencies?
Liveness /livezIs this process wedged beyond self-recovery?Restart containerNo. Only in-process state: event loop responsive, no deadlock
Readiness /readyzShould this instance receive new traffic now?Remove from endpoints, no restartHard local prerequisites: warm caches loaded, connection pool established. Shared dependencies with care (see below)
Startup /startupz or reuse /livezHas the app finished booting?Restart only after the budget expiresNo
Deep status /status (internal)What is the state of each dependency?None; for humans and dashboardsYes, with timeouts, never wired to a probe

The cardinal rule: a liveness probe that checks the database turns a database blip into a restart storm across every replica, which makes recovery slower.

Readiness and shared dependencies: if the database is down for everyone, marking all replicas unready removes the whole service from the load balancer and users get connection errors instead of a clean 503 with a retry hint. Prefer: readiness fails only on instance-local problems; the app returns fast 503s for requests needing a down dependency, and alerts fire on the error rate.

Endpoint implementation

  • Cheap: no allocation-heavy work, no external calls in liveness, response under 100 ms.
  • Unauthenticated but not public: serve on an internal port or block at the ingress.
  • Return 200 or 503 with a tiny JSON body; do not log every probe request.
  • Readiness flips to 503 as soon as shutdown starts (SIGTERM), before the server stops.

Node (Express) sketch:

let ready = false;
let shuttingDown = false;

app.get('/livez', (_req, res) => res.status(200).json({ status: 'ok' }));
app.get('/readyz', (_req, res) =>
  ready && !shuttingDown ? res.status(200).json({ status: 'ready' }) : res.status(503).json({ status: 'not ready' }),
);

await warmUp();          // migrations checked, pools connected, caches primed
ready = true;

process.on('SIGTERM', () => {
  shuttingDown = true;   // endpoints controller removes the pod
  setTimeout(() => server.close(() => process.exit(0)), 10_000); // let in-flight and late requests finish
});

For gRPC, implement the standard grpc.health.v1.Health service and use the native grpc probe in Kubernetes rather than shipping grpc_health_probe in the image.

Kubernetes probes

startupProbe:
  httpGet: { path: /livez, port: http }
  periodSeconds: 5
  failureThreshold: 30          # 150 s budget; set from measured p99 startup x 1.5
livenessProbe:
  httpGet: { path: /livez, port: http }
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 3           # ~30 s of consecutive failure before restart
readinessProbe:
  httpGet: { path: /readyz, port: http }
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 2
lifecycle:
  preStop:
    sleep: { seconds: 5 }       # Kubernetes 1.30+; older: exec ["sleep","5"] if the image has sleep
terminationGracePeriodSeconds: 30
  • With a startup probe, liveness and readiness do not run until it succeeds, so you do not need a large initialDelaySeconds.
  • timeoutSeconds defaults to 1 s; a GC pause or a busy event loop exceeds it. Use 2-5 s.
  • terminationGracePeriodSeconds must exceed preStop sleep plus the app’s drain time.
  • Exec probes fork a process every period; prefer HTTP or gRPC probes.
  • Do not reuse the same aggressive settings for liveness and readiness; liveness should be the most tolerant of the three.

Other platforms

PlatformSettingAdvice
AWS ALB / NLB target grouphealth check path, interval, healthy/unhealthy thresholdsPoint at /readyz; set deregistration delay to cover in-flight requests
ECScontainer healthCheck (restarts task) plus target group checkContainer check = liveness semantics only
Docker / ComposeHEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["/app/healthcheck"]Use a tiny binary or script in the image; curl may not exist in slim images
Cloud Run / App Runnerstartup and liveness probes in service configSame semantics as Kubernetes
Nomad / Consulservice checksReadiness semantics; Consul removes unhealthy instances from DNS

Workflow

  • Classify dependencies as hard-local, shared or soft
  • Implement /livez (process only) and /readyz (local readiness + shutdown flag)
  • Add optional /status for humans with per-dependency timeouts
  • Measure startup p99; set the startup probe budget
  • Set probe timeouts and thresholds; add preStop and grace period
  • Drop probe requests from access logs and traces

Verification

  • Kill the database in a staging environment: pods must stay running (no restarts in kubectl get pods -w), the service returns fast 503s, and it recovers by itself when the database returns.
  • Freeze the process (kill -STOP <pid> inside the container in staging) and confirm liveness restarts it after roughly periodSeconds x failureThreshold.
  • Run a rolling deploy under load ($load-testing or a simple hey/k6 loop) and confirm zero 5xx at the load balancer during the rollout.
  • kubectl describe pod shows no probe failures during normal operation.

Output

Endpoint contract (path, port, what each checks, status codes), probe YAML with the measured startup time behind each number, and the results of the three staging tests.

Gotchas

  • A health endpoint behind authentication middleware returns 401, which probes treat as failure.
  • Probes hitting the same thread pool as user traffic fail under load, triggering restarts exactly when capacity is needed; give them a cheap path.
  • Sidecars (service mesh proxies) need to be ready before the app accepts traffic and must outlive it on shutdown; use native sidecar containers where available.
  • Returning 200 from /readyz before migrations or cache warm-up finish causes errors on every deploy.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Health Checks"
  short_description: "Probes that heal instead of causing outages"
  default_prompt: "$health-checks Add proper liveness and readiness endpoints to this service and the Kubernetes probes"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem