Technical article
Laravel health checks in production: what /up does and does not prove
Use Laravel's built-in /up route as a lightweight boot check, add only critical dependency probes and monitor user journeys separately.
- Laravel 13
- health checks
- uptime monitoring
- DiagnosingHealth
- deployment
- observability

In this article
The default /up route confirms that Laravel boots without an exception. It does not prove that mail can be sent, a payment provider is reachable or a portal shows correct data. Add dependency checks only when they define the availability you intend to measure.
Failure comparison: a boot error can fail /up, while a broken form may coexist with a successful /up response. Distinguish a lightweight availability check from a safe business-flow test.
- Identify which dependencies the health route actually checks.
- Bound external checks so monitoring cannot amplify an outage.
- Do not use real customer transactions or exposed diagnostics as a public health check.
A Laravel application returning HTTP 200 from a health endpoint is reachable, but that does not prove the whole application is usable. Laravel's built-in health route is primarily a lightweight boot check. It is a strong production baseline when reachability, critical dependencies and real user journeys are monitored separately.
What `/up` does and does not prove
Laravel 13 includes a health route, usually at `/up`. The official documentation states that it returns 200 when the application boots without exceptions and 500 when it cannot. The route also dispatches `Illuminate\Foundation\Events\DiagnosingHealth`, allowing targeted additional checks.
- 200 from `/up` means Laravel could process the health request and boot.
- A timeout or connection failure may sit before Laravel, such as DNS, TLS, the web server, network or hosting.
- A green `/up` does not automatically prove that email, an external API, checkout or another business flow works.
Use three levels of monitoring
- Baseline check: request `/up` with a short timeout.
- Critical dependency check: probe only a dependency whose outage makes the application effectively unusable, such as the primary database.
- Functional monitoring: separately check a representative public route, API call or safe synthetic flow.
This separation avoids false confidence and unnecessary fragility. A shallow monitor can remain green while users see errors. An overly deep health endpoint becomes unstable because every external provider or optional integration can turn the overall status red.
A lightweight database probe with `DiagnosingHealth`
If nearly every important request needs the primary database, a small database probe is reasonable. Keep the query cheap, read-only and predictable. A simple `select 1` verifies the connection without reading business data.
<?php
namespace App\Providers;
use Illuminate\Foundation\Events\DiagnosingHealth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
final class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Event::listen(DiagnosingHealth::class, static function (): void {
DB::select('select 1');
});
}
}Do not automatically check every table, external provider or optional feature. Health endpoints are often requested frequently. Heavy queries and network calls increase load, latency and false alarms.
External services usually belong in separate monitoring
A payment provider, CRM, mapping service or mail provider may fail briefly without making the entire website unavailable. Monitor those dependencies separately when they are business-critical. Do not let an optional API decide whether the whole application is healthy.
- Do not run a full checkout from `/up`.
- Do not send a test email on every health request.
- Do not use a heavy reporting query as a database probe.
- Do not expose personal data, secrets, stack traces or provider details in the public health response.
Laravel 13 and JSON health responses
Laravel 13 can return JSON from the built-in health route when the client requests it. For an external monitor, the HTTP status remains more important than the response wording. A simple smoke check can look like this:
curl --fail --silent --show-error \
--max-time 5 \
--header 'Accept: application/json' \
https://example.com/upShared hosting: keep it request-based
On shared hosting, an HTTP health check is useful because it needs no permanent worker, daemon, Redis or Supervisor. An external monitor can periodically request `/up`. Monitoring detects failures, but it does not change hosting runtime constraints and should not make critical flows depend on background processing.
After deployment
Combine the health route with at least one non-destructive smoke check of a representative public page or API route. Also check for new critical exceptions in the logs and know the rollback path before you need it.
Summary
Laravel's built-in `/up` route is a good framework-native baseline for production monitoring. Use `DiagnosingHealth` only for truly critical dependencies, keep the response minimal and monitor functional user journeys separately. The best health check does not try to test everything; it answers one clear question reliably.
Last updated:


