One morning the product count in Merchant Center is lower than it was. No suspension, no disapproval, no policy email — the items are just gone, and the ones still there are the ones you edited recently. Nobody changed anything, which is exactly why this one is hard to find: products in Merchant Center have a shelf life, and when nothing refreshes them, they fall off it.
The rule, exactly as Google writes it
All products expire from a Merchant Center account 30 days after their last refresh. Products added by hand inside Merchant Center are the exception — those don't expire (Manage products in your Merchant Center account).
The clock runs per product, not per account. That is why a catalogue doesn't vanish in one night: it drains. The items you touched most recently survive longest, so what you see is a slow decline that looks like falling demand rather than a mechanical expiry.
What actually counts as a refresh
Re-submitting the data source. A scheduled fetch that runs and succeeds refreshes every product in the file. This is the normal answer, and the reason feeds are usually set to fetch daily rather than monthly.
A crawl of your product pages. Google also re-checks your website and can refresh products automatically when the data validates — for instance from schema.org structured data on the landing page. It is a safety net, not a plan: it depends on your markup being correct and on Google choosing to crawl.
What does not count: opening the feed in a browser, editing products in your store without the feed being re-read, or a fetch that Google attempted and failed. Which leads to the most common cause of all.
The usual cause: the refresh stopped, not the products
Expiry is rarely the root problem. It is the visible end of a fetch that quietly stopped working weeks earlier — a feed URL that started redirecting, a file behind a login, a fetch that fails for one of the documented reasons, or a feed that downloads perfectly and arrives with nothing in it. In every one of those cases the products already in the account keep serving for up to 30 days, so the failure and the symptom are a month apart.
That gap is the whole difficulty. By the time products expire, the change that caused it is off the end of anybody's memory — a plugin update, a new cache, a migrated URL.
The attribute that expires products early on purpose
expiration_date sets a date for a product to leave the account — useful for a limited run or a seasonal listing. One thing to know before you use it: a product expires on that date or 30 days after its last refresh, whichever comes first. The attribute can pull expiry closer, never push it further out.
So if a feed carries an expiration_date copied from somewhere — a template, an old export, a plugin default — it can quietly shorten the life of every product in it. Worth checking before you assume the fetch is at fault.
How to confirm it in two minutes
In Merchant Center, open Products and look for items marked expiring or expired, then open the data source and read the last fetch timestamp and result. Two signatures tell the story apart:
Last successful fetch is old — the refresh stopped. Fix the fetch, and the products come back on the next successful run; you don't need to rebuild anything.
Fetch is running fine, products still expire — look at the file itself. Either the expiring products are no longer in it (a filter, an out-of-stock rule, a plugin limit dropping rows), or the feed carries an expiration_date you didn't intend.
If the product count in the account looks right but nothing is showing in Shopping, that's a different failure — work through the four-step diagnostic instead.
Stopping the drain for good
Fetch daily, not weekly. A daily schedule leaves 29 days of margin: a few failed runs never reach the expiry threshold. A weekly one leaves four attempts before products start dropping.
Watch the fetch, not the catalogue. The thing worth an alert is a failed or skipped fetch, because it happens 30 days before the damage.
Keep prices and availability honest in the same file. Products refreshed with wrong data survive expiry only to be disapproved for a price mismatch instead.
How FeedRobin avoids it
FeedRobin builds the feed when the channel asks for it, so every fetch reads the catalogue as it is right now — each fetch is a refresh, and there is no exported file sitting somewhere getting older than the products it describes. Nothing to re-upload, nothing to schedule, and no 30-day cliff to stay ahead of. If a feed of yours has already thinned out, the free feed check reads the URL the way Google does and tells you what it finds — including the empty and HTML responses that stop a refresh in the first place.
Sources
Google Merchant Center Help: Manage products in your Merchant Center account (the 30-day expiry, what refreshes a product, the manual-entry exception) and Expiration date [expiration_date] (the attribute, and the whichever-comes-first rule).