Collectors
A collector writes one file. Locally that file is one instance. Hosted, write keys stamp many instances into the same file. Relay is optional. The file is DuckDB.
Local is one collector
One process, one file, one instance (default local). Apps POST JSON. The collector is the only writer.
Shared is one collector, many instances
One file. Each row gets instance from the write key. The JSON body may send instance; the collector ignores it. Unknown or missing key on a mapped collector is 401.
Views keep slices apart
Each instance name is a schema. A product view is SELECT * FROM main.<table> WHERE instance = '<name>'. Reserved root is SELECT * from main (every product). Do not name a product root. The panel emits USE <instance>.collector. Authored SQL is FROM events.
Laptop can push
Insert triggers write relay_outbox (path, body, message_id). The loop POSTs each pending row to {upstream}{path} with the upstream write key and marks it sent.
Paths come from the domain table (/v1/batch, /v1/metrics, /v1/traces, /v1/logs). The loop does not inspect which table produced the row. Opt-out skips the loop. Local INSERT still runs. Empty upstream URL posts nothing. Hosted ingest has no further hop.
Pages cover the git repo the panel serves. Docs lists collector HTTP.