A health check is an automated, repeated test that determines whether a server, process or service is able to do its job, returning a simple verdict such as healthy or unhealthy. In servers, within monitoring and logs, health checks are the active counterpart to passive log analysis: instead of waiting for errors to appear in an error log or access log, the monitoring system asks the service directly at regular intervals.
The verdict is consumed by machines as much as by people. Load balancers remove unhealthy backends from rotation, orchestrators and supervisors restart failed instances, and monitoring systems raise alerts. A well-designed health check therefore has to be fast, cheap and honest about what it actually verifies.
How a health check works
A checker sends a probe to a target at a fixed interval, waits up to a timeout for the answer and compares the result with an expected condition, such as an HTTP status in the 200 range, an open TCP port or a command exit code of zero. Because single probes can fail for trivial reasons, the state changes only after several consecutive failures or successes, which provides hysteresis and prevents flapping.
| Parameter | Typical value | Effect of changing it |
|---|---|---|
| Interval | 5 to 30 s | Shorter detects faster but adds load |
| Timeout | 1 to 5 s | Must be shorter than the interval |
| Unhealthy threshold | 2 to 5 failures | Higher avoids false alarms, slows detection |
| Healthy threshold | 2 to 3 successes | Prevents returning a still-unstable node |
| Start period | 10 to 120 s | Ignores failures while the service boots |
These values define detection time. With a 10-second interval and a threshold of three, a dead backend is removed after roughly 30 seconds, which may be too slow for a payment service or perfectly adequate for a reporting tool.
Types of health checks
Health checks range from shallow tests of reachability to deep tests of real functionality. Deeper checks catch more problems, but they cost more and can fail for reasons outside the service itself.
| Type | What it verifies | Blind spot |
|---|---|---|
| Ping or ICMP | Host is reachable on the network | Says nothing about any service |
| TCP connect | Port accepts connections | Application may still return errors |
| HTTP endpoint | Application answers a request correctly | Depends on what the endpoint checks |
| Deep dependency check | Database, cache and queues respond | May fail because of a shared dependency |
| Synthetic transaction | A full user flow succeeds | Slow and expensive to run often |
A dedicated health endpoint, often a path such as /health or /healthz, is the common pattern for web services. It should return quickly, avoid heavy work and never expose sensitive details such as versions or connection strings to unauthenticated callers.
Liveness, readiness and startup checks
Container platforms separate health into distinct questions, and the distinction is useful on any server. Treating them as one check is a common source of unnecessary restarts and outages.
| Check role | Question it answers | Action on failure |
|---|---|---|
| Liveness | Is the process stuck beyond recovery | Restart the instance |
| Readiness | Can it serve traffic right now | Stop sending traffic temporarily |
| Startup | Has initialization finished | Delay other checks until it has |
The key rule is that liveness must not depend on external systems. If a liveness check fails whenever the database is slow, every instance restarts at once during a database incident, turning a partial slowdown into a complete outage. Dependency problems belong in readiness checks, which only remove instances from traffic.
Health checks compared with logs and metrics
Health checks answer a yes or no question now, while logs and metrics explain what happened and why. They complement each other: a failing health check tells an operator where to look, and the application log or error log tells them what went wrong.
| Signal | Strength | Limitation |
|---|---|---|
| Health check | Immediate, actionable verdict | Little detail about the cause |
| Access log | Real traffic, status codes, timings | Silent when no traffic arrives |
| Error log | Exact failure messages | Only covers errors that are logged |
| Metrics | Trends, saturation, latency percentiles | Need thresholds to become alerts |
Frequent probes also generate entries in the access log. Many teams filter health check requests from the log or log them at a lower level, so that thousands of identical lines do not hide real traffic or inflate log rotation volume.
Designing reliable health checks
- Check what users actually need: a 200 response from a static page proves little if the application cannot reach its data.
- Keep endpoints lightweight and cached where needed, so that probes from many load balancers do not overload the service.
- Probe from outside the host as well, because a local check cannot detect network or DNS failures.
- Set timeouts below the interval to prevent overlapping probes.
- Alert on sustained failure, not single misses, and include the failing check in the alert text.
A false positive health check, one that reports healthy while users see errors, is more dangerous than no check at all, because it creates false confidence. Periodically breaking a dependency in a test environment confirms that the check really detects it.
In simple terms
A health check is like a nurse checking a patient’s pulse every few minutes. The nurse does not run a full examination each time, just a quick test that shows whether things are generally fine.
If the pulse is missing several times in a row, the nurse calls for help. Servers work the same way: an automatic check asks each service whether it is working, and after a few failed answers the system stops sending visitors there, restarts it or alerts a person.
A practical example
A web application runs on four servers behind a load balancer. Each server exposes a readiness endpoint that confirms the application can reach its database and cache within 500 ms. The load balancer probes it every 10 seconds with a 3-second timeout and removes a server after three consecutive failures.
During a routine update, one server loses its database connection because of a wrong configuration value. Within about 30 seconds the load balancer stops sending traffic to it, and the other three servers absorb the load. The monitoring system sends an alert naming the failed check, the engineer finds the configuration error in the error log and fixes it, and visitors never see an error page.