> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usenightowl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Every environment variable and artisan command the NightOwl agent exposes.

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.

<Warning>
  **Managed Postgres (Supabase, Neon, RDS):** point the agent at the **direct or session connection on port `5432`**, not a transaction-mode pooler (Supabase's `6543`). The agent holds a long-lived drain connection and relies on session-level settings (`synchronous_commit`) that transaction-mode poolers don't preserve, so a session-scoped connection is the right fit. Set `NIGHTOWL_DB_SSLMODE=require`, and use the provider's existing database (`postgres` on Supabase, `neondb` on Neon) — NightOwl creates the tables, not the database.
</Warning>

### 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 environments are separated only by that column; the `nightowl_*` tables themselves are shared. (Unrelated to table partitioning — see [Data management](/dashboard/data-management#what-pruning-does-to-your-disk) for that.)

`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`.

<Note>
  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.
</Note>

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/listens** on (use `0.0.0.0` to accept payloads from other hosts). This is the listener address — not where your app transmits.                                                                                                                                                                                                                                                                                                                                         |
| `NIGHTOWL_AGENT_PORT`     | `2407`           | TCP port the agent listens on                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `NIGHTOWL_INGEST_URI`     | `127.0.0.1:2407` | Where your **app transmits** telemetry — the agent's `host:port` as seen from your app. Defaults to the loopback listener (co-located agent). Set it to the agent's private address when the app and agent run on different hosts — a [dedicated monitoring server](/agent/remote-agent) or a serverless host like [Laravel Vapor](/agent/vapor). A bare host with no port falls back to `NIGHTOWL_AGENT_PORT`. Mirrors nightwatch's `NIGHTWATCH_INGEST_URI`.                                     |
| `NIGHTOWL_INGEST_TIMEOUT` | `0.5`            | Connect + write timeout (seconds) for transmitting to the agent. The default suits a loopback agent; raise it when the agent is a network hop away (`1.0` on a private network, `3` across the public internet) — otherwise transient latency surfaces as intermittent `Connection timed out` exceptions and dropped batches.                                                                                                                                                                     |
| `NIGHTOWL_AGENT_DRIVER`   | `async`          | Server driver (`async` or `sync`). `async` needs `pcntl` + `posix`                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `NIGHTOWL_ENVIRONMENT`    | `APP_ENV`        | Override `APP_ENV` for the `environment` column stamped on every row                                                                                                                                                                                                                                                                                                                                                                                                                              |

The async server enables `SO_REUSEPORT` automatically on Linux, so multiple agents can bind the same port without extra configuration — see [Running multiple instances](/agent/multiple-instances).

## 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](/agent/running-alongside-nightwatch), 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](/performance/throughput) 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`:

```env theme={null}
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](/agent/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`:

```env theme={null}
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_ROLLUP_RETENTION_DAYS`        | `90`    | Retention for the minute-granular rollup tables (pruned by `nightowl:prune`)        |
| `NIGHTOWL_HOURLY_ROLLUP_RETENTION_DAYS` | `366`   | Retention for the hourly rollup tier (60× sparser than minute)                      |
| `NIGHTOWL_DAILY_ROLLUP_RETENTION_DAYS`  | `1100`  | Retention for the daily rollup tier (1440× sparser than minute)                     |
| `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](/dashboard/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](/agent/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 (drops whole expired day-partitions instantly on partitioned tables)                                                                               |
| `nightowl:partition`          | Convert existing raw telemetry tables to native daily partitioning — no data copying (except `nightowl_logs`, whose legacy text date column is rewritten); new installs are partitioned automatically |
| `nightowl:drop-v1-histograms` | Post-transition cleanup: drop the legacy histogram columns once every rollup row carries a DDSketch — refuses to run before that, requires an agent restart after                                     |
| `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`.
