All articles
Automation5 min read

Out of stock size variants in Meta ads

Out of stock size variants keep serving Meta ads because availability is a per-variant field while your rules run on the item group. Here is the tell.

A denim catalog set had been drifting for about two weeks. Conversion rate down, impressions flat, CTR sitting exactly where it had sat all quarter. I went through the creative, the audience overlap, the frequency. All boring.

Then I clicked my own ad. The product page loaded, the photography looked great, and most of the size selector was greyed out. What was left was one size at each end of the curve.

Short answer: Out of stock size variants keep serving because availability sits on each variant row in your feed, while your reporting, product sets and ad rules all work at the item group or ad level. One leftover size in a long tail keeps the whole product eligible, so spend continues and nothing in Ads Manager looks wrong.

The takeaways

  • availability is a per-item field with two accepted values, in stock and out of stock. Each variant row carries its own; the group has none to set.
  • Plenty of feed integrations write one product-level stock status onto every child row, so a group with a single size left reports as fully sellable.
  • The signature is conversion rate sliding while impressions, CTR and the availability flag hold steady. No ad-metric rule fires, because nothing about the ad changed.

Why does an ad keep running when the sizes people buy are gone?

Because the product is still sellable, technically. A jeans style in eight sizes is eight rows in your feed tied together by item_group_id, which Meta's catalog reference describes as the way to "set up variants of the same product, such as different sizes, colors or patterns". Sell out the middle of the size curve and the group still holds something a shopper could theoretically buy, so the product stays eligible and delivery carries on.

That is the group doing its job, on a size almost nobody wants. What changes is the click. The ad promises a product, the landing page hands over a size chart with most of it disabled, and the shopper leaves. You paid full CPM for a visit that had no path to a purchase.

Where does availability actually live?

On the variant row. Meta's catalog reference defines availability as "the current availability of the item" and accepts two values, in stock and out of stock. Every row gets its own value. There is no group-level availability field, which is the detail people miss when they picture a catalog as a list of products rather than a list of buyable items.

So the real question is whether your integration writes that field per variant. Many feed setups map a single product-level stock status onto every child row, and once it is wired that way, a group with one size left will report as fully sellable indefinitely. Nothing errors. A valid value sits on every line, which is exactly what makes it hard to catch. Before you trust the feed, check three variants you know are sold out in Commerce Manager.

Why do product set rules not fix this?

They help, then they stop short. A product set built on availability drops the individual rows that say out of stock, so those variants stop rendering. What it will not do is take a decision about the group. If one row still says in stock, the product stays in the set and keeps spending.

That is the mismatch. The rule you want is something like "stop this product once the sizes that carry its sales are gone", and there is no field to write it against, because size mix is commercial knowledge that no catalog attribute holds. The workable fix lives upstream: have your feed integration flag the whole group as out of stock once the core sizes are gone, instead of asking the ad platform to infer it. Put the logic where the stock data already is.

What does this look like in the numbers?

A slow decline with nothing to blame. Impressions steady, CTR steady, CPM steady, the availability flag green, and conversion rate giving up ground week after week. Every metric you can see describes the ad, and the ad did not change. What changed sits on the other side of the click.

Worth memorising, because it rules things out. Creative fatigue usually shows in the click first: CTR erodes, then conversion follows. When conversion moves alone and the top of the funnel is flat, the cause sits downstream of the click, and stock is where I look first. Pull spend by product for the week, take the five biggest spenders, open their pages and check the size selector.

How is this different from a product that sold out completely?

It is quieter, and it lasts longer. A full stockout is at least a state your feed can express and your dashboards will eventually show. The damage there comes from sync lag, which I went through in out of stock products in catalog ads, and raising the pull frequency shrinks it a lot.

A partial stockout never resolves on its own. The feed is not lagging; it is accurately describing a group that still holds something buyable, month after month, while the sizes that made the product work are gone. Faster syncs do nothing for it. The product also reads as an ordinary underperformer in any spend report, which is why writing a rule against it is so awkward: the rule builder stops at ad level and never reaches a variant.

What can you automate, and what stays yours?

The ad-account half. Adscalr's rules fire on 8 metrics (CPI, CTR, hook rate, hold rate, ROAS, spend, frequency, CPM), the only actions are pause and kill, every evaluation is logged, and a kill stays reversible for 30 minutes. There are 11 alert event types plus a role-based morning brief in your own timezone, so a spend line drifting the wrong way reaches you the same week instead of at month end.

None of that looks at stock. Adscalr reads ad performance and has no view of your feed, your catalog or your product sets, so it cannot tell a hollowed-out size curve from a tired creative. What it can do is flag the money leaving faster than the results, early enough to be worth acting on. Automation and alerts covers the spend guardrail. The size curve stays a job for your shop integration, which is where it belongs.

This is the thinking behind Adscalr.

See the product