Every served store-host request (page, asset, code, form, content, variant,
cart, checkout — never hook ingress, /healthz or the canonical ops) is
recorded by StatsReporter (src/stats_reporter.ts) and batch-posted to
that env's POST {apiBase}/system/stats/ingest on the env master token, so
tenant traffic joins the backend's log→BigQuery stats pipe and no Google
credential ever lands on the fleet (plan: .dev/plans/store-statistics.md).
- Never blocks serving: bounded queue (default 2000; overflow drops the
OLDEST and reports a
droppedcount in the next flush), flush at 15 s / 500 events / 256 KB — whichever first — fire-and-forget with ONE retry; a batch that still fails is counted dropped, never requeued. - Privacy at the source: the raw IP/UA/referer never leave the recorder.
Events carry a
bot/humanlabel, the referer HOST, and a visitor hash salted per UTC day from the env's master token (deterministic across machines, unlinkable across days). Asset/code hits skip the hash. - Views are browser-confirmed: while an env records traffic its engine
runs with
statsBeacon: true, so every served page carries the inline render beacon (POST /_drop/v?p=…&r=…, seedrop-core-serverstats_beacon.ts). The recorder files that call as aviewevent with the page's path and its owndocument.referrer(beaconFacts); the analytics count views/visitors from those, and every page hit no beacon confirmed is the Bots metric. A request withoutaccept-languageis labelledbot,HEAD/OPTIONSare not recorded. - Configure with
TenantServerOptions.stats(falsedisables; an object tunesflushMs/maxEvents/maxBytes/queueMax) or theTENANT_STATS/TENANT_STATS_FLUSH_MSenv vars.
Deployment (Fly.io: wildcard cert + DNS, always-on machine) is the repo
runbook server-tenant/fly-setup.md; the plan lives in
server-tenant/tenant-server.md. The rootless Linux release dedicated to
customer domains is documented in server-web-prod/README.md.