skip to main content

Post-launch Core Web Vitals: A 30-day monitoring plan

Lighthouse said 95+ at launch but Search Console turned red three weeks later? A 30-day, 4-phase CWV monitoring plan: Plausible web-vitals + Lighthouse CI + RUM.

Engineering — Post-launch Core Web Vitals: A 30-day monitoring plan

If your Search Console CWV tab is drifting yellow after launch and you’re not sure where to start, this post hands you a 30-day plan. You launched, scored 95+ on Lighthouse, and the performance card went green with LCP at 1.8 seconds. Three weeks later, the Search Console “Core Web Vitals” tab turns yellow, then red. In the field, real users see LCP at 3.4 seconds, INP at 280 ms, and CLS at 0.18. That gap is not a Lighthouse lie. It is the distance between the lab — fixed CPU throttling, fixed network, cold cache, one location — and the actual user opening the page on a mid-tier Android over mobile 4G with a warm DOM and a tail of third-party scripts loading in.

This post walks through the first 30 days we spend closing that gap. The plan has four phases: days 0–3 baseline and alerting, days 4–14 pattern detection, days 15–21 targeted fixes, days 22–30 stabilisation and reporting. We finish by handing a weekly executive report to the product team. Throughout, we work with concrete thresholds (LCP <2.5s, INP <200ms, CLS <0.1) and real tools (Plausible web-vitals, Lighthouse CI, the web-vitals npm package, PostHog session replay, Cloudflare Web Analytics) because the advice “set up RUM” looks fine on paper but does nothing until it lands on a dashboard someone actually checks Tuesday morning.

Days 0–3: baseline and alerting

The only goal of the first 72 hours is for real-user data to start flowing and for the right person to be paged when a threshold breaks. If you measured nothing before launch, you cannot answer “did it get worse” after launch. Day zero is therefore the baseline day.

Pick and wire the RUM source. Two main paths. The first is the Plausible web-vitals plugin — script.manual.outbound-links.tagged-events.web-vitals.js ships LCP, INP, and CLS alongside pageviews; cookieless, GDPR-friendly, p75 visible in the dashboard. The second is Google’s official web-vitals npm package (onLCP, onINP, onCLS callbacks) writing to your own telemetry endpoint. We start most projects on Plausible; the moment PUBLIC_PLAUSIBLE_DOMAIN is set, measurement is live.

Write the thresholds down. We treat Google’s “Good” boundaries as fixed: p75 LCP <2.5s, p75 INP <200ms, p75 CLS <0.1. Our Lighthouse CI configuration uses the same numbers (largest-contentful-paint 2500, cumulative-layout-shift 0.1, total-blocking-time 200). Lab-to-field consistency starts here.

Wire the alert path. A daily script reads p75 from the Plausible Stats API or PostHog events; if a threshold breaks, a Slack message lands in #perf-alerts and the on-call engineer’s email. The first week is full of false positives — p75 swings on low sample volume. We suppress alerts under 200 samples and require three days of consecutive breach before paging.

Search Console linkage. Verify the site and submit the sitemap within 48 hours of launch. The Search Console “Core Web Vitals” report draws from CrUX (Chrome User Experience Report); the first meaningful data shows up 21–28 days later. We do not chase Search Console early; we use it for the end-of-month report.

By the end of day 3 you should have: a CWV card visible in Plausible, a tested alert configuration, Lighthouse CI running daily through .lighthouserc.json, and a verified Search Console property.

Days 4–14: pattern detection

The second phase is an eleven-day observation window. Spend 15 minutes every morning on the Plausible CWV card, PostHog session replay (10% sample), and the last 24 hours of Lighthouse CI output. The goal is not to ship fixes yet; it is to see patterns.

Slice by segment. A single p75 number lies. Break the same metric across four axes: by route (homepage, service pages, blog, contact), by device (mobile/desktop), by country (TR, EU, US), and by network (4G/3G/wifi). Most regressions live in a single intersection: “mobile + 4G + blog detail” becomes the top of the fix list while the global p75 looks fine.

Common early-stage problems. Five patterns we keep finding in the first 30 days of any launch:

  • Third-party script regressions. Marketing adds a pixel through GTM, INP jumps from 60 ms to 240 ms. Tag new scripts with Plausible “outbound link” or as PostHog events, and align the spike with the deploy timestamp.
  • Image format mismatch. Hero images ship as AVIF/WebP, but new blog images uploaded through the CMS arrive as PNG. When the LCP element is a CMS image, the metric breaches 2.5 seconds. The “Astro <Image /> everywhere” rule earns its keep here.
  • Hydration spikes. React islands (especially heavy form components) block the main thread while hydrating, and INP balloons. PostHog session replay shows it as input lag.
  • Font swap CLS. Self-hosted Inter and Inter Tight loaded with font-display: swap push CLS to 0.12 because of x-height delta between fallback and custom font. Until corrected with size-adjust, it shows up on every route.
  • Lazy-load misses. A loading="lazy" on the above-the-fold image delays LCP by 800 ms. Standard mistake; one shows up most sprints.

Keep a daily log. A markdown file with date, observation, hypothesis, no change yet. This log is the prioritisation source for the day-15 fix wave. A single file beats scattered Slack threads: page, metric, device, date.

A note on INP. INP replaced FID as a Core Web Vital in March 2024. Lighthouse approximates it through TBT (Total Blocking Time), but the two are not identical. Field INP is closer to the p98 latency a user feels across the entire interaction lifetime — the value reads differently after the first ten seconds, when the DOM is warm. That is why we trust RUM, not lab, in the first 14 days.

Local versus international users. In most engagements, TR visitors hit a local CDN node while EU/US users hit a more distant edge. The same route can show p75 LCP at 1.9s for TR and 3.2s for EU. The gap usually traces to CDN cache hit ratio and image weight — Cloudflare Web Analytics breaks this down geographically inside 30 seconds. Don’t stop at a single global p75.

Days 15–21: targeted fixes

In the third phase, two weeks of accumulated data feed a fix wave. Prioritisation runs on two axes: user impact (% of sessions affected) times frequency (daily occurrences).

Easy wins first. Fixes that close inside one sprint, ship measurable impact, and carry low regression risk:

  • Remove loading="lazy" from the above-the-fold image, replace with fetchpriority="high". Preload the critical fonts via <link rel="preload">. Inline the critical CSS. The three together usually move LCP by 400–700 ms.
  • Defer or async third-party scripts; remove the unused ones (legacy analytics, dormant A/B test SDKs) entirely.

Medium-effort fixes next. Architectural changes that span more than one sprint:

  • Hydration partials: in Astro, use client:visible or client:idle on heavy islands so they only hydrate when in viewport. INP drops in the 80–150 ms range.
  • CMS image pipeline: automatic AVIF/WebP fallback generation for every new upload. Either Cloudflare Image Resizing on the CDN or a build step in your repo.
  • Font metric overrides (size-adjust, ascent-override): cuts font-swap CLS from 0.12 to 0.02; one-time fix.

Don’t ship them all at once. The most expensive mistake is bundling five fixes into one PR. If one regresses, you need days to find which. Keep one fix per PR, one deploy at a time, at least 24 hours apart. When uncertain, A/B test: route 10% of traffic to the new version through Cloudflare Workers, watch the p75 delta in Plausible with a variant property.

Write to the fix log. Which PR, which metric before and after, which page. That record becomes the spine of the day-22 report.

Days 22–30: stabilisation and reporting

The last phase confirms the fix waves stuck and hands the process over to the product team.

Two weeks of observation. Verify that fixes shipped in days 15–21 land in RUM. The Plausible CWV card shows before-and-after on p75 LCP/INP/CLS; we expect at least seven consecutive days under threshold. A single good day means nothing — we want a trend.

Search Console check. From day 22 onward, the CrUX data starts to be meaningful. The “Core Web Vitals” report should show more green URLs and fewer red ones. URLs still red are usually low-traffic pages — we sit with the product team and decide “shut it down or optimize it.”

Weekly executive report. A single page with five sections: 1) p75 LCP/INP/CLS trend across the last 4 weeks, 2) route hotlist (worst 5 pages, p75 values, sessions affected), 3) fix log (PRs shipped this week, measured impact), 4) pending risks (third-party script requests, planned product changes), 5) next-week plan. A CTO or product director should be able to read it in 5 minutes.

Hand-off. On day 30 the report moves to the product team: an alert-channel owner is named, a 30-minute weekly “perf review” lands on the calendar, Lighthouse CI stays as a blocker on the PR pipeline (no PR ships unless it passes LCP <2.5s and CLS <0.1). Our active monitoring role shifts from day 30 to reactive consultancy — we get pulled in when a threshold breaks.

Tools we use at beynart

  • Plausible web-vitals plugin — primary RUM source; cookieless, GDPR-friendly, p75 dashboard out of the box. Either self-hosted or SaaS works inside our setup.
  • PostHog session replay — 10% sample, used to find what caused INP spikes. Filter by an “input lag” event.
  • Cloudflare Web Analytics — backup RUM source; runs in parallel so the data does not gap if Plausible goes down.
  • Lighthouse CI — blocker on the PR pipeline; runs against 18 URLs (TR + EN, critical pages) through .lighthouserc.json. PRs fail if LCP, CLS, or TBT breach thresholds.
  • web-vitals npm package — for custom metrics (Time to First Byte breakdown, custom event timing) the Plausible plugin does not cover, we instrument and write to our own telemetry.

We tune this kit per engagement; the full configuration sits inside our martech and AI operations work.

Closing

When the 30-day plan does its job, three things stay behind: a sustainable RUM pipeline with alerting, a CWV profile stabilised by five concrete fixes, and a weekly reporting discipline owned by the product team. Enough to never repeat the bad path — three weeks after launch, Search Console going red while no one notices.

If you want this discipline plugged into your stack decisions, our martech stack architecture post covers the prior step; to wire the performance pipeline into your back-office systems, our enterprise systems page is the next stop. For a pre- or post-launch performance audit, get in touch[email protected].

Post-launch Core Web Vitals: A 30-day monitoring plan — section visual

Share

Not sure where to start?

Let's find the layer that fits your need and map where the architecture begins.

Related writing

Related writing

Different windows on the same topic.

Newsletter

MarTech, AI, and engineering systems — straight from the beynart team. Once every quarter, no spam.