Monitoring and alerting in Laravel
How to monitor a Laravel app in production with Sentry, uptime checks, Grafana synthetics and Pulse, and how to route alerts by severity without fatigue.
On this page
A Laravel app in production needs to tell you when it breaks, slows down or runs out of resources, before a user does. This page covers the layers in the order to add them: error tracking, a health endpoint with an uptime monitor, performance monitoring, and then alerts on top.
The signals to watch are response times, error rates and resource use. Watching infrastructure resources also shows when an environment has more capacity than it needs, which is a chance to cut costs.
Error tracking with Sentry
An error tracker reports every unhandled exception with its stack trace and request context. Sentry is a common choice for Laravel. Install the SDK and add your DSN to .env:
composer require sentry/sentry-laravelSENTRY_DSN=https://[email protected]/456
Unhandled exceptions are reported with no further setup. To report a caught exception yourself:
use function Sentry\captureException;
try {
$this->processPayment($order);
} catch (\Exception $e) {
captureException($e);
}Health endpoint and uptime monitoring
A health endpoint returns 200 when the app and its dependencies work, and 503 when one fails. Health checks in Laravel covers what to check and how to build it.
An external uptime monitor polls that endpoint, for example every 60 seconds, and alerts you when it does not get a 200. Because it runs from outside your infrastructure, it also catches the whole server going down, which internal monitoring cannot report. UptimeRobot and Better Uptime both do this.
Synthetic monitoring with Grafana Cloud
Grafana Cloud Synthetic Monitoring runs checks against your app from several locations around the world, and its free tier includes it. It can:
- Run HTTP checks on an endpoint and alert when it goes down or slows past a threshold.
- Send API requests with custom headers and check status codes, response times and response bodies.
- Warn you before an SSL certificate expires.
- Alert through Slack, email or webhooks.
Shorter check intervals find problems sooner but use more of your quota. A setup for a Laravel app looks like this:
- Create an HTTP check that calls the health endpoint every 30 seconds.
- Add an alert that posts to Slack when the response time goes over 500ms or the check fails.
- Add SSL certificate monitoring for the domain.
The results are Prometheus metrics, so you can chart uptime and response times in a Grafana dashboard next to your infrastructure metrics.
Application performance monitoring
Application performance monitoring (APM) tools profile requests and show slow queries, slow routes and overall response times. Datadog and New Relic both integrate with Laravel. Laravel Pulse is the first-party option:
composer require laravel/pulse
php artisan vendor:publish --provider="Laravel\Pulse\PulseServiceProvider"
php artisan migratePulse gives you a dashboard of slow queries, slow routes, queue throughput and server resource use, without adding instrumentation to your code.
If you collect your own metrics with Prometheus, the promphp/prometheus_client_php library lets the app expose counters:
use Prometheus\CollectorRegistry;
use Prometheus\Storage\InMemory;
$registry = new CollectorRegistry(new InMemory());
$counter = $registry->getOrRegisterCounter('app', 'requests_total', 'Total requests');
$counter->inc();InMemory storage only lasts for one request. Use the Redis or APCu adapter in production so counts add up across requests.
What to alert on
Alerts depend on the monitoring and logging under them. You can only alert on resource use if you measure it, and you can only alert on a specific error if you log it.
From monitoring, alert on:
- Response times above the threshold you accept.
- Error rates rising above your normal baseline.
- CPU, memory or disk close to capacity.
From logs, you can count an event and alert on the count. For example, log every failed payment, then alert when failures in a time window pass a threshold. This covers business flows that your dashboards may not show. Logging in Laravel covers structured log messages that make this kind of count possible.
Routing alerts by severity
Send each alert somewhere that matches how urgent it is:
| Severity | Example | Alert destination |
|---|---|---|
| Critical | Application returns 500 errors | PagerDuty or a phone call |
| High | Error rate spikes above baseline | Slack #alerts channel |
| Medium | Response time exceeds threshold | Slack #monitoring channel |
| Low | Disk space above 80% | Email digest |
Laravel's slack log channel can post critical errors straight to Slack. For anything that needs someone to respond, use an incident tool.
On-call tools
If the app runs around the clock, such as a shop or a 24-hour service, someone needs to be on call. These tools route an alert to the person on call by SMS, email or phone:
- PagerDuty handles on-call schedules and escalation.
- Splunk On-Call, formerly VictorOps, handles on-call and incident response.
Cloud providers have their own alerting too: AWS CloudWatch Alarms, Azure Monitor Alerts and Google Cloud Alerting.
Keep thresholds tuned to your app's normal baseline. Noisy or misleading alerts lose people's trust faster than having no alerts. When an alert fires, a runbook tells the person on call what to do, and a status page tells customers what is happening.