Framework Guide
Laravel Health Check
Set up health check endpoints and uptime monitoring for your Laravel application. Simple patterns for production-ready monitoring.
Simple Health Route
// routes/web.php or routes/api.php
Route::get('/health', function () {
return response()->json([
'status' => 'healthy',
'timestamp' => now()->toISOString()
]);
});
Health Controller
// app/Http/Controllers/HealthController.php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
class HealthController extends Controller
{
public function health(): JsonResponse
{
return response()->json(['status' => 'healthy']);
}
public function ready(): JsonResponse
{
$checks = [];
$healthy = true;
// Check database
try {
$start = microtime(true);
DB::select('SELECT 1');
$checks['database'] = [
'status' => 'ok',
'response_time_ms' => round((microtime(true) - $start) * 1000, 2)
];
} catch (\Exception $e) {
$healthy = false;
$checks['database'] = [
'status' => 'error',
'message' => $e->getMessage()
];
}
// Check cache/Redis
try {
$start = microtime(true);
Cache::put('health_check', 'ok', 10);
Cache::get('health_check');
$checks['cache'] = [
'status' => 'ok',
'response_time_ms' => round((microtime(true) - $start) * 1000, 2)
];
} catch (\Exception $e) {
$healthy = false;
$checks['cache'] = [
'status' => 'error',
'message' => $e->getMessage()
];
}
return response()->json([
'status' => $healthy ? 'healthy' : 'unhealthy',
'timestamp' => now()->toISOString(),
'checks' => $checks,
'version' => config('app.version', 'unknown')
], $healthy ? 200 : 503);
}
}
// routes/web.php
Route::get('/health', [HealthController::class, 'health']);
Route::get('/ready', [HealthController::class, 'ready']);
Using spatie/laravel-health
For a more robust solution, use the Spatie health package:
# Install
composer require spatie/laravel-health
php artisan vendor:publish --tag="health-config"
# config/health.php
use Spatie\Health\Checks\Checks\DatabaseCheck;
use Spatie\Health\Checks\Checks\CacheCheck;
use Spatie\Health\Checks\Checks\RedisCheck;
use Spatie\Health\Checks\Checks\UsedDiskSpaceCheck;
return [
'checks' => [
DatabaseCheck::new(),
CacheCheck::new(),
RedisCheck::new(),
UsedDiskSpaceCheck::new()
->warnWhenUsedSpaceIsAbovePercentage(70)
->failWhenUsedSpaceIsAbovePercentage(90),
],
];
# routes/web.php
use Spatie\Health\Http\Controllers\HealthCheckResultsController;
Route::get('/health', HealthCheckResultsController::class);
Exclude from CSRF
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'health',
'ready',
];
Check Queue Health
// Check if queue workers are running
try {
$queueSize = Queue::size('default');
$checks['queue'] = [
'status' => $queueSize < 1000 ? 'ok' : 'warning',
'pending_jobs' => $queueSize
];
} catch (\Exception $e) {
$checks['queue'] = [
'status' => 'error',
'message' => $e->getMessage()
];
}
Best Practices
- Skip middleware — Health checks shouldn't require auth or CSRF
- Check queue workers — Verify background jobs are processing
- Monitor disk space — Laravel logs can fill up disks
- Check scheduled tasks — Ensure cron is running