Documentation
HoneData and retention
Updated
Hone keeps all of its data in your deployment's PostgreSQL database. Nothing is forwarded to a hosted monitoring service. This page explains what happens to a record between your app and an MCP answer.
From your app to the database
- Nightwatch captures records in your app. The Hone client batches them and posts them to
/ingestwith the app's ingest credential. - Hone checks the credential and the batch's format, answers
202 Accepted, and queues the batch. It does no storage work while your app waits. - A queue worker writes each record to the
raw_eventstable, tagged with the app id from the credential and the deploy id from the batch. - Every hour,
hone:maintainrolls recent raw events into daily aggregates and per-minute activity buckets, then deletes data that is past retention.
Hone stores the whole Nightwatch record as JSON and reads a small, type-specific set of fields from it: the record type, its timestamp, the fields that make up its normalized key (route, SQL shape, job name, exception class and location, host, log level, user id, cache store and type), and the numeric fields it aggregates.
What is kept, and for how long
| Data | Default retention | Used by |
|---|---|---|
| Raw events | 72 hours | The discovery tools, and as the source for every rollup. |
| Daily aggregates | 90 days | The slow, analysis, and volume tools. |
| Per-minute activity buckets | 400 days | The activity and traffic tools. |
Each window can be changed; see Configuration. Disk use is driven mainly by raw events: the number of records your apps send per day multiplied by the raw retention window.
Rollups and late events
Each hourly rollup re-reads whole UTC days, starting 24 hours back from now and running through today. An event that arrives up to 24 hours after it happened is still counted. An event whose timestamp is older than that is stored as a raw event but never aggregated.
If aggregates have a gap, for example after an outage that stopped maintenance, rebuild a date range from the raw events that are still retained:
php artisan hone:backfill 2026-10-01 2026-10-03
It rebuilds one UTC day at a time and resumes from its own checkpoint if interrupted. Add --restart to ignore the checkpoint and start the range again. Raw events older than the raw retention window are gone, so a backfill can only rebuild days that still have raw data.
To run any of these commands on your Hone environment, use Laravel Cloud's command runner. These commands print no secrets.
Comparing deploys
Every record carries the deploy id its app sent, taken from NIGHTWATCH_DEPLOY in that app. Hone uses it to filter the slow tools by deploy, to list recent deploys, and in regression_check to compare one metric for one key across recent deploys. If an app does not set NIGHTWATCH_DEPLOY, its records have no deploy and cannot be compared.
Maintenance health
The scheduler also runs hone:health every hour. It checks three things:
| Check | Alarms when |
|---|---|
maintenance |
hone:maintain has not succeeded in the last 150 minutes. |
retention |
The oldest raw event is older than the raw retention window plus 24 hours, which usually means pruning has stopped. |
aggregate_freshness |
The newest daily aggregate is more than 6 hours old. |
A check reports idle rather than ok when no event has arrived in the last hour. That is a quiet deployment, not a broken one.
Nothing watches this check for you. hone:health exits non-zero when a check alarms, but no alert or notification is sent; the result only appears in the scheduler's logs in Laravel Cloud. To see it on demand, run php artisan hone:health --json on the environment, or ask your agent to call ingest-freshness-tool, which includes the same maintenance health.
Privacy
Redaction happens in each app's Nightwatch configuration, before anything is sent to Hone. Hone adds no redaction of its own, and the client does not sample. Query bindings are not part of a query's normalized key.
MCP tools answer with summaries keyed by route, SQL shape, exception class and location, log level, user id and cache store, not with raw request bodies or arbitrary event payloads. Those summaries still leave your infrastructure if your agent runs elsewhere.