All configuration lives in config/nightowl.php after running php artisan nightowl:install. Most values are driven by environment variables — the defaults are tuned for a single-instance deployment doing up to a few thousand requests per second.
Database connection
| Variable | Default | Description |
|---|
NIGHTOWL_DB_HOST | 127.0.0.1 | PostgreSQL host |
NIGHTOWL_DB_PORT | 5432 | PostgreSQL port |
NIGHTOWL_DB_DATABASE | nightowl | PostgreSQL database name |
NIGHTOWL_DB_USERNAME | nightowl | PostgreSQL username |
NIGHTOWL_DB_PASSWORD | nightowl | PostgreSQL password |
NIGHTOWL_DB_SSLMODE | prefer | PostgreSQL SSL mode (disable, allow, prefer, require, verify-ca, verify-full) |
Use the same credentials you entered when creating the app in the dashboard — the hosted UI uses them to read the telemetry your agent wrote.
Sharing one database across environments
NightOwl stamps an environment column (your APP_ENV) on every row, so you can point several app environments (local, staging, production) at one NightOwl database and filter them apart in the dashboard. The data is partitioned by environment; the nightowl_* tables themselves are shared.
nightowl:install and nightowl:migrate track their migration history inside the NightOwl database, so they’re idempotent across every environment that shares it. Run php artisan nightowl:migrate as part of each deploy:
- the first environment to deploy creates the tables;
- the rest are no-ops;
- when a package upgrade adds a migration, it applies on whichever environment deploys first.
No “owner” environment, no flags. If a database already has the nightowl_* tables but no NightOwl migration history (for example it was created by an older version, or by your app’s php artisan migrate), the command adopts the existing schema as a baseline instead of trying to recreate it — so you never hit relation "nightowl_requests" already exists.
By default NightOwl’s migrations are not bundled into your app’s php artisan migrate. Manage the schema with nightowl:migrate (or nightowl:install). See NIGHTOWL_RUN_MIGRATIONS below if you want the legacy ride-along behavior.
If a package upgrade adds a migration and you forget to run nightowl:migrate, php artisan nightowl:agent warns at startup that the schema is behind (and keeps running) rather than failing silently mid-drain. So wiring nightowl:migrate into your deploy is the way to keep the schema current.
Agent runtime
| Variable | Default | Description |
|---|
NIGHTOWL_ENABLED | true | Master switch. Set false to make the package inert — no telemetry is collected or transmitted, and the migrations are not registered. Most commonly flipped off in the testing environment so your test suite doesn’t pay the ingest overhead or require the nightowl database. nightowl:install still runs its migrations regardless. |
NIGHTOWL_RUN_MIGRATIONS | false | Legacy ride-along. When true, NightOwl’s migrations also run as part of your app’s php artisan migrate (history tracked in your primary database). Off by default because the schema is managed by nightowl:migrate / nightowl:install, which track history in the NightOwl database. Don’t combine the two — they record history in different places and would both try to create the tables. Only enable for a single-database setup where you’d rather not run nightowl:migrate. |
NIGHTOWL_AGENT_HOST | 127.0.0.1 | TCP host the agent binds to (use 0.0.0.0 or an LB VIP for multi-host) |
NIGHTOWL_AGENT_PORT | 2407 | TCP port the agent listens on |
NIGHTOWL_AGENT_DRIVER | async | Server driver (async or sync). async needs pcntl + posix |
NIGHTOWL_SO_REUSEPORT | false | Allow multiple agents to bind the same port (Linux only) |
NIGHTOWL_ENVIRONMENT | APP_ENV | Override APP_ENV for the environment column stamped on every row |
See Running multiple instances for SO_REUSEPORT.
Authentication
| Variable | Description |
|---|
NIGHTOWL_TOKEN | Agent token copied from the NightOwl dashboard (Settings → Agent token). The agent verifies inbound payloads against it and uses it as a Bearer credential when reporting health to the NightOwl platform. For a standalone install this is the only token you need. |
NIGHTOWL_APP_ID | Connected-app ID, copied from the NightOwl dashboard (Settings → Agent token, alongside NIGHTOWL_TOKEN). Required for alert emails and webhooks to include a direct-link view_url pointing at the issue. Without it, links fall back to the generic dashboard root. |
NIGHTWATCH_TOKEN | Only needed in parallel mode, when NightOwl runs alongside Nightwatch’s hosted agent. This is your real Nightwatch token — the Nightwatch SDK uses it to authenticate against Laravel Cloud’s hosted ingest. Don’t set it for a standard install. |
For a standalone install, set NIGHTOWL_TOKEN only. For parallel mode, set both: NIGHTOWL_TOKEN is what the NightOwl agent verifies against, NIGHTWATCH_TOKEN is your Nightwatch token used by the Nightwatch SDK to reach Laravel Cloud’s hosted ingest in parallel.
Drain pipeline
| Variable | Default | Description |
|---|
NIGHTOWL_DRAIN_WORKERS | 1 | Parallel drain worker processes (forked, atomic SQLite row claiming) |
NIGHTOWL_DRAIN_BATCH_SIZE | 5000 | Rows per PostgreSQL COPY batch |
NIGHTOWL_DRAIN_INTERVAL_MS | 100 | Drain loop sleep interval when the buffer is idle |
NIGHTOWL_MAX_PENDING_ROWS | 100000 | Reject new payloads once the buffer hits this depth |
NIGHTOWL_MAX_BUFFER_MEMORY | 268435456 | RSS ceiling (bytes) before back-pressure kicks in (default 256 MB) |
Issue lifecycle
| Variable | Default | Description |
|---|
NIGHTOWL_REOPEN_COOLDOWN_HOURS | 0 | Hours of silence required before a resolved issue auto-reopens on recurrence. 0 = always reopen on first new occurrence (Sentry-style behavior). Set higher to suppress flapping issues — e.g. 24 only reopens if the issue has been resolved for at least a day. ignored issues are never auto-reopened regardless of this setting. |
See throughput tuning for how to size these.
Sampling
Sampling is handled upstream by laravel/nightwatch before the payload reaches the agent. Configure it in your customer app’s .env:
NIGHTWATCH_REQUEST_SAMPLE_RATE=0.1 # Keep ~10% of HTTP requests (1.0 = keep all)
NIGHTWATCH_COMMAND_SAMPLE_RATE=1.0 # Keep all artisan commands
NIGHTWATCH_EXCEPTION_SAMPLE_RATE=1.0 # Keep all exceptions
NIGHTWATCH_SCHEDULED_TASK_SAMPLE_RATE=1.0 # Keep all scheduled tasks
The decision is made before transport, so the agent only sees and stores what Nightwatch decided to ship — no double-sampling.
See Filtering and context for the full recipe.
Redaction
PII redaction is handled upstream by laravel/nightwatch before the payload reaches the agent. Configure it in your customer app’s .env:
NIGHTWATCH_REDACT_HEADERS=Authorization,Cookie,Proxy-Authorization,X-XSRF-TOKEN
NIGHTWATCH_REDACT_PAYLOAD_FIELDS=_token,password,password_confirmation
Both lists are applied inside the customer’s PHP process before the record leaves the host, so the agent’s TCP buffer and PostgreSQL drain never see the un-redacted values.
Retention and caching
| Variable | Default | Description |
|---|
NIGHTOWL_RETENTION_DAYS | 14 | Default for nightowl:prune --days=? — nothing is deleted until the command is run |
NIGHTOWL_THRESHOLD_CACHE_TTL | 86400 | Seconds to cache performance thresholds (restart to pick up changes immediately) |
Full retention and pruning strategy lives in Data management.
Parallel mode
| Variable | Default | Description |
|---|
NIGHTOWL_PARALLEL_WITH_NIGHTWATCH | false | Fan telemetry out to both Nightwatch and NightOwl simultaneously |
See Running alongside Nightwatch.
Artisan commands
| Command | Description |
|---|
nightowl:agent | Start the monitoring agent |
nightowl:install | Publish config, create/update the schema, verify fork safety |
nightowl:migrate | Create/update the NightOwl schema (idempotent — run on each deploy) |
nightowl:prune | Delete monitoring data older than retention period |
nightowl:clear | Truncate all monitoring tables |
nightowl:check-thresholds | Poll and dispatch threshold-breach notifications |
The agent command accepts --driver=async|sync. async is the default and required for multi-worker drain; sync is a single-process fallback for hosts without pcntl/posix.