Health Checks and Kubernetes Probes for Laravel
Liveness, readiness, and startup probes are how Kubernetes decides if your pod is healthy. Laravel Health gives you a clean API for all three, plus Prometheus metrics.
Kubernetes probes are deceptively simple. You define an HTTP endpoint, Kubernetes hits it periodically, and if it returns a non-200 status code enough times, the container gets restarted (liveness) or removed from the service (readiness). Most teams start with a route that returns 200 OK and call it done.
The problem is that a process being alive isn't the same as being healthy. PHP-FPM can be running while the database connection pool is exhausted. Redis can be reachable but out of memory. The queue can be processing but the failure rate is 80%. A simple 200 OK tells Kubernetes nothing useful about the actual state of your application.
Three probe types, three purposes
Liveness probes answer: "Is the process stuck?" If the liveness probe fails, Kubernetes kills and restarts the container. This should be fast, cheap, and only check if the PHP process is responsive. Do not check external dependencies here. If your database is down, restarting your PHP container won't fix it.
Readiness probes answer: "Can this pod handle requests?" If the readiness probe fails, the pod is removed from the Service endpoints but not restarted. This is where you check dependencies: database connectivity, Redis availability, cache warmth.
Startup probes answer: "Has the application finished initializing?" This gives slow-starting applications time to warm up caches, run migrations, or build indexes.
Laravel Health implementation
Laravel Health provides three endpoints out of the box:
GET /health/liveness- Am I alive?GET /health/readiness- Can I handle requests?GET /health/startup- Am I done initializing?
Each endpoint runs a configurable set of checks and returns a structured JSON response with individual check results and an overall status.
Built-in checks
The package ships with checks for the most common dependencies:
Database - Runs a simple
SELECT 1query with configurable timeoutRedis - Pings the Redis connection, tests both default and named connections
Queue - Checks if the queue connection is reachable and workers are processing
Disk - Verifies that configured storage disks are writable with free space above a threshold
Memory - Uses System Metrics for container-aware memory checks against cgroup limits
CPU - Container-aware CPU utilization via System Metrics
Custom checks
Adding a custom check is a single class implementing HealthCheck. Register it in your config and assign it to the appropriate probe type. A search index check belongs on the readiness probe (not liveness), because a missing search index means the app can't serve search results, but the process itself isn't stuck.
Prometheus integration
Every check result is also exposed as a Prometheus gauge at /health/metrics. This gives you historical visibility into check results over time. If the database check starts taking 500ms instead of 3ms, your Prometheus alerts fire before the probe actually fails.
Deployment
A typical Kubernetes deployment uses the startup probe with a generous failure threshold (30 attempts at 2-second intervals = 60 seconds to initialize), the liveness probe at 10-second intervals for basic process health, and the readiness probe at 5-second intervals for dependency checks.
Install with composer require cboxdk/laravel-health and the endpoints are available immediately with sensible defaults. Customize checks per probe type in the published config file.