Meta ads ROAS overreports and underreports at the same time, for different reasons. Here is what breaks the number, how attribution settings change it, and how to check yours against the only figure that pays the bills.
Return on ad spend looks like a fact. It is a calculation, and both halves of it are estimates. The spend figure is solid. The revenue figure is assembled from events your website sent, filtered through an attribution model, inside a window you probably never chose. Change any one of those and the number changes without a single thing happening in the market.
That matters because ROAS is the number people cut budgets on. We have seen campaigns killed on a reported ROAS that was understated by broken tracking, and campaigns scaled on a reported ROAS that was inflated by duplicate events. In both cases the dashboard was read correctly. The dashboard was reading the site incorrectly.
This guide is the supporting piece to our Meta pixel audit guide. Start here if the number looks wrong. Start there if you want the full tracking checklist.
Broken measurement is not one problem. It is two problems that push in opposite directions, and most accounts have some of each running at the same time. That is why a gut check like "my ROAS feels too high" is useless on its own. You have to know which failure you are looking at.
Duplicate events. The most common cause of inflated revenue. When a store sends a Purchase from the browser pixel and a second Purchase from the Conversions API, both events need a shared eventID so Meta can recognize them as one order. Without it, one sale is counted twice, and reported revenue roughly doubles on every affected order. The same thing happens when two pixels are installed, when a Shopify app and a manual theme snippet both fire, or when a Purchase sits on a thank-you page that customers reload.
View-through attribution. Meta's default setting credits conversions from people who saw the ad without clicking it, inside a 1-day window. Some of those buyers were coming anyway. That is not a bug, it is a modeling choice, and it means Meta's ROAS is structurally higher than a click-only view of the world.
Missing deduplication after a migration. Server-side tagging setups that worked fine can start double counting after a checkout change, a new app, or a theme update that alters where the event ID comes from. Nothing looks broken. Revenue just quietly runs high.
Blocked pixels. Ad blockers, browser tracking protection, and privacy extensions stop the browser pixel from loading for a meaningful share of visitors. Their purchases still happen. Meta never hears about them. Browser-only tracking loses the most here, which is one of the reasons we treat pixel plus Conversions API as the baseline rather than an upgrade.
iOS signal loss. App Tracking Transparency limits what Meta can observe on iOS devices. If your customers skew toward iPhones, Ads Manager will consistently show fewer conversions than your store does, and the gap widens as the tracking setup gets weaker.
Missing parameters. A Purchase event that fires without a value or currency parameter still counts as a conversion but contributes nothing to revenue. Your purchase count looks right, your ROAS looks terrible, and the two numbers disagree in a way that is easy to miss.
Consent gates. A consent management platform that blocks tracking until opt-in means every visitor who ignores the banner is invisible. Consent design is a legal decision, not a marketing one, but you should at least know how much of your traffic it removes from reporting.
Two people can pull the same campaign, the same dates, and get different ROAS. The attribution setting is why.
Meta's default is 7-day click and 1-day view. A conversion counts if the person clicked the ad within 7 days of buying, or saw it within 1 day. Switch the column to 1-day click only, and every view-through conversion plus every delayed click conversion drops off. Reported ROAS falls, sometimes by a lot, and nothing about the campaign changed. The setting is per column in Ads Manager, so it is entirely possible to compare two numbers built on different rules without noticing.
Meta versus GA4. These will never match, and chasing agreement is wasted time. Meta uses its own view-through and click attribution across its platforms. GA4 uses session-based channel attribution and gives no credit at all for an ad someone saw but did not click, which usually lands that order in direct or organic instead. Both are describing the same purchase with different rules.
Meta versus blended MER. Marketing efficiency ratio is total revenue divided by total ad spend, taken from your backend. It cannot be gamed by attribution because it does not attribute anything. It also cannot tell you which ad worked.
Each number has one job. Blended MER tells you whether the business is working. Meta's ROAS tells you which ads and audiences to compare against each other inside Meta. GA4 tells you what on-site behavior looks like by channel. Use platform ROAS for relative decisions and backend revenue for absolute ones. Our conversion drop diagnostic uses the same split when it separates a real performance drop from a reporting gap.
Plenty of tracking problems affect optimization without touching the revenue figure. These three hit ROAS directly.
Duplicate Purchase events inflating revenue. Worth repeating because it is the single most expensive one. Duplicates do not just inflate the report, they feed a distorted signal back into optimization, so Meta learns from orders that never existed. Deduplication depends on the browser event and the server event carrying the same event ID and the same event name. Our free Meta pixel audit checks whether conversion events carry deduplication keys at all, and flags server-side setups running without one.
Missing value and currency parameters. A Purchase with no value contributes zero to revenue. A Purchase with a value but no currency can be misread. Lead events with no value make lead-gen ROAS meaningless from the start, since every lead is worth the same nothing. On Shopify this often shows up after a theme or app change, which is why a Shopify pixel audit is worth running after any checkout work.
Events firing on the wrong pages. A Purchase on the cart page instead of the confirmation page counts intent as revenue. A Purchase in a global script fires on every page load. A thank-you page reachable by refresh or back button counts the same order repeatedly. In each case the event fires perfectly, which is exactly why nobody catches it: Events Manager shows the Purchase event arriving on schedule, doing the wrong thing.
Four checks, in order. None of them require a developer.
If your reported ROAS and your backend numbers tell different stories, believe the backend. If they agree, you can start trusting the platform number for the comparisons it is good at. To find out whether your costs are normal for your category, our Meta ads ROAS benchmarks page cites public sources rather than our own accounts.
Every optimization decision you make sits on top of the conversion data your site sends. Pausing a campaign, reallocating budget, killing a creative, raising a target: all of it assumes the revenue number is real. When it is not, you are optimizing toward a fiction, and so is Meta.
So fix the measurement before you touch the budget. Confirm the Purchase event fires once, on the right page, with value and currency attached. Confirm the Conversions API is live and deduplicated against the browser event. Confirm you know which attribution setting your reports use. Then make the call.
The fastest way to see where you stand is our free Meta pixel audit. Paste your URL and it scans your live site: whether a pixel is present and loading in the head, whether Purchase carries value and currency, whether conversion events carry deduplication keys, whether a Conversions API pipeline appears to exist, what is inside your GTM container, and whether your consent stack blocks tracking. It takes about 20 seconds, needs no login and no pixel ID, and it marks anything it cannot verify from outside as needing a manual check rather than guessing, which is spelled out in the full methodology. Run it before your next budget decision.
Usually duplication or attribution, sometimes both. Duplication happens when the same order fires a browser Purchase and a Conversions API Purchase without a shared event ID, so Meta counts it twice. It also happens when a Purchase event sits on a thank-you page that buyers reload or return to. Attribution adds a second gap: Meta credits a conversion to the ad even when the buyer converted days later or after only seeing the ad, which your store's last-click reporting never credits to Meta at all. Check deduplication in Events Manager first, because that is the one that is genuinely broken. Our free pixel audit flags conversion events running without deduplication keys.
An overnight change in ROAS is almost always the data, not the market. The common causes are a site change that stopped the Purchase event from firing, a Conversions API token that expired, a consent banner update that now blocks tracking before opt-in, and a change to the attribution setting or the date range on the report you are reading. Compare Meta's purchase count to your backend orders for the same days. If the store is fine and Meta is not, you have a measurement break, not a performance break. The conversion drop diagnostic walks through the rest of the causes.
Neither on its own, and they are not supposed to agree. Meta reports on its own attribution model, which includes view-through conversions and a 7-day click window by default. GA4 reports on its own session and channel model, which gives no credit to a view and often assigns the order to direct or organic. Use your backend order data as the source of truth for revenue, use blended MER for the business decision, and use Meta's numbers to compare ads inside Meta.
It depends entirely on your contribution margin, so there is no universal number. Breakeven ROAS is 1 divided by your margin: a 40% margin breaks even at 2.5, a 25% margin breaks even at 4.0. A 3.0 ROAS is excellent for one business and a loss for another. Calculate your own with the breakeven ROAS calculator, set a target above it based on the profit you want, and use our Meta ads ROAS benchmarks only to check whether your costs look normal for your category.
It closes part of the gap, and it can make things worse if it is installed carelessly. A server-side Purchase event survives browser blocking and ad blockers, so it recovers conversions the pixel alone misses, and stronger customer information improves event match quality. But a Conversions API event sent without a shared event ID that matches the browser event gets counted as a second purchase, which inflates revenue and ROAS. Send both, deduplicate both, then verify in Events Manager. The pixel versus Conversions API guide covers how the two are meant to work together.
Before you move another dollar of budget, check whether the number you are moving it on is real. The audit scans your live site for the failures that corrupt ROAS: missing values, duplicate events, browser-only tracking, and consent gates.