Liveness and readiness probes look almost identical in a Kubernetes manifest. They are configured the same way, they hit HTTP endpoints, they have the same parameters. It is easy to assume they do the same thing, or to configure them identically and move on.
They do fundamentally different things, and confusing them causes real problems in production. Here is what I learned while implementing them.
The core difference
Readiness controls traffic routing. Liveness controls container lifecycle. They solve completely different problems.
Why using the same endpoint for both is a mistake
The most common pattern I see is configuring both probes to hit the same /health endpoint. It seems logical — if the app is healthy, it should be both live and ready, right?
The problem emerges during startup. A Next.js application or any Node.js server takes time to initialise. During that period, the app might be alive — the process is running, the port is open — but not yet ready to serve requests. If your liveness probe fires too early and the app has not loaded yet, Kubernetes kills and restarts the container. That restart resets the timer. The container never gets a chance to finish starting up.
What the probes should actually check
The configuration — what to actually set
The initialDelaySeconds on the liveness probe is the most important parameter. Set it too low and you get crash loops. Set it too high and Kubernetes will not catch genuine failures quickly enough. For most Node.js applications, 30 seconds is a safe starting point. Profile your actual startup time and set it to roughly 1.5× that value.
Startup probes — the third option
Kubernetes 1.16 introduced a third probe type: the startup probe. It runs once during container startup and disables the liveness probe until it succeeds. This is the cleanest solution for applications with variable startup times.
With a startup probe, you can give a slow-starting container up to 5 minutes to initialise without loosening your liveness probe thresholds. Once the startup probe succeeds, the liveness probe takes over with its normal strict settings.
What I got wrong first
My first attempt used the same /health endpoint for both probes with an initialDelaySeconds of 5 seconds. The app took 12 seconds to start. Kubernetes killed the container after 3 failed liveness checks, restarted it, and the cycle repeated. The pod showed as Running but was never Ready.
The fix was two separate endpoints, a 30-second initial delay on liveness, and a startup probe to handle the variable startup window cleanly. After those changes, the pod came up reliably on every deployment.
The full Kubernetes implementation including probe configuration is documented on the Kubernetes Platform project page.