javidev/laravel-health-check

Artisan command that checks DB, cache, queue and storage, and prints a clean console report.

Maintainers

Package info

github.com/javierDev03/laravel-health-check

pkg:composer/javidev/laravel-health-check

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-27 20:05 UTC

This package is auto-updated.

Last update: 2026-07-27 20:05:14 UTC


README

Latest Version on Packagist GitHub Tests Action Status PHPStan Total Downloads License

Know if your Laravel app is actually healthy — in one Artisan command.

Database down? Redis unreachable? S3 failing writes? Queue stuck?
Stop guessing. Run app:health and get a clear, timed report in seconds.

php artisan app:health
  Health Check

+----------+--------+----------------------------------------+--------+
| Service  | Status | Detail                                 | Time   |
+----------+--------+----------------------------------------+--------+
| Database | ✔ OK   | Connection OK (mysql)                  | 4.2 ms |
| Cache    | ✔ OK   | Write/read OK (driver: redis)          | 1.1 ms |
| Queue    | ✔ OK   | Connection 'redis' OK (0 pending jobs) | 2.8 ms |
| Storage  | ✔ OK   | Write/read OK (disk: s3)               | 89 ms  |
+----------+--------+----------------------------------------+--------+

  All good (4/4)

Requires PHP 8.1+ and Laravel 10+.

Why this package?

Production incidents rarely start in your controllers. They start when MySQL refuses connections, Redis dies, S3 times out, or the queue connection breaks.

This package gives you a battle-ready way to:

Without this package With laravel-health-check
SSH in and poke each service manually One command, one report
Write ad-hoc scripts per project Install once, reuse everywhere
Guess what failed in CI / Docker Exit code 1 when something is broken
Build custom JSON for monitors --json out of the box

Built for developers who ship Laravel apps and want zero-friction observability at the infrastructure layer.

Features

  • One commandphp artisan app:health checks DB, cache, queue & storage
  • Beautiful console output — status, detail message, and duration per check
  • JSON mode — pipe into uptime tools, dashboards, or HTTP endpoints
  • Fail-fast for CI & containers--fail-on-error exits 1 on any failure
  • Zero extra config — uses your existing Laravel database, cache, queue, and filesystems config
  • Safe by default — probe keys/files are always cleaned up (try/finally)
  • Fluent APIDatabaseCheck::new()->connection('mysql')
  • Programmatic runner — inject HealthChecker anywhere in your app
  • Extensible — write custom checks in ~15 lines with AbstractCheck
  • Production-grade internalsfinal classes, enums, hrtime timing, PHPStan level 6, Pint, CI

Table of contents

Installation

Install via Composer:

composer require javidev/laravel-health-check

Laravel auto-discovers the service provider. No manual registration required.

Publish the config (optional)

php artisan vendor:publish --tag=health-check-config

This publishes config/health-check.php so you can enable, disable, or reorder checks.

Local / path development

Developing the package locally? Add a path repository to your app's composer.json:

{
    "repositories": [
        {
            "type": "path",
            "url": "../laravel-health-check"
        }
    ],
    "require": {
        "javidev/laravel-health-check": "*"
    }
}
composer update javidev/laravel-health-check

Usage

Console report

php artisan app:health

Runs every registered check and prints a table with service name, status, detail, and duration in milliseconds.

JSON output

Perfect for uptime monitors, external dashboards, or your own /health endpoint:

php artisan app:health --json
[
    {
        "name": "Database",
        "ok": true,
        "status": "ok",
        "message": "Connection OK (mysql)",
        "duration_ms": 4.21
    },
    {
        "name": "Cache",
        "ok": true,
        "status": "ok",
        "message": "Write/read OK (driver: redis)",
        "duration_ms": 1.08
    }
]

Fail on error

Exit with code 1 when any check fails — ideal for CI pipelines, cron jobs, and container healthchecks:

php artisan app:health --fail-on-error
Situation Exit code
All checks pass 0
One or more fail 1

Without --fail-on-error, the command always exits 0 so you can still inspect the report.

