Skip to main content

Ingest endpoint

app/api/__crust/ingest/route.ts
Point the collector at it:
The handler is authenticated with a constant-time comparison, rate-limited per client, bounded in payload size, and write-only — a 204 with no body, so there is nothing to probe. GET returns 405.
An open POST appending to a history table is free vandalism. The secret must be at least 16 characters; the handler throws at construction otherwise.
Never sync staging data back into git. Let CI write to the repo and keep the server’s samples on the server.

Synthetic runs

Playwright is an optional peer, so ordinary installs never download a browser:

What makes the numbers comparable

  • The first iteration is discarded. A cold start measures the deployment’s morning — server compile caches, CDN misses, JIT warmup — not your code.
  • The median is reported, not the mean. A mean is hostage to a single GC pause.
  • Throttle and network are pinned into the run’s environment fingerprint.
  • The collector and widget are off. A measurement tool competing for the main thread moves the numbers it reports.
Staging numbers are relative, never absolute. Smaller instances, different or absent CDN, more cold starts, and above all a seeded database at a fraction of production size — an 8 ms query on 500 rows is 400 ms on 5 million. crust labels the trend “vs. previous build”, never “is this fast”.

Server spans

Deliberately minimal — your APM may already cover this.
instrumentation.ts
It groups render and fetch time by route. The processor is structurally typed against OTel’s ReadableSpan shape, so crust takes on no OpenTelemetry dependency, and it uses the supported instrumentation.ts hook rather than patching server internals.