Bulk Core Web Vitals Monitor (PageSpeed + CrUX)
Pricing
from $5.60 / 1,000 url auditeds
Bulk Core Web Vitals Monitor (PageSpeed + CrUX)
Bulk PageSpeed + CrUX monitor for hundreds of URLs. Get alerted when your speed app stops working: history, regression alerts, a warning when Lighthouse scores well but real users fail Core Web Vitals, competitor benchmarks, Slack/webhook alerts. No monthly plan: pay per URL.
Pricing
from $5.60 / 1,000 url auditeds
Rating
0.0
(0)
Developer
Mateus Correia
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
Core Web Vitals Monitor: bulk PageSpeed & CrUX checker (GTmetrix alternative)
Get alerted when your speed app or plugin stops working.
Audit hundreds of URLs with PageSpeed Insights and CrUX real-user data (with a free Google API key) in one run, track Core Web Vitals (LCP, INP, CLS), get Slack alerts on regressions and benchmark competitors. It flags pages that score 90+ in Lighthouse while real Chrome users fail Core Web Vitals. This can mean a speed plugin or app is optimising for the PageSpeed test rather than for real visitors, or that the problem only shows on real devices.
A GTmetrix alternative with no monthly plan: $0.008 per URL per device, competitor URLs included, plus $0.01 per own URL × device benchmarked. Google's PSI quota still applies (25,000 requests/day with a free key).
Use cases
- SEO consultants: weekly client reports with regression alerts.
- Shops using a speed app (NitroPack, WP Rocket): daily checks for real users.
- E-commerce teams: benchmark key templates against competitors.
- Developers: check every release from CI, n8n, Make or Zapier.
Sample output (shortened, real coolblue.nl run):
{"url": "https://www.coolblue.nl/","strategy": "mobile","performanceScore": 61,"field": { "source": "crux-api", "lcpMs": 2002, "inpMs": 202, "cls": 0.01 },"coreWebVitalsAssessment": "failed","labFieldMismatch": false,"failingFieldMetrics": [{ "metric": "INP", "p75": 202, "rating": "needs-improvement" }]}
What does it do?
- Bulk PageSpeed Insights (v5). Mobile, desktop or both, with retries and rate-limit handling.
- CrUX field data. Real-user p75 LCP, INP, CLS, FCP and TTFB from the official CrUX API. Falls back to origin-level data when a URL has too little traffic;
field.scopesaysurlororigin. Optionally adds 6-month CrUX history. - Core Web Vitals assessment (passed / failed / insufficient data) on field data.
- Threshold checks for LCP, INP, CLS and the performance score, using your thresholds. Field data is preferred; each check names its source.
- History and regression detection. Each run is compared with the previous one for the same URL and device, with deltas and a
regressions/improvementslist (for example "Performance score dropped 72 → 60" or "Lab LCP worse by 38% (2100ms → 2900ms)"). - Lab-vs-field mismatch warning. When the Lighthouse score is 90 or higher but CrUX fails Core Web Vitals (p75 LCP > 2.5 s, INP > 200 ms or CLS > 0.1), the row gets
labFieldMismatch: true, the failing metrics infailingFieldMetricsand a plain-language message inwarnings. They also appear in the report,OUTPUTand alerts. - Competitor comparison. Your rank, the gap to the best competitor's score and LCP, and a side-by-side table in the report.
- Alerts to any webhook or Slack Incoming Webhook.
- Works without an API key, with limits (see FAQ).
Input
| Field | Description | Default |
|---|---|---|
urls | URLs to audit (yours) | – |
competitorUrls | Competitor URLs to benchmark against | – |
strategy | mobile, desktop or both | mobile |
pageSpeedApiKey | Your Google API key (stored as a secret). Recommended. | – |
includeCrux / includeCruxHistory | Real-user data from the CrUX API (needs an API key) | true / false |
engine | auto (PSI, then local Lighthouse when the quota is exhausted), pagespeed, local | auto |
alertThresholds | { lcpMs, inpMs, cls, performanceScore } | 2500 / 200 / 0.1 / 90 |
historyMode, historyStoreName | Keep history and compute deltas and regressions | true |
regressionScoreDrop, regressionMetricPct | What counts as a regression | 5 points / 15% |
webhookUrl, alertOn | Where to send alerts and for what (regressions, threshold-failures, both) | – / regressions |
maxConcurrency, locale | Advanced settings | auto / en |
Free Google API key (2 minutes): in Google Cloud Console, create a project, enable PageSpeed Insights API and Chrome UX Report API, create an API key under Credentials restricted to those two APIs, and paste it into pageSpeedApiKey. The default PSI quota is 25,000 requests per day.
Output
One dataset row per URL × device, also with role (own or competitor), status (ok or error), full lab/field metrics, checks, passedAllThresholds, topOpportunities, engine and pageSpeedInsightsUrl. On the next run of the same URL, previous, delta, regressions and improvements are filled in.
labFieldMismatch is false in the sample because the lab score (61) is below 90. When a page scores 90+ but field data fails, it is true and warnings explains why, for example: "Lab score 98 looks good, but real Chrome users fail Core Web Vitals: CLS 0.11 (needs improvement)..." It is null when there is no field data or no lab score.
The key-value store holds report.html, OUTPUT (run summary, labFieldMismatches, alerts) and COMPARISON. Download the dataset as CSV, Excel or JSON.
Schedule recurring Core Web Vitals monitoring
Speed usually slips after launch, so monitoring is where this Actor is most useful:
- Save your URLs, competitors, API key and
webhookUrlas an Apify Task (one per client or site, each with its ownhistoryStoreName). - In Apify Console, open Schedules and add the task with a cron expression, for example
0 7 * * *for daily at 07:00 or0 7 * * 1for Mondays. alertOndefaults toregressions, so Slack only hears from it when something got worse. A lab-vs-field mismatch is alerted only when it is new since the previous run.
Use an API key so the engine, and the numbers, stay the same between runs. See Apify schedules.
Use it from n8n, Make and Zapier
Apify has official integrations for all three: connect your Apify account with an API token, then use the Apify app or node to run an Actor or Task and fetch its dataset items, or trigger a workflow when a run finishes.
Typical workflows:
- Client dashboard: after each scheduled run, keep rows with
role: "own"andstatus: "ok"and appendurl,strategy,performanceScore, field LCP/INP/CLS andcoreWebVitalsAssessmentto a Google Sheet or Looker Studio source. - Ticket on regression: for
role: "own"rows with a non-emptyregressionslist, create a Jira, Linear or Trello card. For mismatches, use the webhook alerts (new mismatches only, by default), sincelabFieldMismatchstaystrueon every run until the page is fixed. - After a deploy: run the Task for the changed templates and post the result to the release channel.
Pricing (pay per event)
No subscription, no auto-renew, no monthly plan, no scan quota or page-view tiers. You pay only for audits that run.
| Event | Price |
|---|---|
URL audited (url-audited), per URL × device | $0.008 |
Competitor comparison (competitor-comparison), per own URL × device benchmarked | $0.01 |
Competitor URLs are audited too, so each one costs $0.008 per device, on top of the $0.01 comparison per own URL × device.
Examples: a weekly check of 20 URLs on mobile costs about $0.64 a month. 100 URLs on mobile and desktop, daily, cost about $48 a month. Failed audits are not charged.
Apify's free monthly credit covers hundreds of audits. Set Maximum cost per run to cap spend.
FAQ
Do I need a Google API key? No, but it is recommended, and needed for heavy use. Without a key, Google's keyless quota is shared by everyone and is often exhausted. The Actor then uses its built-in Lighthouse 12 fallback, which gives lab data only and no CrUX field data. With your own free key, results come from Google's PageSpeed Insights API itself, plus CrUX real-user data.
Why do scores differ from my last run? Lighthouse lab scores vary by about ±5 points between runs, so the default regression thresholds ignore small changes and field data (CrUX, 28-day p75) is preferred for pass/fail.
Why is INP empty? INP can only be measured on real users, so it comes only from CrUX. Low-traffic pages have no CrUX data; the origin-level value is used when available.
My speed plugin gives me 95+ in PageSpeed. Why does this flag a mismatch? The PageSpeed score is one lab test on a simulated device. Core Web Vitals pass/fail comes from real Chrome users over 28 days. Some plugins improve the lab test (for example by delaying scripts) without helping visitors. When the two disagree, trust the field data and test on a real phone. Field data lags by up to 28 days, so give a change a few weeks.
How is this different from GTmetrix? It is pay per use with no monthly plan, audits hundreds of URLs per run, and adds CrUX data, regression alerts and competitor benchmarks. It does not offer GTmetrix's choice of test locations or its waterfall and video views.
Can I send alerts to Slack?
Yes. Paste a Slack Incoming Webhook URL into webhookUrl. The payload includes a Slack text field and structured alerts.
Limitations
- The built-in Lighthouse fallback runs on Apify's servers. Mobile scores can be lower than PSI's (different CPU).
- Sites with aggressive bot protection may block the fallback. PSI with an API key is usually not blocked.
- CrUX data exists only for URLs and origins with enough Chrome traffic.
- The PSI API has a limit of about 60 s per audit. Very slow pages can time out and are reported as failed, not charged.
Keywords
Core Web Vitals, Core Web Vitals monitor, PageSpeed checker, bulk PageSpeed Insights, CrUX, Chrome UX Report, LCP INP CLS, site speed monitoring, GTmetrix alternative, competitor speed comparison.