Skip to content
Latchkey

How to Poll a Health Check Until It Returns 200 in GitHub Actions

A freshly deployed service is not ready instantly, so poll its health endpoint in a loop until it returns 200 rather than testing once and failing.

Loop on curl -o /dev/null -w "%{http_code}" against /healthz, sleeping between attempts, and exit non-zero if it never reaches 200 within a bounded number of tries.

Steps

  • Set a max attempt count and a sleep interval.
  • Capture the HTTP status code from curl with -w "%{http_code}".
  • Break the loop on 200; fail the job if the loop exhausts.

Workflow

.github/workflows/ci.yml
- name: Wait for healthy
  env:
    BASE: ${{ vars.DEPLOY_URL }}
  run: |
    for i in $(seq 1 30); do
      code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/healthz" || true)
      if [ "$code" = "200" ]; then echo "healthy after $i tries"; exit 0; fi
      echo "attempt $i: got $code, retrying"; sleep 10
    done
    echo "never became healthy"; exit 1

Gotchas

  • Add || true to the curl so a connection refused early does not abort the loop under set -e.
  • Bound total wait (attempts x sleep) below the job timeout-minutes so the loop, not the runner, controls failure.
  • A health check that only proves the process started is weak; check dependencies in a readiness endpoint.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →