laravel/nightwatch
Official Laravel Nightwatch package gathers performance metrics inside your Laravel application and securely transmits them to the Nightwatch hosted monitoring platform, delivering deep, Laravel-optimized insights into your app's performance for unparalleled visibility.
Install and authenticate
composer require laravel/nightwatch
php artisan vendor:publish --tag=nightwatch-config # verify tag in docs
Set the project token/secret in .env (the exact variable names live in the published config and the official docs — the README itself is deliberately thin):
NIGHTWATCH_TOKEN=...
NIGHTWATCH_ENVIRONMENT=production
Then run the app and confirm data appears in the Nightwatch dashboard. There is no application code to write for baseline coverage: the service provider registers framework hooks for requests, queries, jobs, commands, scheduled tasks, outgoing HTTP, cache, views, mail, and exceptions.
Where to look first
config/nightwatch.php — this is the real surface area. Sampling, ignored paths/commands, capture toggles, and connection settings all live here.https://nightwatch.laravel.com/docs — the authoritative documentation. Treat the GitHub repo as the client implementation, not the manual; the README is an introduction only.CHANGELOG/changelog/*.md — this package ships several releases per month and behaviour changes land in patch/minor releases. Skim it before upgrading.agents/skills, including a "configure-nightwatch" skill) that will walk an AI assistant through correct configuration.First use case
Pick one real production symptom — a slow endpoint, a flaky queued job, or an intermittent exception — and trace it end-to-end in the dashboard before touching configuration. Baseline instrumentation is usually enough to answer "which query, which job attempt, which deploy". Resist the urge to start by filtering things out; you need a noisy baseline to know what to silence.
Treat it as zero-touch first, configure second. The default flow is: deploy → observe → then narrow. Only add Nightwatch::ignore(...) and capture toggles once you can see which traffic is diluting your signal.
Deploy tracking as a CI step. The nightwatch:deploy command exists specifically so that performance/error regressions can be attributed to a release:
php artisan nightwatch:deploy
Wire it into your deploy pipeline as the last step. NIGHTWATCH_DEPLOY is honoured, with a VAPOR_COMMIT_HASH fallback on Vapor, so most teams can just let the commit hash flow through and get deploy markers for free.
Scoped ignoring. Nightwatch::ignore() is the day-to-day tool for noise and privacy:
Nightwatch::ignore(fn () => request()->is('up', 'healthz', 'horizon/*'));
Use the same mechanism for webhook endpoints, admin-only routes, and noisy artisan commands. Note that some noisy vendor commands (octane:status) and framework-internal keys (Livewire checksum failures) are already ignored by default — check before adding redundant rules.
Forcing a flush. Events are buffered and handed to a local agent process before transmission. In long-running contexts (queue workers, Octane, custom daemons) the digest timer may not fire when you expect, so Nightwatch::digest() lets you proactively push the current buffer. Call it at natural boundaries — end of a batch job, after a critical operation — rather than in a loop.
Volume control per app/environment. Since v1.29 you can cap how many events are ingested per app/env from an event listener, using IngestingEvent::eventCount (added in v1.30) to make decisions based on the incoming count. This is the correct extension point for cost/quota control:
// Listener on the ingesting event — bail out of high-volume,
// low-value traffic before it costs you quota.
if ($event->eventCount() > $limit) {
return false; // shape depends on the listener contract — confirm in docs
}
Sampling deliberately. Sampling is the primary cost lever for high-traffic apps. Two things shaped by recent releases worth knowing: unhandled exceptions are now ingested immediately while sampling (so you don't lose the errors you actually care about), and Nightwatch::ignore no longer overrides sampling when unset. That combination means you can sample aggressively in production and still keep a faithful error stream.
Filter through the framework, not around it. Manual exception reporting respects ExceptionHandler::dontReport, and unhandled view exceptions are deeply unwrapped so you see the root cause rather than a blade wrapper. This means "what Laravel suppresses, Nightwatch suppresses" — a good default, but see the gotcha below.
Queue and job fidelity. Job attempts, exceptions, and enum-backed queue names (via the queue attribute) are tracked. For workers, ensure the agent is reachable from the worker process, not just the web tier, and flush on idle so long-lived workers don't accumulate an unbounded buffer.
Distributed tracing. Cloud trace IDs are used when present, and direct connection types are supported — useful when your app sits behind a load balancer or gateway that already emits trace headers and you want one continuous trace across services rather than starting fresh at the PHP boundary.
Buffered data can be lost. In-process buffering plus an agent hop means a hard PHP crash (segfault, OOM kill, exit) may drop whatever hadn't been digested. For genuinely critical paths, Nightwatch::digest() right after the event is the mitigation — not a guarantee.
dontReport is respected — including when you don't want it to be. If you've silenced an exception in bootstrap/app.php or a handler to reduce log noise, Nightwatch won't see it either. Teams frequently rediscover this when an "invisible" error resurfaces in production. Decide suppression once, deliberately, knowing it applies to both surfaces.
Config caching order matters. If you publish the config and then run php artisan config:cache in a deploy script that executes before a container builds with the new config, you'll ship stale settings. Publish, cache, then verify with php artisan about or config('nightwatch...') in a tinker session.
Upgrade cadence is fast — 30+ tagged releases across the changelogs provided. Constrain with a caret on the minor ("laravel/nightwatch": "^1.30") rather than floating, read the changelog for behavioural changes (trace handling location, naming standardisation, sampling interactions have all shifted), and exercise the upgrade in staging before it reaches production monitoring. Breaking your observability during a deploy is the worst time to lose it.
Watching volume as cost. Event count scales with traffic: every request, query, cache hit, and job can become a record. The per-app/env ingestion limit via an event listener is the sanctioned release valve. Set it up before you have a spike, not during one.
PII in payloads. Request data, headers, and query bindings can be captured. Before enabling in production, decide what must never leave the box and express that through ignore rules and capture toggles. This is a configuration review task, not a code review task — put it on the same checklist as your deploy step.
Don't ship dev noise. Local development generates metrics that pollute the same project unless you separate environments via env vars. Use a distinct NIGHTWATCH_ENVIRONMENT per environment and disable or heavily sample locally.
Debugging "nothing is arriving." Work outward: (1) is the token/env var actually set in the running process (not just in .env)? (2) has the config been cached? (3) can the host reach the agent/ingest endpoint over the configured connection type? (4) do you see a digest happening at all? Only then suspect the filtering configuration — most ingestion failures are credential, config-cache, or network problems, not instrumentation bugs.
Extension points worth knowing. Ignore callbacks, configuration toggles, ingesting-event listeners for limits/lifecycle, manual reporting for handled-but-important errors, and the agent itself (documented separately in agent/) for connection/runtime specifics. The package is intentionally thin in user-facing API — nearly all day-to-day leverage comes from configuration, not from writing against its classes.
How can I help you explore Laravel packages today?