An order comes in on Tuesday. Meta counts it as a conversion instantly. Your dashboard shows revenue the moment the checkout completes. But for a meaningful share of e-commerce orders, especially apparel, footwear, and anything sized or fit-dependent, that "sale" isn't final. It's provisional, pending a return window that, in most stores, runs 15 to 30 days.

This creates a specific, structural blind spot: every real-time ROAS number you look at is an optimistic snapshot, because it's calculated before the return data exists yet.

The mechanics of the lag

Here's the sequence that actually plays out for a lot of stores:

  1. Monday: a campaign shows a strong reported ROAS based on this week's attributed revenue.
  2. Based on that number, budget gets increased 20–30% to "double down" on what's working.
  3. Over the following 2–4 weeks, returns tied to those same orders come back in, but they land in a different reporting period, disconnected from the campaign decision that drove them.
  4. By the time the true return rate on that cohort is visible, the budget decision is weeks old and effectively unreviewable in the ad platform's own interface.

The ad platform isn't wrong, exactly; it's reporting what it can see at the moment it's asked. It just can't see forward 30 days. Nothing in Meta or Google's own dashboard is built to.

// The compounding version of this problem

Scaling a campaign on a return-inflated ROAS doesn't just waste this week's incremental spend. It repeats the same optimistic estimate at a larger budget the following week, since the algorithm and the operator are both optimizing against the same lagging number.

Why you can't just "wait 30 days" to make decisions

The obvious fix, waiting a full return cycle before evaluating any campaign, isn't realistic. Ad accounts move too fast, and a genuinely underperforming campaign left alone for a month can burn a lot of budget in the meantime. The useful fix isn't waiting; it's disclosure: knowing which decisions are being made on data that's still likely to shift, and by roughly how much, so a 91%-confidence pause recommendation and a 60%-confidence one aren't treated the same way.

What a return-rate-adjusted view actually looks like

In practice, this means three things layered on top of the raw ROAS number:

  • A rolling, SKU-level return rate pulled from store order data (Shopify or WooCommerce), not a single blended store average.
  • An explicit lag disclosure on any decision where return data is still incomplete, stated in plain terms, not buried in a footnote.
  • A conservative adjustment applied to the true ROAS estimate for recent cohorts, rather than treating week-one data as final.
30dTypical return window used for the adjustment
±Confidence range disclosed on any decision touched by return lag
30%Max budget change allowed per decision, regardless of confidence

Why the 30% cap matters here specifically

This is also the argument for a hard ceiling on how much a single decision can move a budget, even when the recommendation looks confident. Return data, by nature, is never fully final at the moment a Monday report goes out; some later cohort correction is always possible. Capping the maximum swing per approved decision at 30%, with a 24-hour rollback window on anything executed, means a decision that turns out to be based on data that shifted afterward is never catastrophic, and it's always reversible.

The goal isn't to eliminate uncertainty. Return-rate uncertainty is a structural feature of e-commerce, not a bug to be engineered away. The goal is to make the uncertainty visible and bounded, instead of invisible and unbounded, which is the default state of a real-time ROAS dashboard.

Stop making budget calls on data that isn't final yet.

See what your campaigns look like once return-rate lag is factored in and disclosed, with your real numbers.

Get your report →