Skip to main content
Nightwatch captures everything by default. Without sampling or filtering, it will collect 100% of requests, jobs, queries, exceptions, and more, giving you complete visibility with zero setup. Sampling lets you reduce the volume of data collected, helping you manage usage in high-throughput or noisy environments. You might choose to sample aggressively in staging, more conservatively in production, or apply targeted sampling to specific routes. Sample rates in Nightwatch are decimal values where 1 captures 100%, 0 captures 0%, and values like 0.25 capture 25% of events.
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1 # Recommended
💡 Tip: We recommend starting with the sample rate of 0.1 or lower on requests to build an understanding of your application’s profile and adjusting the rate based on your observations.

Request and command sampling

You can configure global sampling for both HTTP requests and Artisan commands using environment variables. When a request or command is sampled in, Nightwatch captures the full execution context, including related database queries, queued jobs, exceptions, and outbound HTTP calls.
Why do we only expose global sampling controls for requests and commands? Take a look at the Nightwatch Sampling Philosophy section to learn more.

Exception sampling

By default, Nightwatch captures all exceptions from all requests and commands to ensure that you have the full context of any exception that occurs in your application. For example, if you set the request sample rate to 10% and the exception sample rate to 100% (default), Nightwatch will capture any request that throws an exception, regardless of whether the request would have been sampled otherwise. To ignore exceptions on non-sampled requests, set NIGHTWATCH_EXCEPTION_SAMPLE_RATE=0. This setting ensures that exceptions are captured only from sampled requests.

Exception throttling

Laravel provides additional ways to throttle exception reporting for high traffic applications or when you need to protect against sudden spikes. https://laravel.com/docs/errors#throttling-reported-exceptions

Route-based sampling

The Nightwatch Sample middleware provides individual route or route group sample rates within your Laravel application.
routes/web.php
use Illuminate\Support\Facades\Route;
use Laravel\Nightwatch\Http\Middleware\Sample;

// Applied to a single route
Route::get('/users', [UserController::class, 'index'])
    ->middleware(Sample::rate(0.5));

// Applied to a route group
Route::middleware(Sample::rate(0.5))->group(function () {
    // ...
});

// Always sample a route
Route::get('/users', [UserController::class, 'index'])
    ->middleware(Sample::always());

// Never sample a route
Route::get('/users', [UserController::class, 'index'])
    ->middleware(Sample::never());

Unmatched routes sampling

You can set sample rates for bot traffic by using the Sample middleware with Laravel’s fallback route. We don’t recommend ignoring all unmatched routes. Instead, you should implement a reduced sample rate for bot traffic to help identify and block unwanted requests.
routes/web.php
// Applied to unmatched 404 routes
Route::fallback(fn () => abort(404))
    ->middleware(Sample::rate(0.5));

Package route sampling

Many packages provide options to modify the middleware applied to their routes through configuration. For example, Laravel Nova lets you add middleware to its internal routes in your config/nova.php configuration file.
config/nova.php
/*
|--------------------------------------------------------------------------
| Nova Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will be assigned to every Nova route, giving you the
| chance to add your own middleware to this stack or override any of
| the existing middleware. Or, you can just stick with this stack.
|
*/

'middleware' => [
    \Laravel\Nightwatch\Http\Middleware\Sample::rate(0.5),
    'web',
    \Laravel\Nova\Http\Middleware\HandleInertiaRequests::class,
    'nova:serving',
],

Dynamic sampling

Under the hood, all the sampling options above defer to the low-level Nightwatch::sample method. You can call this method directly for fine-grained control in situations where Nightwatch doesn’t yet provide sampling capabilities.
use Laravel\Nightwatch\Facades\Nightwatch;

Nightwatch::sample(); // Sample 100% of executions.
Nightwatch::sample(rate: 1.0); // Sample 100% of executions.
Nightwatch::sample(rate: 0.5); // Sample 50% of executions.
Nightwatch::sample(rate: 0); // Sample 0% of executions.
Nightwatch::dontSample(); // Sample 0% of executions.

Dynamic sampling examples

When setting dynamic sample rates, it’s important to note that you should always call the Nightwatch::sample method in event listeners, middlewares, or other code that is executed after the application has booted. If you execute the Nightwatch::sample method directly in your application’s service provider, the dynamic sample rate will be overridden by the global sample rate (via environment variables) or route-based sampling.

Sampling the health check endpoint

Laravel includes a built-in health check route at /up that can be used to monitor the status of your application. You can exclude this route from sampling by adding the following event listener:
AppServiceProvider.php
use Illuminate\Foundation\Events\DiagnosingHealth;
use Laravel\Nightwatch\Facades\Nightwatch;

public function boot(): void
{
    Event::listen(function (DiagnosingHealth $event) {
        Nightwatch::dontSample();
    });
}

Sampling based on the user’s role

You can create custom middleware to sample requests based on user attributes like their role.
app/Http/Middleware/SampleAdminRequests.php
use Closure;
use Illuminate\Http\Request;
use Laravel\Nightwatch\Facades\Nightwatch;
use Symfony\Component\HttpFoundation\Response;

class SampleAdminRequests
{
    public function handle(Request $request, Closure $next): Response
    {
        if (! $user = $request->user()) {
            return $next($request);
        }

        if ($user->isAdmin()) {
            Nightwatch::sample();

            return $next($request);
        }

        return $next($request);
    }
}
routes/web.php
use App\Http\Middleware\SampleAdminRequests;

Route::middleware(SampleAdminRequests::class)->group(function () {
    // ...
});

Sampling specific jobs

Nightwatch currently doesn’t offer or recommend setting a sample rate for a specific job. However, you could achieve this by adding the following to the start of your job:
use Laravel\Nightwatch\Facades\Nightwatch;

class MyJob
{
    public function handle()
    {
        Nightwatch::sample(rate: 0.5); // Sample 50%

        // ...
    }
}

Sampling specific commands

AppServiceProvider.php
use Illuminate\Console\Events\CommandStarting;
use Illuminate\Support\Facades\Event;
use Laravel\Nightwatch\Facades\Nightwatch;

public function boot(): void
{
    Event::listen(function (CommandStarting $event) {
        if (in_array($event->command, [
            'schedule:finish',
            // ...
        ])) {
            Nightwatch::dontSample();
        }
    });
}

Event filtering

In addition to sampling, you can filter out specific events entirely. This allows you to focus your event allocation on the events that matter most to your application. When an event is filtered, it is completely excluded from collection, no data will be sent to Nightwatch, and the event will not appear in your stream, traces, or usage metrics.

Filtering with a callback

Nightwatch provides the following methods that allow you to filter events using a callback function:
  • Nightwatch::rejectCacheEvents()
  • Nightwatch::rejectMail()
  • Nightwatch::rejectNotifications()
  • Nightwatch::rejectOutgoingRequests()
  • Nightwatch::rejectQueries()
  • Nightwatch::rejectQueuedJobs()
For example, you may wish to filter out cache events based on the cache key:
AppServiceProvider.php
use Laravel\Nightwatch\Facades\Nightwatch;
use Laravel\Nightwatch\Records\CacheEvent;

public function boot(): void
{
    Nightwatch::rejectCacheEvents(function (CacheEvent $cacheEvent) {
        return in_array($cacheEvent->key, [
            'illuminate:foundation:down',
            'illuminate:queue:restart',
            'illuminate:schedule:interrupt',
        ]);
    });
}
Filtering events can help to conserve your event quota, but may also hide issues in your application. In the above example, if your cache service was responding slowly, your queue throughput would be reduced, but you wouldn’t have visibility as to why.

Filtering underlying query events

You may also wish to filter events that are already represented by other event types. For example, if you are using the database queue or cache driver, you may wish to exclude the underlying queries:
// AppServiceProvider.php

use Laravel\Nightwatch\Facades\Nightwatch;
use Laravel\Nightwatch\Records\Query;

public function boot(): void
{
    Nightwatch::rejectQueries(function (Query $query) {
        return str_contains($query->sql, 'into "jobs"');
    });

    Nightwatch::rejectQueries(function (Query $query) {
        return str_contains($query->sql, 'from "cache"')
            || str_contains($query->sql, 'into "cache"');
    });
}

Filtering all events of a specific type

Set any of the following environment variables in your .env file to true to disable collection of that event type:
  • NIGHTWATCH_IGNORE_CACHE_EVENTS — Exclude all cache events
  • NIGHTWATCH_IGNORE_MAIL — Exclude all mail events
  • NIGHTWATCH_IGNORE_NOTIFICATIONS — Exclude all notification events
  • NIGHTWATCH_IGNORE_OUTGOING_REQUESTS — Exclude all outgoing HTTP requests
  • NIGHTWATCH_IGNORE_QUERIES — Exclude all database queries

Ignoring cache events

For applications that make heavy use of caching, cache events can consume a significant portion of your quota. By filtering them out, you can preserve more of your allocation for higher-value signals like queries, jobs, and exceptions. To ignore cache events, add the following to your .env file:
NIGHTWATCH_IGNORE_CACHE_EVENTS=true

Nightwatch sampling philosophy

Nightwatch collects rich, contextually linked data related to the events that happen in Laravel applications. Fundamentally, any event which occurs in a Laravel application can be traced back to one of three entry points; a request, command, or scheduled task. When Nightwatch samples the data generated by your application, it aims to preserve the relationship between these entry points and all of the events they trigger (e.g. jobs, exceptions, queries, etc). As a result, reducing the sample rate for the entry point which triggers these other events, will also reduce the number of jobs, queries, cache events, etc. which are collected. This ensures that despite reducing the overall volume, for any captured event you are still able to look at a full picture of every other related event which occurred, ensuring that you always have the most complete understanding possible of how your application is behaving. All applications are different, however, and for some this approach won’t give the best signal to noise ratio. This is why we allow more fine-grained control of sampling and filtering of events, so that you can tune Nightwatch to capture the data which best suits your specific needs. The dynamic sampling and filtering methods described above allow flexible control of what is captured and at what rate, to help you achieve the best result. For example, while global sampling of jobs is not configurable using an environment variable (for the reasons outlined above), it is possible to de-couple the sampling of jobs from the sample rates of their parent entry points:
AppServiceProvider.php
use Illuminate\Support\Facades\Queue;
use Laravel\Nightwatch\Facades\Nightwatch;

public function boot(): void
{
    Queue::before(fn () => Nightwatch::sample(rate: 0.5));
}
It should noted, however, that this may necessarily lead to the request, command or scheduled task that triggered a captured job not being captured, or a job triggered by a captured request, command, or scheduled task not being captured, which could lead to a less complete view of how your application is performing.
I