A Shopify kitchenware brand ran a single Meta catalog (Advantage+ Shopping) campaign across 2,400 SKUs. Account-level ROAS looked acceptable at 3.1. When we split the catalog by spend and purchases per SKU, 340 products — 14% of the catalog — had spent $9,100 combined over the prior 60 days and produced zero purchases between them. None of it showed up in the campaign-level report. A catalog ad doesn't fail the way a single-product ad fails; it just quietly reallocates budget toward whatever converts and keeps paying for whatever doesn't, indefinitely.
Why catalog campaigns hide waste better than any other ad type
A standard campaign has one offer, one landing page, one CVR to watch. A catalog campaign has one blended ROAS number covering however many thousand SKUs are in the feed. Meta's algorithm does allocate more impressions toward better-converting products — but it doesn't stop spending on the rest. Slow-moving SKUs, out-of-stock items still in the feed, and products with thin margins keep drawing a trickle of spend because the account-level number never forces anyone to look at the SKU level.
The bigger the catalog, the worse this gets. A 50-SKU catalog has few enough products that someone eventually notices a dead one. A 2,400-SKU catalog doesn't get looked at row by row — it gets judged by the one number at the top.
The 3-filter catalog audit
This runs inside Meta Commerce Manager's catalog diagnostics plus a Meta Ads Manager breakdown by product ID. Set the window to the last 60 days.
Filter 1: Spend above $15 per SKU, purchases = 0. Break down ad set performance by product ID (Ads Manager → Breakdown → Product ID for catalog campaigns with fewer than ~500 active SKUs; for larger catalogs, export and filter in a spreadsheet). Flag every SKU with more than $15 in attributed spend and zero purchases across the window. These are the clearest waste — a product isn't going to start converting at exactly the same rate after 60 days of nothing.
Filter 2: Feed data quality flags. In Commerce Manager → Catalog → Diagnostics, check for items flagged as out of stock, missing GTIN/price mismatches versus the live Shopify listing, or disapproved. Meta will keep serving ads for a SKU with a stale feed entry until either the feed updates or someone catches it manually. A product that's been sold out for 3 weeks but still shows "in stock" in the feed is spend with a zero conversion ceiling by definition.
Filter 3: Contribution margin below breakeven at current CPA. Pull each flagged SKU's margin. A product converting fine at a $22 CPA is still waste if its margin after COGS and shipping is $14. Catalog ads optimize for purchases, not profit — a "working" SKU can still be a losing one.
What the kitchenware brand's audit found
Filter 1: 340 SKUs flagged, $9,100 in combined 60-day spend, zero purchases. Excluded from the active catalog set (moved to a separate "low priority" product set with a capped daily budget rather than fully paused, since some were newer items still needing signal).
Filter 2: 58 of those 340 were flagged out-of-stock in Commerce Manager's diagnostics but still marked available in the feed — a sync issue between a discontinued-item tag in Shopify and the product feed app. Fixing the sync stopped spend on those 58 immediately.
Filter 3: Of the remaining SKUs that were converting, 22 had margins below their CPA. These were kept in the catalog but excluded from the "broad discovery" product set and moved to a lower-bid set, since suppressing them entirely would have meant losing organic-feeling product diversity in the ad.
30 days after the restructure: catalog-level ROAS moved from 3.1 to 4.0 on the same total spend, because the $9,100/60-days that had been leaking into 340 dead SKUs was now concentrated on the ~2,000 products actually producing purchases.
Run this on your catalog today
Open Meta Ads Manager, set the date range to 60 days, and break your catalog campaign down by Product ID (or export to a spreadsheet if your catalog is too large for the in-platform breakdown to stay usable). Sort by spend, descending, filter to purchases = 0.
Anything above $15 spent with zero purchases goes into a separate, capped-budget product set today — not paused outright if the product is newer, but no longer competing for the same budget as your proven SKUs. Then cross-check the flagged list against Commerce Manager's catalog diagnostics for stock and price mismatches before assuming it's a demand problem rather than a feed problem.
If your catalog is large enough that this audit needs to happen every month rather than once, that recurring maintenance is exactly the kind of thing what a $2,000/month agency should actually deliver covers — and at a certain SKU count, it's worth checking which performance agencies actually handle catalogs at that scale.