A health check endpoint lets load balancers, monitoring tools, container orchestrators, and your own scripts quickly verify whether your application is actually working — not just that the process is running.
Why "Process Running" Isn't Enough
A process can be alive but unable to serve requests — a stuck database connection, an exhausted connection pool, or a deadlocked thread all present as "running" to a process manager while being completely non-functional to real users.
What a Good Health Check Verifies
- The application process itself is responsive
- The database connection is alive
- Any critical external dependencies (Redis, external APIs) are reachable, if the app can't function without them
Basic Health Check (Node.js/Express)
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok' });
});
Health Check with Database Verification (Node.js)
app.get('/health', async (req, res) => {
try {
await db.query('SELECT 1');
res.status(200).json({ status: 'ok', database: 'connected' });
} catch (err) {
res.status(503).json({ status: 'error', database: 'disconnected' });
}
});
Basic Health Check (PHP/Laravel)
Route::get('/health', function () {
try {
DB::connection()->getPdo();
return response()->json(['status' => 'ok'], 200);
} catch (\Exception $e) {
return response()->json(['status' => 'error'], 503);
}
});
Basic Health Check (Python/Flask)
@app.route('/health')
def health():
try:
db.session.execute('SELECT 1')
return {'status': 'ok'}, 200
except Exception:
return {'status': 'error'}, 503
Testing Manually
curl -i http://127.0.0.1:3000/health
Using Health Checks with Docker
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
See Docker Restart Policies and Healthchecks Explained for full detail.
Using Health Checks with a Load Balancer
Configure your load balancer (or Nginx upstream) to periodically hit the health endpoint and automatically remove unhealthy backends from rotation — see How to Set Up Basic Load Balancing with Nginx.
Using Health Checks for Uptime Monitoring
Point an external monitoring service at your /health endpoint rather than just the homepage — it gives a faster, more specific signal than checking whether an entire page renders correctly.
Security Consideration: Don't Leak Sensitive Detail
Keep the health endpoint's response minimal in production — avoid returning internal error messages, stack traces, or infrastructure details that could help an attacker; a simple status code and generic JSON is sufficient.
Common Errors
Health check always returns 200 even when the app is broken — the endpoint isn't actually testing anything meaningful (like a database query); add a real dependency check as shown above.
Best Practices
- Verify actual dependencies (database, critical external services), not just that the process responds
- Keep the endpoint fast — avoid expensive operations that could themselves cause timeouts
- Don't expose sensitive internal details in the response
Related Articles
- Docker Restart Policies and Healthchecks Explained
- How to Set Up Basic Load Balancing with Nginx
- How to Manage Services with systemd and systemctl