Configuration

// config/health-check.php

return [
    'checks' => [
        \JaviDev\HealthCheck\Checks\DatabaseCheck::class,
        \JaviDev\HealthCheck\Checks\CacheCheck::class,
        \JaviDev\HealthCheck\Checks\QueueCheck::class,
        \JaviDev\HealthCheck\Checks\StorageCheck::class,
    ],
];

Remove what you don't need. Add your own checks that extend AbstractCheck (or implement HealthCheck).

Available checks

Check What it does Fluent options
Database Opens a connection and runs select 1 ->connection('mysql')
Cache Writes, reads, and deletes a probe key ->store('redis')
Queue Resolves the connection and reports pending jobs ->connection('redis')
Storage Writes, reads, and deletes a probe file ->disk('s3')

All checks respect your existing Laravel configuration (database.default, cache.default, queue.default, filesystems.default).

Probe keys and files are always cleaned up, even when a check fails mid-way.

Programmatic usage

Use the same engine outside Artisan — controllers, jobs, Octane, whatever you need:

use JaviDev\HealthCheck\HealthChecker;
use JaviDev\HealthCheck\Checks\DatabaseCheck;
use JaviDev\HealthCheck\Checks\CacheCheck;

$report = app(HealthChecker::class)->run([
    DatabaseCheck::new()->connection('mysql'),
    CacheCheck::new()->store('redis'),
]);

if (! $report->ok()) {
    logger()->critical('Health check failed', $report->toArray());
    // notify Slack, abort deploy, etc.
}

return response()->json($report->toArray());

Custom checks

Extend AbstractCheck — timing and exception handling are handled for you:

<?php

declare(strict_types=1);

namespace App\HealthChecks;

use Illuminate\Support\Facades\Http;
use JaviDev\HealthCheck\Checks\AbstractCheck;
use JaviDev\HealthCheck\Checks\HealthCheckResult;

final class MeilisearchCheck extends AbstractCheck
{
    public function name(): string
    {
        return 'Meilisearch';
    }

    protected function check(): HealthCheckResult
    {
        $response = Http::timeout(3)
            ->get(config('scout.meilisearch.host').'/health');

        if (! $response->successful()) {
            return $this->fail('Unexpected status: '.$response->status());
        }

        return $this->pass('Cluster is healthy');
    }
}

Register it:

'checks' => [
    \JaviDev\HealthCheck\Checks\DatabaseCheck::class,
    \App\HealthChecks\MeilisearchCheck::class,
],

Scheduling

Keep an eye on production every few minutes.

Laravel 11+ (routes/console.php):

use Illuminate\Support\Facades\Schedule;

Schedule::command('app:health --fail-on-error')->everyFiveMinutes();

Laravel 10 (app/Console/Kernel.php):

protected function schedule(Schedule $schedule): void
{
    $schedule->command('app:health --fail-on-error')->everyFiveMinutes();
}

CI / Docker / Kubernetes

GitHub Actions

- name: Application health check
  run: php artisan app:health --fail-on-error

Dockerfile

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD php artisan app:health --fail-on-error || exit 1

Docker Compose

healthcheck:
  test: ["CMD", "php", "artisan", "app:health", "--fail-on-error"]
  interval: 30s
  timeout: 5s
  retries: 3

Architecture

Clean separation of concerns — the command never owns business logic:

app:health (Command)          ← presentation only
    └── HealthChecker         ← resolves & runs checks
            └── HealthCheckReport
                    └── HealthCheckResult[]
                            └── CheckStatus (enum)
Piece Responsibility
Command Table / JSON / exit codes
HealthChecker Orchestration + validation
AbstractCheck Shared hrtime timing + safety net
Checks One job each — final, fluent, focused

Testing

composer test        # PHPUnit
composer lint        # Laravel Pint
composer analyse     # PHPStan level 6
composer check       # all of the above

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details. Pull requests are welcome.

Security Vulnerabilities

If you discover a security-related issue, please open a private GitHub security advisory instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.