2026-08-01
Margin-Based Bidding in Performance Max: Tag Your Feed (2026)
Performance Max spends the same $1 chasing a 5%-margin product and a 50%-margin one, because it optimizes to the number you feed it — and by default that number is revenue. Tag every SKU by margin in your feed, give each tier its own target, and the algorithm starts bidding on profit instead.
Google Performance Max and Meta's Advantage+ Catalog ads bid on revenue, not profit. They can't see your margin unless you put it in the feed. So when two products convert at the same ROAS but one keeps 45 cents on the dollar and the other keeps a nickel, the algorithm treats them as equals and happily pours budget into the loser. This piece is the tactical how behind POAS: a nightly pipeline that tags every SKU by margin tier in Google Merchant Center, plus a campaign structure that gives each tier its own target — so the machine reallocates spend toward the products that actually make you money.
The short version
- Your ad platform optimizes to revenue, not profit. PMax and Advantage+ chase the conversion value you send them. Send revenue, and they'll happily scale a product with no margin left.
- Same ROAS, opposite outcomes. A cheap low-margin item and an expensive high-margin one can hit the identical ROAS while one prints cash and the other bleeds. A blended target buries that.
- The feed is your biggest lever. The algorithm can only optimize the product data you give it. Merchant Center hands you
custom_label_0throughcustom_label_4— use one for margin tier. - Automate it nightly. A scheduled job pulls live COGS from your ERP, computes gross margin per SKU, maps it to a tier, and writes
custom_label_0back into the feed. Margins move, so a static label rots. - Split campaigns by tier. High-margin gets an aggressive target, low-margin gets a cap or exclusion. Then read POAS, not ROAS.
Your ad platform is optimizing for the wrong number
Here's the uncomfortable truth about every automated bidding system you run. Performance Max, Advantage+ Shopping, Smart Bidding. They are extremely good at hitting the goal you set, and completely blind to the goal you actually have. You set "maximize conversion value at a 4x ROAS." They do exactly that. But conversion value is revenue, and revenue is not profit.
The AI optimizes conversions and revenue because that's the data flowing into it. It doesn't know your COGS. It doesn't know that one product ships in a $14 box, gets returned a third of the time, and rides on a supplier price that jumped last quarter. It sees a sale for $200 and logs a win. Whether that $200 sale left you $90 or $9 is invisible to the machine, because you never told it[5].
And this is where a lot of operators get stuck. They assume the fix lives inside the ad account — some bid adjustment, some audience tweak, some setting Google buried three menus deep. It doesn't. With Performance Max you can't set a per-SKU bid the way old Shopping campaigns let you. You influence PMax through three levers: the feed, your listing groups and asset groups, and your per-campaign targets. Of those, the feed is the one you fully control and the one the algorithm leans on hardest[5].
So picture the setup this whole article is about. You've got a $30 throw pillow at a 10% margin and a $1,200 sofa at a 45% margin, both sitting in the same PMax campaign under one blended ROAS target. To the algorithm they're interchangeable inventory. To your P&L they could not be more different. Fix that mismatch and you've done more for profit than any bid tweak ever will.
Same ROAS, opposite outcomes
Start with the definitions, because the whole argument hangs on one word. ROAS is revenue divided by ad spend. POAS — Profit on Ad Spend — is gross profit divided by ad spend[1]. Same denominator, completely different numerator. One counts what the customer paid. The other counts what you actually kept after COGS, returns and fees.
Now watch what happens when a single ROAS target sits on top of two very different products. The following is illustrative — the arithmetic is real, the specific SKUs are invented to show the shape.
| SKU | Price | Margin | Ad spend at 4x ROAS | Gross profit | POAS |
|---|---|---|---|---|---|
| Throw pillow | $30 | 10% | $7.50 | $3.00 | 0.4x — loses money |
| Sofa | $1,200 | 45% | $300 | $540 | 1.8x — prints cash |
Illustrative, not measured data. Both products hit the exact same 4x ROAS. One returns 40 cents of profit per ad dollar; the other returns $1.80. A blended target treats them as equals. Mechanic: Ayko[3]; numbers invented.
Same 4x ROAS. Opposite outcomes. The pillow clears a 4x return on paper and still loses you money after costs, because at a 10% margin you'd need far more than 4x just to break even. The sofa at 45% is comfortably profitable at the same target. Feed both into one campaign and the algorithm — steering by revenue — has no reason to prefer the sofa. It might even prefer the pillow, if pillows convert faster.
A blended 4x ROAS is an average, and an average can hide a winner quietly paying the losses of a loser sitting right next to it.
Here's the version that keeps people up at night. Say your account shows a healthy blended 4x. That single number can be a $6-profit winner and a $1.50-profit loser averaged into one comfortable figure (again, illustrative). The dashboard looks fine. The high-margin hero is subsidizing the low-margin dog, and you'd never know from the top-line ROAS[3]. You're scaling both when you should be scaling one and capping the other.
And in 2026 the trap is getting deeper. Practitioners are watching input costs, freight and tariffs squeeze DTC contribution margins across the board[4]. As margins compress, the gap between revenue and profit widens — which means a revenue-based metric like ROAS misleads louder than it did two years ago. The thinner your margins get, the more expensive it is to keep bidding on the wrong number. (Treat that as an industry observation, not a measured law — but it lines up with what most operators are seeing.) If you want the strategic case for why this matters, we've covered how ROAS quietly bankrupts D2C brands and the broader MER vs ROAS trade-off separately. This article is about the plumbing that fixes it.
The fix: tag your feed by margin
The algorithm can only optimize the product data you give it. That single sentence is the whole strategy. If margin isn't in the feed, the machine can't factor it in. So the job is to get margin into the feed in a form it can segment on.
Google Merchant Center gives you five free fields for exactly this kind of thing: custom_label_0 through custom_label_4. A custom label is a tag you attach to each product. It doesn't show to shoppers, and it doesn't affect how your listing looks. Its only job is to let you group and filter your catalog for bidding and reporting[2]. People use them for season, price band, best-seller status, clearance. You're going to spend one of them on margin.
Pick a slot — say custom_label_0 — and populate it with a margin tier:
custom_label_0 = high_margincustom_label_0 = medium_margincustom_label_0 = low_margin
That's it. Once every SKU carries its tier, you can build listing groups and campaigns around those three values and hand each one a different target. The feed is where this belongs — not a spreadsheet, not a bid rule, not a note in your head — because the feed is the input the algorithm reads directly when it decides where your budget goes[2][5]. The same logic applies on the catalog side of paid social, where product sets are built by filtering on catalog attributes rather than per-item bids.
Why not just three separate feeds? You could, but a label on one feed is cheaper to maintain and keeps your source of truth in one place. One product, one row, one margin tag that updates itself. That last part — updates itself — is the whole game, and it's the next section.
The nightly pipeline
A margin label you set by hand is wrong within a week. Supplier prices move. You run a promo. Freight ticks up. A product's return rate creeps. The moment your COGS changes and the label doesn't, you're bidding on a stale number with total confidence. Which is worse than not tagging at all. So the tag has to refresh itself on a schedule. Automatically. Every night.
Automate bad data and all you've done is make the wrong bids faster — with total confidence.
The pipeline is simple in shape. A scheduled job runs overnight and does four things in order:
- Pull. Hit your ERP, warehouse or inventory system and pull the current cost data for every SKU.
- Compute. Calculate live gross margin per SKU: price − COGS − returns/fees. Not last quarter's margin. Tonight's.
- Map. Bucket each SKU into a tier — high / medium / low — against thresholds you set.
- Write. Push the tier into
custom_label_0in the feed that syncs to Merchant Center.
You can wire this three ways depending on your stack. A feed-management tool (Feedonomics, DataFeedWatch, GoDataFeed and the like) can transform a supplemental feed and set the label rule. A script — Python on a cron job, a scheduled cloud function — can do the same if you'd rather own the logic. Or an iPaaS flow (Make, Zapier, n8n) can run the event-compute-write chain without you maintaining a server. The pattern is identical across all three: event fires → margin computed → label written.
Three build details decide whether this actually runs. First, the join key: your ERP export and your feed have to share item_id / SKU, or nothing lines up — this is the single most common place these pipelines break. Second, your thresholds: something like high ≥ 40%, medium 20–40%, low < 20% is a fine place to start, but pull the cutoffs to the shape of your margin distribution, not ours. Third, write to a supplemental feed, not your primary one — a supplemental feed overrides custom_label_0 on matching item_ids without you rebuilding the source feed every night.
custom_label_0 to the supplemental feed.Nightly beats monthly for one concrete reason: the morning after you drop a product to clearance, it falls out of your high-margin campaign on its own. No one has to remember to move it. If you want the deeper build on wiring inventory data into ad accounts, we walk through the full inventory-to-ad-account pipeline elsewhere. And automation like this tends to pay for itself: Nucleus Research pegged marketing automation at $5.44 returned per $1 spent over three years, with payback under six months[6].
Structuring campaigns around the tiers
A labeled feed does nothing on its own. The label is just a hook. Now you hang campaign structure on it, so each margin tier gets a target that fits its economics instead of one blended average that over-invests in low-margin winners-on-paper.
Split by custom_label_0. In practice that means listing groups or separate asset groups / campaigns per tier, each with its own target ROAS or target CPA:
- High-margin (~45%, break-even ~2.2x) — go hungry. Set a target ROAS around 2.5–3x. Low enough to tell the algorithm to buy volume, high enough that every sale still clears real profit.
- Medium-margin (~25%, break-even ~4x) — steady. A target around 4.5–5x keeps them profitable without starving the high-margin push.
- Low-margin (~10%, break-even ~10x) — cap or cut. Cap the target around 11–12x so you're not overspending on thin products, or exclude the ones with nothing left to give.
Illustrative targets. Each number is anchored to break-even ROAS = 1 ÷ gross margin, then nudged up to leave profit headroom — plug in your own margins. The principle holds even when the numbers don't: every tier's target sits a controlled distance above its own break-even, never on a blended average.
Remember the direction of the target. A lower ROAS target tells the algorithm to spend more aggressively; a higher one reins it in. So your high-margin tier gets the lower, hungrier target, and your low-margin tier gets the higher, tighter one. That's the whole reallocation. You're not touching a single bid by hand, you're setting the rules of engagement per tier and letting the machine do the placement.
One pattern a lot of practitioners have settled into, as a rule of thumb rather than a rule: PMax for scale on the bulk of the catalog, plus Standard Shopping kept alive for the two cases where you want tighter control, pushing high-margin heroes and controlling clearance. PMax is a blunt instrument on purpose. Standard Shopping gives you back the manual grip it took away.
Where this goes wrong
This works, but it's unforgiving in four specific ways. Skip these and you'll automate a mistake at scale.
Garbage COGS in, wrong bids out. The entire system runs on your margin data being accurate and current. If your COGS is stale, or it ignores returns and fulfillment fees, you'll tag products into the wrong tier and then bid on that lie with total confidence. A product with a 35% gross margin that gets returned 30% of the time is not a high-margin product. Get returns and fees into the calculation or don't bother.
Give it time to recalibrate. When you change targets, the algorithm needs a learning window to adjust — it doesn't flip overnight. Don't panic on day 3 and rip it all out because the numbers wobbled. Automated bidding rebalances over weeks, not days. Judging it too early is how good structures get killed before they've had a chance to work.
Don't over-segment a thin catalog. Three tiers is usually right. Seven is usually wrong. Every split you make divides your conversion data into smaller pools, and PMax needs volume to learn. Slice a modest catalog into too many campaigns and you starve each one of the signal it needs. If you've got 200 SKUs, three tiers. Save the fine-grained segmentation for when you have the volume to support it.
This fixes allocation, not economics. Margin-based bidding moves budget toward your profitable products. It cannot manufacture profit that isn't there. If a product has no margin after all costs, the honest move is to fix the price, fix the supply cost, or stop advertising it. Not hope the algorithm rescues it. This is a targeting tool, not a turnaround plan.
What to build first
Don't try to do all of this in a weekend. The order matters — get the margin data right before you automate anything, because automating bad data just makes the wrong bids faster.
| # | Step | Why it's first / why it matters |
|---|---|---|
| 1 | Get accurate per-SKU gross margin, including returns and fees. | Everything downstream bids on this. Wrong margin = confidently wrong bids. |
| 2 | Define 3 tiers and add custom_label_0 to the feed. | Three is enough. The label is the hook the whole structure hangs on[2]. |
| 3 | Automate the nightly refresh (feed tool, script, or iPaaS). | Margins move. A static label rots within a week. |
| 4 | Restructure campaigns by tier — aggressive target high, cap/exclude low. | This is where reallocation actually happens. |
| 5 | Give it 2–4 weeks, then read POAS, not ROAS. | Let it learn, then judge it on profit per dollar — the number you were trying to fix[1]. |
Build order. Data first, automation second, structure third, patience last. Source: Polar Analytics[1].
The mechanism is boring and that's the point. There's no growth hack here: just accurate margin data, a free feed field, a nightly job, and campaign structure that respects the difference between a pillow and a sofa. Do that and the algorithm you already run starts hunting profit on its own.
FAQ
Sources
- Skale Strategy — Profit on Ad Spend for Google Ads (POAS = Gross Profit ÷ Ad Spend). skalestrategy.com; Polar Analytics — POAS: Profit on Ad Spend. polaranalytics.com
- Google Merchant Center Help — Custom label [custom_label_0..4]. support.google.com; 85SIXTY — Using custom labels to subdivide products. 85sixty.com
- Ayko — POAS bidding and why it outperforms ROAS for e-commerce growth (margin-variance illustration, industry). ayko.com; JudeLuxe — POAS vs MER vs ROAS. judeluxe.com
- Pigeon Digital — Tariff Math for DTC: When a COGS Spike Quietly Shrinks Your Q4 Ad Budget, 2026 (margin compression from tariffs/freight, industry observation). pigeondigital.com
- Store Growers — Performance Max campaigns guide (the feed as the highest-leverage lever, industry). storegrowers.com; 85SIXTY — Custom labels. 85sixty.com
- Nucleus Research (V61, 2021) — Marketing automation returns $5.44 for every dollar spent, payback under six months. nucleusresearch.com