Performance RUM

Percentiles,
never averages.

Real-user Core Web Vitals at full percentile depth — p50, p75, p90, p95 for LCP, INP, CLS, FCP and TTFB — collected by the official web-vitals attribution build and stored as TDigests in ClickHouse, so every percentile is the true percentile of real field data. Averages hide regressions; percentiles convict them.

Full percentile depth

p50, p75, p90, p95 — for all five vitals.

Every vital is stored as a ClickHouse TDigest per day, per page, per device class — which means any percentile can be recomputed exactly, at any retention depth, without averaging anything away. Ratings follow the CrUX methodology: good, needs-improvement, poor.

Vitalp50p75p90p95p75 rating
LCP — largest contentful paint1.6 s2.1 s3.0 s3.8 sgood
INP — interaction to next paint96 ms148 ms214 ms268 msgood
CLS — cumulative layout shift0.030.120.180.24needs-imp.
FCP — first contentful paint1.1 s1.5 s2.1 s2.6 sgood
TTFB — time to first byte0.4 s0.9 s1.2 s1.9 sneeds-imp.

Thresholds are Google's published CrUX boundaries: LCP 2.5 s / 4.0 s · INP 200 ms / 500 ms · CLS 0.10 / 0.25 · FCP 1.8 s / 3.0 s · TTFB 800 ms / 1.8 s — good, needs-improvement, poor. Percentiles come from TDigests, not from sampled averages.

Breakdowns & attribution

Slice every vital until it confesses.

Daily series for trend-watching, per-page breakdowns to find the slow routes, per-device splits because mobile is a different internet — and attribution data for the drill-down: which element painted last, which interaction target stalled.

Attribution built in

The official web-vitals attribution build reports the element behind LCP and CLS and the interaction target behind INP — so a bad percentile names its suspect, and drill-downs start with a suspect, not a blank page.

Per-page, per-device

Every percentile is available per path and per device class. "The site is fine" is not an answer when /checkout on mobile is the one dragging p75 over the line.

Daily series, no consent

Vitals are collected with zero cookies and zero browser storage in the default tier — the same banner-free posture as the rest of Observer, running on your own hardware.

Anomaly detection

When a metric moves, you get sentences.

z-score ≥ 2 against a trailing baseline, evaluated on views, errors, goals and Core Web Vitals — and rendered as plain-language cards on Overview. No ML theater, no opaque scores: an honest statistical flag, phrased so a human can act on it.

Views

"Views on /pricing are 2.4σ below the trailing baseline — check recent deploys and campaigns." Volume shifts surface before they cost you a week.

Errors

"Error rate moved to 2.1σ above baseline in the last hour." The card links straight to the window where it started moving.

Goals

"Goal conversions are 2.3σ below baseline over 24 h." Conversion dips get flagged with the same math as traffic dips.

Core Web Vitals

"LCP p75 moved to 3.1 s on /pricing — check recent deploys." Exactly the card the Overview shows when a vital crosses its baseline.

All detections are z-scores on aggregate data vs a trailing baseline — the same honest statistics that drive the alert rules. Nothing is inferred about individuals, because no individuals exist in the data.

Deploy diff

Ship, then measure the ship.

POST a deploy webhook — authenticated with your site token — and Overview gains "since last deploy" deltas: views, goals, errors and CWV after the deploy, against an equal-length window before it. Regression hunting stops being archaeology.

deploy webhook — fired by your CI
# site-token auth; the timestamp lands on the deploy table
curl -X POST https://sa.yourdomain.com/api/v1/deploy \
  -H "Authorization: Bearer <site-token>" \
  -H "Content-Type: application/json" \
  -d '{ "version": "v2.4.2" }'
Since last deploy · v2.4.2 · 6 h window vs equal window beforedeploy diff
MetricBeforeAfterΔ
Views6,1207,214+17.9%
Goals214262+22.4%
Errors9631−67.7%
LCP p752.9 s2.3 s−0.6 s
Deltas compare an equal-length window after the deploy against the window before — same hours of day, same math, no cherry-picking.

Measure what visitors
actually feel.

Core Web Vitals RUM ships in the default tier — percentiles from day one, no consent banner. Access is granted after an NDA, and we deploy together with your DevOps team, on your hardware.