In short: On a huge site the first Search question is not which keywords to buy, but which landing pages can mathematically carry the cost of paid clicks. Feed in a GA4 export plus a site crawl, compute maxCPC = target CRR × CR × AOV for every page, and compare each maxCPC to your real average CPC. Out comes a ranked TOP 100–200 build pile, a fix pile of trouble pages, and a skip pile, all before you spend a cent.
Just want the distilled filter?
Download the complete AI instructions — one file you paste into Claude or any capable coding agent, and it sorts your own pages into build, fix and skip piles. Leave your email and the file is yours — or keep reading below.
One file, one list. I only write when there's something worth reading.
A client once handed me a site with about ten thousand landing pages and one question. Where do we start with Search? I’ve heard the default agency answer for twenty years. Point a broad campaign at everything and let Google sort it out. I’ve also cleaned up after that answer often enough to know what it costs. It torches budget on pages that never had a chance to convert, drags the account’s ROAS below its target and poisons the learning phase before anyone reads a single report.
So before a cent leaves the account, I make every landing page prove it can afford a paid click. The proof runs on two things you already own. A GA4 export of your landing pages and a crawl of your site. What comes back is a ranked list of the pages worth a Search campaign, each with the exact max CPC it can afford. Plus a clean “don’t bid on this” pile for the pages whose economics forbid paid search. No keyword tool, no hunch, no “let’s just turn on Dynamic Search Ads and see.”
That’s the whole article. Below I run the pipeline end to end and show you the actual output of every step. The GA4 rows, the max-CPC arithmetic on a single line, the crawl extraction table, the prioritization sort before and after, and the trouble-page diagnosis that rescues a page everyone else would delete. The numbers are illustrative throughout, so plug in your own. The output is laid out exactly as the tools return it.
The pipeline in one box
- What we're after The landing pages worth advertising, ranked
- Inputs GA4 landing-page export · a site crawl
- The one formula maxCPC = target CRR × CR × AOV
- What you get A build pile, a fix pile, and a skip pile
The one number that decides everything
Every landing page has a ceiling: the highest price you can pay for a click and still hit your target efficiency. Compute that ceiling for every page and the whole prioritization falls out of the math:
maxCPC = target CRR × CR × AOV
where CRR (cost-revenue ratio, the European PNO, equivalent to ACOS) is the share of revenue you’re willing to spend on ads, CR is the page’s conversion rate, and AOV is its average order value.
A worked example, straight from the formula. A category page converts at 2%, averages a €1,000 order, and you’re willing to spend 10% of revenue on ads (a 10× ROAS):
maxCPC = 0.10 × 0.02 × €1,000 = €2.00.
If you prefer to think in ROAS, the same thing rearranges to maxCPC = CR × AOV / ROAS = 0.02 × 1,000 / 10 = €2.00. Same number, pick the form your brain likes. (Illustrative example.)
That €2.00 is the verdict. Compare it to the real average CPC in your account for that market and the page sorts itself. If it sits comfortably above the average, you build the page. If it sits below, the page can’t pay its way. If it sits far below, the page isn’t worth considering. Everything that follows is just producing this number for every page, reliably, and reading the result.
The pipeline at a glance
Five steps. For each one, what you do, what you’re looking at, and why. Every step exists to answer one specific question about a page.
1 · Pull landing-page economics from GA4
What you do: per landing page, export sessions, conversions, transactions and revenue; derive CR and AOV. Why: these two numbers measure demand and money in one place, and without them the max CPC is a guess. What you get: one row per page carrying the two numbers the formula eats, CR and AOV.
2 · Crawl the site for structure
What you do: crawl every page for title, H1 and breadcrumb depth, and above all for the column that does the work: how many products it lists. Why: GA4 knows economics but not structure. A page with two products in stock can’t carry a campaign no matter how it converts. What you get: the structural mirror of your GA4 rows, plus a thin-page flag.
3 · Join the two, compute max CPC
What you do: join GA4 and the crawl by URL, run the formula on every row, drop thin pages. Why: this is where economics and structure meet and the verdict becomes computable. What you get: every page with a max CPC sitting next to it.
4 · Prioritize: max CPC vs. real avg CPC
What you do: put each page’s max CPC next to the actual average CPC in your account or country, sort by headroom. Why: a max CPC means nothing in isolation. Only the gap to what clicks actually cost decides if a page can pay. What you get: the TOP 100–200 build pile, a fix pile, and a skip pile.
5 · Diagnose the trouble pages
What you do: for pages that should convert but don’t, check the price-competitiveness of the products they list first. Why: a low CR on a page that ought to sell is usually a merchandising leak, and a merchandising leak is fixable. What you get: pages rescued from the skip pile back into the build pile, once they can actually convert.
Now the same five steps, one at a time, each with the output it produces.
Get the complete AI instructions for this filter
The whole filter, rewritten as a brief you can paste straight into Claude or any capable coding agent. You supply the GA4 export and the crawl; it computes the max CPC for every page and hands back the build, fix and skip piles. Leave your email and the file is yours.
One file, one list. I only write when there's something worth reading.
Step 1 · The GA4 export, as it lands
You don’t need a fancy report. In GA4 open Explore → blank → Free form, dimension Landing page + query string, metrics Sessions, Key events / Conversions, Total revenue. Add Transactions if you have it; otherwise AOV comes from revenue ÷ conversions. One filter up front. Exclude product detail pages and keep category and collection pages. You’re working out which pages are worth sending traffic to, and on most sites those are category pages, not individual product pages. Mixing product pages into the export skews every AOV and CR you compute.
Here is what four representative rows look like once exported, with CR and AOV derived:
Landing page Sessions Conv CR Revenue AOV
/cordless-vacuums 8,140 163 2.0% €68,460 €420
/winter-tyres 5,020 156 3.1% €28,080 €180
/sleeping-bags 12,300 135 1.1% €12,825 €95
/phone-cases 9,800 137 1.4% €2,192 €16
(Illustrative example.) CR is conversions ÷ sessions; AOV is revenue ÷ conversions. That’s the entire input the formula needs from GA4. Two columns per page, CR and AOV. Notice already that /sleeping-bags pulls the most sessions in the set yet converts the worst. Remember that page; it becomes the interesting case later.
Step 2 · The crawl, and the column that does the work
GA4 told you how each page performs. It can’t tell you a page is structurally hollow. A “category” with two products in stock, or a parametric filter view that should never carry a campaign. For that you crawl. Two routes. Have an AI write you a throwaway crawler in five minutes, or use Screaming Frog with a custom XPath extraction you set up in about three minutes (full mini-guide in the download at the end of the article). Run it in List mode on your GA4 URL set and it grinds in the background while you do something else.
The one column that does the work is the product count: how many product cards the page actually renders. Here’s the extraction output joined to the same four pages, plus one more the crawl flags:
URL Title H1 Products Breadcrumb
/cordless-vacuums Cordless Vacuums … Cordless Vacuums 48 Home>Floorcare>Vacuums
/winter-tyres Winter Tyres | … Winter Tyres 112 Home>Tyres>Winter
/sleeping-bags Sleeping Bags … Sleeping Bags 9 Home>Camping>Sleep
/phone-cases Phone Cases … Phone Cases 640 Home>Accessories>Cases
/clearance-2019 Clearance Clearance 0 Home>Clearance
(Illustrative example.) The thin-page rule does its job on the spot. /clearance-2019 lists zero products: an empty category that still collects sessions in GA4. Drop any page under about three products before you prioritize, and that ghost page never reaches the build pile. In practice the thin-page rule is one move on one signal. The crawl shows a “category” with nothing live to sell, and you exclude it before prioritization. You don’t waste a campaign budget, or an analyst’s afternoon, on a page with nothing to offer.
Step 3 · Join the two, and the formula on a single row
Now the two datasets become one. Join GA4 and the crawl by URL and every page carries both its economics (CR, AOV) and its structure (product count). Apply maxCPC = target CRR × CR × AOV to every row of that joined table. Watch it land on a single row, /cordless-vacuums at a target CRR of 10%:
maxCPC = 0.10 × 0.020 × €420 = €0.84.
One line, one ceiling. Do it for all four survivors and you get the per-page max CPC the whole decision hangs on:
Page CR AOV CRR maxCPC = CRR×CR×AOV
/cordless-vacuums 2.0% €420 10% 0.10 × 0.020 × 420 = €0.84
/winter-tyres 3.1% €180 12% 0.12 × 0.031 × 180 = €0.67
/sleeping-bags 1.1% €95 10% 0.10 × 0.011 × 95 = €0.10
/phone-cases 1.4% €16 10% 0.10 × 0.014 × 16 = €0.02
(Illustrative example.) If your margins vary from page to page, the target CRR can vary with them. /winter-tyres has a target CRR of 12% here because the category can take a less strict efficiency goal. Everything else is mechanical. You now have a max CPC for every page on the site; the next step is the only judgement call left.
Step 4 · Prioritize: the sort, before and after
A max CPC means nothing on its own. €0.84 is generous in one market and unaffordable in another. What decides is the gap to what a click actually costs you. So pull your real average CPC per page from the Google Ads account, or per market if the account doesn’t report it per page, and put that figure next to the page’s max CPC.
Before, the raw join in whatever order the rows fell out of it, unreadable as a plan:
Page maxCPC avg CPC
/sleeping-bags €0.10 €0.45
/phone-cases €0.02 €0.35
/cordless-vacuums €0.84 €0.55
/winter-tyres €0.67 €0.40
After, sorted by headroom (maxCPC − avg CPC), the same four rows become a work order with the verdict written in the last column:
| Landing page | CR | AOV | Target CRR | maxCPC | avg CPC | Verdict |
|---|---|---|---|---|---|---|
| /cordless-vacuums | 2.0% | €420 | 10% | €0.84 | €0.55 | Build now |
| /winter-tyres | 3.1% | €180 | 12% | €0.67 | €0.40 | Build now |
| /sleeping-bags | 1.1% | €95 | 10% | €0.10 | €0.45 | Fix first (trouble page) |
| /phone-cases | 1.4% | €16 | 10% | €0.02 | €0.35 | Don't bother |
(Illustrative example.) The numbers are made up to show the mechanic, so plug in your own GA4 figures. Every maxCPC here is just target CRR × CR × AOV applied to the row.
Two rows are obvious. /cordless-vacuums can pay €0.84 where the market costs €0.55: that is 53% of headroom, so you build it. /winter-tyres likewise. /phone-cases can only afford €0.02 where clicks cost €0.35. That will never work in your wettest dreams, so leave it out and don’t look back. Scale this from four rows to ten thousand and the top of the sorted list is your TOP 100–200, the pages to build first, ranked by how much room they have to bid.
The interesting one is /sleeping-bags. maxCPC €0.10 against a €0.45 market, so on paper “don’t bother.” But /sleeping-bags pulled the most sessions in the whole export, and sleeping bags are a category that obviously should sell. A suspiciously low CR on a page that ought to convert is rarely a demand problem. It’s a trouble page, and trouble pages get a diagnosis, not a delete.
Step 5 · Trouble pages: the diagnosis, on a real listing
When a page’s conversion rate sits far below what the category should deliver, ask why before you drop it. On e-commerce the answer, most of the time, is the price-competitiveness of the products the page shows first. The first 10–20 products a visitor sees are the page’s entire first impression. If those are your weakest-value items, CR craters regardless of how much demand the page pulls.
So you read the category exactly as the customer does, in its default sort order, and price-check the products it lists first.
Read the category's product mix in sort order
Pull the products in /sleeping-bags by their product_type from Google Merchant Center, in the default listing order the visitor actually gets. The top of the list is what’s converting (or not).
Price-check the top positions against the market
Take the top-listed products and research live competitor prices with DataForSEO. The serp/google/organic/live/advanced endpoint returns the whole results page (shopping blocks with merchants and prices, organic below) as structured JSON. Billing runs per SERP of up to 10 results, at a base price of about $0.002 before paid advanced parameters.
Cut the price or change the sort order, then measure again
If the first-listed products are over-priced, you have two levers. Cut their price, or change the category’s sort order so genuinely competitive products lead. Then watch CR. Only once CR lifts do you promote the page from the fix pile into the build pile.
This is what that diagnosis looks like on /sleeping-bags, the page sitting at maxCPC €0.10. Top of the listing, your price against the cheapest competitor DataForSEO found for the same product:
Pos Product (first-listed) Your price Cheapest comp. Gap
1 AlpineLite 200 Down Bag €129 €99 +30%
2 TrekWarm Mummy −5°C €115 €112 +3%
3 BaseCamp Synthetic XL €89 €92 −3%
4 ValleyHike Junior €45 €47 −4%
(Illustrative example.) The leak is right at the top. The product 12,300 monthly sessions land on first is priced 30% over the cheapest market offer. Everything below it is competitive, but after a first impression that bad, almost nobody keeps scrolling. Drop the AlpineLite price to €105, or change the sort order so the competitive BaseCamp and ValleyHike come first, and CR climbs back to the normal level for the category. Re-run step 3: the maxCPC rises above €0.10, and the page graduates into the build pile.
This is the loop most agencies never close, because it reaches into an area they usually stay out of. The shop’s job (pricing, merchandising, sort order) and the agency’s job (buying the traffic) are two halves of one optimization loop. Optimize the buying without the shop, and you are paying for traffic that leaks away.
After the filter: choosing how you buy
Only now, with the build pile in hand, do you pick the how. AI Max, Dynamic Search Ads, classic STAG, or a combination (broad plus DSA in one campaign). Whether that is one campaign or three or five depends on the client and conversion volume; respect the roughly 30-conversions-per-campaign rule before you split. I’m leaving this choice to you on purpose. The point of the whole pipeline is that you make it after the economics, not before.
Whatever you land on, the rule is the same. A new campaign must never start on bad pages. Weak landing pages drag the account’s ROAS below its target and poison the learning phase. The pre-filter keeps the launch pointed only at pages that can pay for themselves. From there you build the super-structure: crawl data plus keyword research per category via the Google Ads API, constructed in waves by category, language and maturity. That super-structure is a topic of its own, and I’ve described it in a separate article on market expansion.
The part that ties back to the manifesto
Technically, none of this is new. You could have run the GA4 export, the crawl, the price scrape and the join five years ago. But it would have been half a year of bespoke development, and anyone sane would have given up halfway. Twelve years of writing against the Google Ads API taught me exactly how those projects die. I’m writing it down now because tools like Codex, Claude Code and the current generation of agents have turned it from a project into a regular Tuesday workflow: a script you run on an account overnight.
That’s the whole shift, and it’s clearest from both sides at once. The shop’s work on pricing and merchandising and the agency’s work on advertising collapse into a single loop, and both halves can finally be optimized together. The economics are what let you close that loop.
Download the complete instructions for your AI
The whole filter above, rewritten as a brief you can paste straight into Claude or any capable coding agent. You supply the GA4 export and the crawl; it computes the max CPC for every page and hands back the build, fix and skip piles. Leave your email and the file is yours.
One file, one list. I only write when there's something worth reading.
FAQ
Why use maxCPC instead of just looking at ROAS targets in Google Ads?
Because Google’s tROAS reacts after you’ve spent money learning. maxCPC is a pre-launch filter. It tells you, before a single click, which pages can mathematically carry the cost of paid clicks. You use it to decide what to build; tROAS then runs what you built.
My CR and AOV swing a lot month to month. Doesn't that break the formula?
Use a stable window of 60 to 90 days and segment by device or market if they differ materially. The formula isn’t meant to be precise to the cent. It sorts pages into build, fix and skip piles, so what you need is the rough order of magnitude of the headroom, not the exact figure.
Do I really need Screaming Frog, or can AI just write the crawler?
Either works. Screaming Frog with a custom XPath extraction is the no-code route and genuinely a three-minute setup. A scripted crawler is better if you need the data joined into a pipeline automatically. Pick by whether this is a one-off audit or a repeatable workflow.
What counts as a 'trouble page' versus a page I should just skip?
A skip page has weak economics by nature. Low AOV, low intent, so its maxCPC is genuinely tiny and always will be (/phone-cases at €0.02). A trouble page should convert. Decent AOV, real demand, lots of sessions, yet it doesn’t, usually because its first-listed products are over-priced or badly sorted (/sleeping-bags at €0.10). Skip pages you leave out; trouble pages you fix, then re-measure.
Does this only work for e-commerce?
The maxCPC formula works anywhere you have a conversion value, lead gen included, where AOV becomes lead value. The trouble-page diagnosis (Merchant Center product_type, competitor pricing, category sort order) is e-commerce-specific. Lead-gen trouble pages need their own diagnosis, usually form friction or offer mismatch.
How does this connect to AI Max and the end of DSA?
This filter runs before you choose a campaign type. Whether you pick AI Max (DSA’s successor) or classic STAG, the campaign should send traffic only to pages that passed the filter. The strategy choice changes how you buy; the economics decide what’s worth buying at all.
CTA: Want the build pile for your site, ranked by what each page can actually afford? Send me your GA4 export and we’ll run the filter together.