Navigation

Laravel

How to Implement a Basic Health Check Endpoint

Create a simple health check endpoint in Laravel for monitoring application status, database connectivity, and service availability.

Your app is running perfectly at 3 AM, but by morning it's completely dead. Sound familiar? Health check endpoints are like having a nurse check on your app every few minutes.

Table Of Contents

The Basic Setup

// routes/api.php
Route::get('/health', [HealthController::class, 'check']);

// app/Http/Controllers/HealthController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;

class HealthController extends Controller
{
    public function check()
    {
        $status = 'healthy';
        $checks = [];
        
        // Database check
        try {
            DB::connection()->getPdo();
            $checks['database'] = 'healthy';
        } catch (\Exception $e) {
            $checks['database'] = 'unhealthy';
            $status = 'unhealthy';
        }
        
        // Cache check
        try {
            Cache::put('health_check', 'test', 5);
            Cache::get('health_check');
            $checks['cache'] = 'healthy';
        } catch (\Exception $e) {
            $checks['cache'] = 'unhealthy';
            $status = 'unhealthy';
        }
        
        $response = [
            'status' => $status,
            'timestamp' => now()->toISOString(),
            'checks' => $checks
        ];
        
        return response()->json($response, $status === 'healthy' ? 200 : 503);
    }
}

Advanced health check with multiple services:

public function check()
{
    $checks = [
        'database' => $this->checkDatabase(),
        'redis' => $this->checkRedis(),
        'storage' => $this->checkStorage(),
        'external_api' => $this->checkExternalApi(),
    ];
    
    $healthy = collect($checks)->every(fn($check) => $check['status'] === 'healthy');
    
    return response()->json([
        'status' => $healthy ? 'healthy' : 'unhealthy',
        'timestamp' => now()->toISOString(),
        'version' => config('app.version', '1.0.0'),
        'environment' => app()->environment(),
        'checks' => $checks
    ], $healthy ? 200 : 503);
}

private function checkDatabase(): array
{
    try {
        $start = microtime(true);
        DB::select('SELECT 1');
        $duration = round((microtime(true) - $start) * 1000, 2);
        
        return ['status' => 'healthy', 'response_time' => "{$duration}ms"];
    } catch (\Exception $e) {
        return ['status' => 'unhealthy', 'error' => $e->getMessage()];
    }
}

The Health Check Protocol

The rules are simple: return 200 when everything's fine, 503 when something's broken. Your load balancer reads these status codes like a doctor reading vitals - 200 means "keep sending traffic," 503 means "this server needs help."

Simple one-liner health check:

// For basic needs
Route::get('/ping', fn() => response()->json(['status' => 'pong', 'timestamp' => now()]));

// With app info
Route::get('/status', fn() => response()->json([
    'app' => config('app.name'),
    'version' => config('app.version'),
    'environment' => app()->environment(),
    'uptime' => now()->diffInSeconds(new \DateTime('@' . $_SERVER['REQUEST_TIME']))
]));

Related: Laravel Collections: Beyond Basic Array Operations | Laravel Events and Listeners: Building Decoupled Applications | Building Multi-tenant Applications with Laravel: A Comprehensive Guide | Laravel Health Checks: Monitor App State in 2025 | Performance Optimization: Speed in Web Applications

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel