bref/laravel-health-check
Laravel health checks that confirm your app is running correctly when deployed with Bref on AWS Lambda. Meant to work with bref.cloud, it provides quick, reliable status checks so you can catch problems early and keep your serverless application healthy in production.
1. Install the package
composer require bref/laravel-health-check
Because this package has almost no public adoption (1 star, 0 dependents), treat the first install as an evaluation: read src/ and the service provider before you wire it into production alerting. The package surface is small enough to audit in a few minutes.
2. Publish and inspect the config (if the package provides one)
php artisan vendor:publish --tag=health-check-config
Look at three things in the config: which checks are enabled by default, the route/URI that gets registered, and whether any checks assume Lambda-specific services (S3, DynamoDB, CloudWatch) that you may not have provisioned locally. If no config is published, check the service provider for hard-coded route registration — that tells you whether you need to gate it by environment yourself.
3. Look first at the route and the check list
Open routes/ or the service provider in vendor/bref/laravel-health-check/ and confirm:
/health or /_health) and HTTP method.4. First use case: a load-balancer / uptime probe
Run php artisan serve (or bref local) and hit the endpoint:
curl -i http://localhost:8000/health
You want a 200 with a small JSON body when everything is healthy, and a non-2xx (typically 500 or 503) when a dependency is down. That contract is what Bref Cloud, an ALB target group, or an external uptime monitor consumes. Wire that URL into Bref Cloud's health check setting or your ALB target group's health check path before doing anything fancier.
5. First "real" use case: CI/CD smoke test
After serverless deploy (or bref deploy), call the deployed URL as a post-deploy step:
curl -fsS https://your-app.example.com/health || echo "deploy unhealthy"
If the endpoint fails here, you catch misconfigured env vars (DB host, S3 bucket, cache) before traffic is shifted.
Pattern 1 — Environment-scoped route registration
Health endpoints leak infrastructure detail (DB reachability, queue depth). Register the route only where you need it, or protect it:
// In a service provider, or by excluding the package route
if (app()->environment('production', 'staging')) {
// expose publicly for the ALB / Bref Cloud probe
}
If the package registers the route unconditionally, wrap it: disable it in local/testing via config, or add middleware that requires a shared secret header for the richer checks while leaving a lightweight /health open for the ALB.
Pattern 2 — Split liveness from readiness
The single biggest practical distinction on Lambda:
If the package exposes a single endpoint, either accept the composite check and set a generous ALB health check timeout/interval, or add your own trivial route alongside it:
Route::get('/live', fn () => response('ok', 200));
Use /live for the ALB target group, and /health for richer monitoring/alerting.
Pattern 3 — Feed it into Bref Cloud
This is the intended integration. Point Bref Cloud's health check at the package's route so its dashboard/monitoring reflects actual dependency status, not just TCP reachability. That's the whole reason the package exists — it converts "the Lambda responds" into "the Lambda and its dependencies are healthy" inside the Bref Cloud UI.
Pattern 4 — Post-deploy gate in CI
- run: composer install --no-dev
- run: serverless deploy
- run: |
for i in 1 2 3 4 5; do
curl -fsS "$APP_URL/health" && exit 0
sleep 10
done
exit 1
Retry because the first invocation after deploy is a cold start and may be slower than your probe timeout.
Pattern 5 — Reuse existing health checks
If you already use spatie/laravel-health, check whether this package wraps it or duplicates it. Duplicating health logic across two packages is a maintenance trap — pick one source of truth and delete the other's route.
Pattern 6 — Custom checks for Lambda-specific gotchas
The checks that actually matter on Lambda are the ones a vanilla Laravel health check misses:
/tmp (the only writable path)?FILESYSTEM_DISK=s3 respond?Add these as custom checks if the package supports extension, otherwise call them from a dedicated /health/deep route.
Cold starts inflate health check latency. Every check that touches the network (DB, S3, cache) runs inside the Lambda request. A health endpoint doing five network calls can take 1–2s on a cold start. Set ALB health check timeouts accordingly (≥5s) and keep intervals loose (30s), or you'll get "unhealthy" flapping.
A public health endpoint on a Lambda has a cost. Every probe is an invocation. Frequent ALB probes from multiple targets add up, though it's usually negligible. If your Lambda is memory-heavy (512MB+), a 30s probe interval is still cheap — just be aware it's not free.
Don't expose secrets in the response. Check whether the endpoint returns exception messages or connection strings on failure. In production you want {"status":"unhealthy"} with details going to logs, not to the client. Wrap the route in middleware or override the response if the package is verbose.
Verify the package's checks actually run on Lambda, not locally. A check that passes under php artisan serve proves nothing about the Lambda runtime — different filesystem, different network egress, different env var source. Always validate against a deployed environment.
Zero dependents means zero community debugging. With 1 star and no dependents, when this breaks you are the first person to hit it. Pin the version in composer.json ("bref/laravel-health-check": "1.*") and read the release notes before bumping. The last release date (2026-02-26) suggests it is maintained, but the adoption signal is the risk, not the maintenance signal.
Check for route collisions. If your app already defines /health (or your framework's health route), the package's registration may silently shadow it or throw a duplicate-route error depending on registration order. List routes to confirm:
php artisan route:list --path=health
Middleware and auth. If your app uses a global auth middleware on the web group and the package registers under web, the probe will get a 302 to login and everything looks "unhealthy." Register the route outside the web group (the api group or no group) — most health check packages do this correctly, but verify.
Extension point: custom checks. If the package follows the common pattern of a check registry/resolver, you can append your own checks (S3 connectivity, /tmp writability, queue reachability) without forking. Look for a HealthCheck contract or an extend/register method in the service provider. That's the difference between "another route" and "the one place your team looks when things break."
Debugging a failing check. Reproduce the failing check locally by exporting the same environment variables Lambda has:
AWS_LAMBDA_FUNCTION_NAME=test php artisan serve
Half the time a check fails on Lambda it's because a package branches on the Lambda environment name and behaves differently than in local dev.
Combine with Bref's own diagnostics. Bref Cloud gives you invocation logs, errors, and cold-start metrics alongside this health check. Use the health check for is my app healthy? and Bref Cloud's logs/APM for why isn't it? — don't try to make the health endpoint the debugging tool.
Fallback plan. If the package turns out to be too thin for your needs, a health route is ~20 lines and can be composed from spatie/laravel-health, an S3 exists() call, and a DB select 1. Keep that exit ramp in mind before you build alerting around an unproven dependency.
How can I help you explore Laravel packages today?