Catch Google Ads money landing on pages that load too slowly to convert
Every Monday: Google Ads spend per landing page joined with mobile LCP from PageSpeed Insights and GA4 bounce rate, and a question on what to do first.
How the skill works: your agent reads spend per landing page from Google Ads; test each page on mobile from PageSpeed Insights; paid visitors' behavior per page from Google Analytics; google ads customer id, ga4 property id, slow lcp threshold (seconds) from What you tell it, mondays at 9:00, and gives you a question for you and a telegram ping and the report in the chat.
Reads
Google AdsSpend per landing page
PageSpeed InsightsTest each page on mobile
Google AnalyticsPaid visitors' behavior per page
What you tell itGoogle Ads customer ID, GA4 property ID, Slow LCP threshold (seconds)
reads
Your agentClaude Code, Codex, Cursor or GeminiMondays at 9:00
posts
You get
A question for youOn your board, answered with a tap
A Telegram pingOnly when it needs your answer, if you connect Telegram
The report in the chatEvery run, with or without Briefkin
What you get
Spend on slow pages last week and how many pages.
Per page: spend, clicks, mobile LCP (field or lab), bounce rate, key events.
Slow vs fast: cost per key event on each.
Tracking gaps: pages with ad clicks but no GA4 paid sessions.
The ask: fix tickets, new final URLs, or leave it.
The card on the right is a sample. Yours shows your own numbers and updates in place every run.
What lands on your board
Your boardMondays at 9:00
example.comAd spend on slow landing pages: Google Ads, PageSpeed Insights and GA4 · Claude Code
$1.2k a week lands on 3 slow pages
What should I do about these three pages?
$1,200 of last week's Google Ads spend landed on 3 pages with mobile LCP over 4 seconds, where paid visitors bounced 71% of the time. A key event costs $80 there and $28 on /lp/invoice-template.
Landing page
Spend
Mobile LCP
Bounce
Key events
/pricing-lp-b
$540
4.8 s
74%
6
/features/invoicing
$410
4.3 s
69%
5
/lp/free-trial
$250
4.1 s (lab)
68%
4
/lp/invoice-template
$860
2.1 s
44%
31
/lp/free-trial is new on the list. /lp/spring-promo took $140 of clicks but no GA4 paid sessions: a redirect may be dropping gclid.
An example with made-up numbers. Your agent posts your real ones.
What it does
Paid search sends a click to a page, and the page takes five seconds to show anything on a phone. Google Ads reports the click and its cost, PageSpeed Insights reports the slow load, GA4 reports the bounce, and nobody sees the three facts on the same row.
Every Monday the agent takes last week's spend per landing page, tests each page on mobile, and joins in how paid visitors behaved once they got there. The card puts a dollar figure on slow pages and asks whether to draft fixes or point the ads somewhere faster.
How it works
1Get spend per landing page
Run SELECT expanded_landing_page_view.expanded_final_url, metrics.cost_micros, metrics.clicks, metrics.conversions FROM expanded_landing_page_view WHERE segments.date DURING LAST_7_DAYS AND metrics.cost_micros > 0. Normalize each URL (lowercase host, drop www., the query string, the fragment and a trailing slash), sum by the result, and keep pages with $100 or more of spend, at most 20.
2Test each page on mobile
Call runPagespeed?url=<normalized URL>&strategy=mobile&category=performance. Use loadingExperience.metrics.LARGEST_CONTENTFUL_PAINT_MS.percentile (p75 over 28 days) unless loadingExperience.origin_fallback is true; then run the lab test 3 times and take the median audits["largest-contentful-paint"].numericValue, marked as lab.
3Get paid visitors' behavior per page
Call runReport for the same 7 days with dimensions: ["landingPage", "hostName"], metrics sessions, bounceRate, engagementRate and keyEvents, and a filter sessionSourceMedium == "google / cpc".
4
4Join on the landing page path
Match each Ads URL to GA4 on host and path (landingPage has no query string; strip a trailing slash on both sides). An Ads page with no GA4 cpc sessions is a tracking gap (a redirect dropping gclid or a missing tag) and gets its own line; GA4 cpc pages with no Ads row and under 20 sessions are ignored. A page is slow when LCP is over 4.0 seconds, Google's "poor" line.
5
5Ask what to do
Total the spend on slow pages, their session-weighted bounce rate and cost per key event against the fast pages. Read last week's card with GET https://briefkin.dev/v1/cards/insight-google-ads-spend-on-slow-pages to say which pages are new to the list. Then ask whether to draft fix tickets, draft new final URLs, or leave it; the agent changes nothing in Google Ads.
Post it to the board
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Install and run it
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
Agent
Data
Schedule
Install the skill
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/google-ads-spend-on-slow-pages/install | sh
Run it
Ask Claude Code:
promptRun the google-ads-spend-on-slow-pages skill
Or paste the prompt instead of installing:
promptFor the last 7 days, get Google Ads spend, clicks and conversions per landing page from expanded_landing_page_view, normalize the URLs (no query string, no trailing slash) and keep pages with $100 or more of spend. Run PageSpeed Insights on each with strategy=mobile and take the field LCP p75, or the median of 3 lab runs when there is no field data. From GA4 runReport, get sessions, bounceRate and keyEvents by landingPage for sessionSourceMedium google / cpc. Join on host and path. List the pages with LCP over 4 seconds with spend, LCP, bounce rate and key events, the total spend on them, and cost per key event on slow vs fast pages. List Ads pages with no GA4 paid sessions as tracking gaps. Then ask me whether to draft fix tickets or new final URLs; change nothing in Google Ads.
Put it on a schedule
Mondays at 9:00, from cron on any machine where Claude Code is signed in:
crontab0 9 * * 1 claude -p "Run the google-ads-spend-on-slow-pages skill"
Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Send it to your board
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a question for you. How setup works
SKILL.md---
name: google-ads-spend-on-slow-pages
description: "Every Monday: Google Ads spend per landing page joined with mobile LCP from PageSpeed Insights and GA4 bounce rate, and a question on what to do first. Use when the user asks for this, or when it runs on a schedule."
---
# Ad spend on slow landing pages: Google Ads, PageSpeed Insights and GA4
Every Monday: Google Ads spend per landing page joined with mobile LCP from PageSpeed Insights and GA4 bounce rate, and a question on what to do first.
Paid search sends a click to a page, and the page takes five seconds to show anything on a phone. Google Ads reports the click and its cost, PageSpeed Insights reports the slow load, GA4 reports the bounce, and nobody sees the three facts on the same row.
Every Monday the agent takes last week's spend per landing page, tests each page on mobile, and joins in how paid visitors behaved once they got there. The card puts a dollar figure on slow pages and asks whether to draft fixes or point the ads somewhere faster.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- Read only access to the Google Ads account (the Google Ads MCP server or the API), and Viewer on the GA4 property that the landing pages report to.
- A PageSpeed Insights API key in `PAGESPEED_API_KEY` (free; a run makes about 20 to 60 requests), and the GA4 tag on every landing page with auto-tagging intact through redirects.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **Get spend per landing page** (Google Ads): Run `SELECT expanded_landing_page_view.expanded_final_url, metrics.cost_micros, metrics.clicks, metrics.conversions FROM expanded_landing_page_view WHERE segments.date DURING LAST_7_DAYS AND metrics.cost_micros > 0`. Normalize each URL (lowercase host, drop `www.`, the query string, the fragment and a trailing slash), sum by the result, and keep pages with $100 or more of spend, at most 20.
2. **Test each page on mobile** (PageSpeed Insights): Call `runPagespeed?url=<normalized URL>&strategy=mobile&category=performance`. Use `loadingExperience.metrics.LARGEST_CONTENTFUL_PAINT_MS.percentile` (p75 over 28 days) unless `loadingExperience.origin_fallback` is true; then run the lab test 3 times and take the median `audits["largest-contentful-paint"].numericValue`, marked as lab.
3. **Get paid visitors' behavior per page** (Google Analytics): Call `runReport` for the same 7 days with `dimensions: ["landingPage", "hostName"]`, metrics `sessions`, `bounceRate`, `engagementRate` and `keyEvents`, and a filter `sessionSourceMedium == "google / cpc"`.
4. **Join on the landing page path**: Match each Ads URL to GA4 on host and path (`landingPage` has no query string; strip a trailing slash on both sides). An Ads page with no GA4 cpc sessions is a tracking gap (a redirect dropping `gclid` or a missing tag) and gets its own line; GA4 cpc pages with no Ads row and under 20 sessions are ignored. A page is slow when LCP is over 4.0 seconds, Google's "poor" line.
5. **Ask what to do**: Total the spend on slow pages, their session-weighted bounce rate and cost per key event against the fast pages. Read last week's card with `GET https://briefkin.dev/v1/cards/insight-google-ads-spend-on-slow-pages` to say which pages are new to the list. Then ask whether to draft fix tickets, draft new final URLs, or leave it; the agent changes nothing in Google Ads.
## Route B: the browser
### What you need
- Signed in to Google Ads with Read only access or higher, and to GA4 with Viewer access on the property; PageSpeed Insights needs no sign-in.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://ads.google.com/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **Read spend per landing page**: Pick the account, then open **Campaigns > Insights and reports > Landing pages** (or type "Landing pages" in the search bar at the top). Set the date to **Last 7 days**, switch to **Expanded landing pages**, sort by **Cost**, and note the pages with $100 or more.
2. **Test each page**: Open `https://pagespeed.web.dev/`, enter each URL without its query string, and read the **Mobile** tab. Use the Largest Contentful Paint from **Discover what your real users are experiencing** when it is shown for this URL; when only the origin is shown, use the lab LCP under **Diagnose performance issues**.
3. **Read paid visitors in GA4**: In `https://analytics.google.com/`, open **Explore > Free form** with the dimensions **Landing page** and **Session source / medium**, the metrics **Sessions**, **Bounce rate** and **Key events**, a filter on Session source / medium exactly `google / cpc`, and the last 7 days.
4. **Join and ask**: Match the pages on their path. List those with LCP over 4 seconds with spend, LCP, bounce rate and key events, total their spend, and note any Ads page with no paid sessions in GA4. Ask before changing anything.
Note: The Landing pages report sits in a different spot in older Google Ads layouts; the search bar always finds it. Each PageSpeed test takes about half a minute, so 20 pages is a slow run, and lab numbers vary between runs. GA4 explorations can sample on large properties.
## The report
- **Spend on slow pages** last week and how many pages.
- **Per page**: spend, clicks, mobile LCP (field or lab), bounce rate, key events.
- **Slow vs fast**: cost per key event on each.
- **Tracking gaps**: pages with ad clicks but no GA4 paid sessions.
- The ask: fix tickets, new final URLs, or leave it.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "google-ads-spend-on-slow-pages/<date of this run, e.g. 2026-10-16>",
"item_key": "google-ads-spend-on-slow-pages",
"project": "example.com",
"source": "Ad spend on slow landing pages: Google Ads, PageSpeed Insights and GA4 skill",
"kind": "action",
"title": "$1.2k a week lands on 3 slow pages",
"summary": "**$1,200** of last week's Google Ads spend landed on **3 pages with mobile LCP over 4 seconds**, where paid visitors bounced **71%** of the time. A key event costs $80 there and $28 on /lp/invoice-template.",
"action": {
"request": "What should I do about these three pages?",
"options": [
"Draft a fix ticket per page",
"Draft new final URLs",
"Both",
"Leave them this week"
]
},
"widget": [
{
"type": "Table",
"props": {
"columns": [
"Landing page",
"Spend",
"Mobile LCP",
"Bounce",
"Key events"
],
"align": [
"left",
"right",
"right",
"right",
"right"
],
"rows": [
[
"/pricing-lp-b",
"$540",
"4.8 s",
"74%",
6
],
[
"/features/invoicing",
"$410",
"4.3 s",
"69%",
5
],
[
"/lp/free-trial",
"$250",
"4.1 s (lab)",
"68%",
4
],
[
"/lp/invoice-template",
"$860",
"2.1 s",
"44%",
31
]
]
}
},
{
"type": "Callout",
"props": {
"text": "/lp/free-trial is new on the list. /lp/spring-promo took $140 of clicks but no GA4 paid sessions: a redirect may be dropping gclid.",
"tone": "warn"
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Mondays at 9:00 (`0 9 * * 1`). From cron, with the agent signed in on that machine:
```bash
0 9 * * 1 claude -p "Run the google-ads-spend-on-slow-pages skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/google-ads-spend-on-slow-pages#schedule
Source: https://briefkin.dev/skills/google-ads-spend-on-slow-pages
What your agent needs
Read only access to the Google Ads account (the Google Ads MCP server or the API), and Viewer on the GA4 property that the landing pages report to.
A PageSpeed Insights API key in PAGESPEED_API_KEY (free; a run makes about 20 to 60 requests), and the GA4 tag on every landing page with auto-tagging intact through redirects.
Connecting Google Ads
Google Ads MCP server, Google's open-source, read-only server (google-ads-mcp, source). Run it locally with pipx run --spec git+https://github.com/googleads/google-ads-mcp.git google-ads-mcp, or deploy it to Cloud Run for remote clients. Its tools are list_accessible_customers, search for GAQL and get_resource_metadata (docs).
Google Ads API with OAuth. Enable the Google Ads API in a Google Cloud project, sign in with Application Default Credentials (gcloud auth application-default login with the adwords scope) or an OAuth client, and set GOOGLE_PROJECT_ID. Add GOOGLE_ADS_LOGIN_CUSTOMER_ID when you reach client accounts through a manager account, and write customer IDs without dashes.
The adwords scope can't be narrowed, so sign in as a Google Ads user with Read only access; the MCP server has no write tools either way.
Connecting PageSpeed Insights
MCP server. Google doesn't publish an MCP server for PageSpeed Insights; community servers wrap the same API. The Chrome DevTools project does publish Chrome DevTools MCP, which records performance traces in a local Chrome and can add CrUX field data: claude mcp add --transport stdio chrome-devtools -- npx -y chrome-devtools-mcp@latest (source). Codex and Cursor run the same command.
PageSpeed Insights API with a key. The API answers occasional requests without a key; for scheduled runs, enable the PageSpeed Insights API in a Google Cloud project, create an API key restricted to it, and store it in PAGESPEED_API_KEY. Enable the Chrome UX Report API on the same key if the skill also reads CrUX history.
Lighthouse CLI.npx lighthouse https://example.com --only-categories=performance --output=json --quiet --chrome-flags="--headless" runs the lab test on your own machine or in CI.
All of this reads public performance data. Restrict the API key to the PageSpeed Insights and Chrome UX Report APIs so a leaked key is useless for anything else.
Connecting Google Analytics
Google Analytics MCP server, Google's own open-source server (analytics-mcp on PyPI, source). It runs locally with pipx run analytics-mcp, offers run_report, run_realtime_report and get_account_summaries, and Google labels it experimental.
Data API with a service account. Enable the Google Analytics Data API in a Google Cloud project, create a service account, add its email as a Viewer on the GA4 property, and point GOOGLE_APPLICATION_CREDENTIALS at its JSON key. The skill also reads GA4_PROPERTY_ID.
Your own Google login.gcloud auth application-default login --scopes https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform --client-id-file=client.json gives the MCP server or a script your user's access without a key file.
Request only analytics.readonly and keep the service account at Viewer: none of these reports needs Editor.
Questions
Why do some pages show a lab LCP instead of field data?
Field data comes from the Chrome UX Report and needs enough real Chrome visits to a URL over 28 days. Ad landing pages often get too few, and PageSpeed Insights then falls back to the whole site's numbers, which say nothing about that page. The skill uses the median of three lab runs in that case and marks it, since lab runs vary from one to the next.
Why does GA4 show fewer paid sessions than Google Ads shows clicks?
Clicks and sessions are counted differently: a visitor who clicks twice in a few minutes is one session, and people who leave before the page loads never fire the GA4 tag. On slow pages that last group is bigger, which is part of the cost. A page with clicks and no paid sessions at all is different: usually a redirect that drops gclid or a page without the tag.
Do I need Briefkin to use the Ad spend on slow landing pages: Google Ads, PageSpeed Insights and GA4 skill?
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a asks you, so you can glance at it instead of asking again.
Which agents can run it?
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Can it work without an API or MCP server, from my browser?
Yes. Switch the data source to "Your browser" and the steps change to the Google Ads, PageSpeed Insights and Google Analytics pages themselves: the agent opens ads.google.com in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
More skills with Google Ads and PageSpeed Insights
Answer your agents from one board, or from Telegram
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.