GuideUpdated 2026-07-06

Inventory and availability sync

How Shopify inventory and inventory policy map to Google's availability attribute, how often it should refresh, and how to avoid the availability-mismatch disapprovals that waste ad spend on unbuyable clicks.

Plain-English summary

Google's availability attribute tells shoppers, and Google, whether a product is in stock. It's built from two Shopify signals: the variant's inventory quantity and its inventory policy (whether it keeps selling at zero). Get the mapping or the refresh cadence wrong and you either pay for clicks on sold-out products or hide stock you could sell. This guide covers the mapping, the cadence, and the mismatches that cause disapprovals.

The availability attribute, and its two Shopify inputs

Google's availability attribute takes a small set of values: the two that matter for most Shopify stores are in_stock and out_of_stock (with backorder and preorder for specific cases). Shopify doesn't have a single "availability" field. It's derived from two signals per variant:

Shopify signal What it is
Inventory quantity The tracked stock count for the variant
Inventory policy "Stop selling when out of stock" (deny) or "Continue selling when out of stock" (continue)

The logic that maps them to Google:

  • Quantity > 0in_stock.
  • Quantity = 0, policy = "stop selling"out_of_stock.
  • Quantity = 0, policy = "continue selling" → still in_stock (the store will still take the order). This is the one that surprises people: see below.
  • Inventory not tracked → treated as always available, so it maps to in_stock regardless of count.

Because this is a per-variant calculation, it's another reason variants must be sent as their own offers (see variants and item_group_id): the sold-out size 10 goes out_of_stock while the size 12 keeps serving. Product-level availability can't express that: it either wastes spend advertising the sold-out size or hides the size that's in stock.

Refresh cadence: the gap that costs money

Availability is the most time-sensitive attribute in the whole feed. A title can be stale for a week and cost you nothing; an availability value that's an hour behind means an hour of paid clicks on a product nobody can buy.

Two things set your real cadence:

  1. How often the feed re-reads Shopify inventory. A feed that only rebuilds nightly is up to 24 hours behind on every stock change.
  2. How often Merchant Center refetches the feed. Even a fresh feed only helps once Google pulls it.

The goal is availability that tracks Shopify as closely as the pipeline allows: and never a full day behind. Fast-moving stores (limited stock, flash launches, single-item vintage) feel this hardest: a one-of-a-kind item that sold an hour ago should not still be advertised as available.

Out-of-stock handling

When a variant sells out, what should happen depends on whether it's coming back:

  • Restocking soon → let it go out_of_stock in the feed and come back to in_stock on restock. Keeping the offer in the feed (rather than deleting it) preserves its history so it doesn't restart from cold.
  • Gone for good → remove or unpublish it so it drops from the feed cleanly, rather than leaving a permanently out-of-stock offer.
  • "Continue selling" backorders → if you genuinely fulfil at zero stock, in_stock is honest; if the page then tells shoppers "sold out" or "ships in 6 weeks" without setting expectations, you've created a mismatch. Use backorder/preorder semantics where they fit, and make the landing page say the same thing.
Deep dive The "continue selling" trap and availability-mismatch disapprovals

The most common availability disapproval on Shopify stores comes from a setting that feels harmless: "Continue selling when out of stock."

Here's the chain. You set a variant to keep selling at zero stock: maybe for a made-to-order line, maybe left on by default. Inventory hits zero. Per the mapping above, the feed still reports in_stock, because Shopify will still accept the order. So far, consistent.

The trap springs when the landing page tells a different story. Perhaps a theme setting or an app shows a "Sold out" button at zero stock even though the policy is "continue selling". Now Google's crawler visits the page, sees "Sold out", compares it to the feed's in_stock claim, and disapproves the product for an availability mismatch. Your feed was internally correct; the page disagreed with it, and Google sides with the page.

It also runs the other way: a page that shows "Add to cart" while the feed says out_of_stock is the same mismatch class. And availability mismatches often travel with price mismatches: the crawler checks both on the same visit, so a store with sloppy sync tends to collect both disapproval types together.

The durable fixes:

  1. Make the feed's availability logic mirror what the page actually shows a shopper, not just what the inventory policy technically permits. If the page says sold out, the feed should say out_of_stock, regardless of policy.
  2. Decide "continue selling" deliberately. It's right for genuine made-to-order and backorder lines; it's a liability when left on by accident for normally-stocked products.
  3. Keep the refresh tight so the window where feed and page can disagree is measured in minutes, not hours.

/tools reads per-variant quantity and inventory policy on each sync, maps availability with the "continue selling" nuance handled, and flags availability/price consistency risks in the Feed Health Score before Google's crawler finds them: catching the mismatch pre-emptively rather than after impressions are lost. As with everything in the enriched feed, this reads Shopify and never writes back, so your inventory settings stay exactly as you configured them. For disapprovals already showing, see fixing disapproved products.

Checklist

  • Availability is derived per variant, not per product.
  • "Continue selling when out of stock" variants are deliberate, and their landing pages agree with the in_stock claim.
  • The feed re-reads inventory frequently and is never a full day behind Shopify.
  • Sold-out-but-restocking items stay in the feed as out_of_stock; discontinued items are removed.
  • Landing pages and the feed tell the shopper the same stock story.

Frequently asked questions

How does Shopify decide if a product is in stock for Google?

From the variant's inventory quantity and its inventory policy together. Quantity above zero is in stock. At zero, it depends on the policy, "continue selling when out of stock" reports as in stock, "stop selling" reports as out of stock.

How fast should availability refresh?

As close to real time as your pipeline allows, and no slower than a few times a day. The risk is the window between selling out in Shopify and the feed telling Google, every hour of lag is ad spend on clicks that can't convert.

Why is a product disapproved for availability when it's in stock?

Google's crawler visited the landing page and saw something different from what the feed claimed, a "sold out" button, or a price that didn't match. The feed and the page have to agree; a mismatch triggers the disapproval even when your intent was fine.

Put this into practice. /tools rebuilds messy product data into Merchant Center-ready feeds. Connect a store and see your Feed Health Score in minutes.
Try /tools →