At a glance
Return on ad spend, the headline efficiency number for Meta. action_values[purchase] ÷ spend. A 4× ROAS means £1 of Meta spend produced £4 of Meta-attributed purchase value. Below 2× is unprofitable for most DTC margins after COGS, fulfilment, and overhead. Caveat: post-iOS 14.5, Meta’s claimed ROAS over-states by 30, 80% versus commerce-platform truth without Conversions API.
| The formula | action_values[action_type='purchase'] ÷ spend, both pulled from the Meta Marketing API Insights endpoint at account level. The result is a unitless multiple. |
| Insights API level | Account-level. Per-campaign / per-adset / per-ad ROAS rolls up to this card weighted by spend. |
| What “spend” means | Gross media cost in account currency, before agency markup. |
| What “purchase value” means | Meta-attributed revenue (action_values for purchase event). NOT order revenue from the commerce platform. Includes Pixel-confirmed conversions, CAPI events, and modeled conversions Meta auto-fills. See Reconcile section for why this differs from Shopify or BigCommerce. |
| Attribution model | 7-day click + 1-day view (post-iOS 14.5 default). Was 28-day click + 1-day view pre-iOS-14.5. Configurable per ad account. Switching back to 28d/1d (where eligible) lifts ROAS 5, 15% but Meta has flagged this as a deprecating option. |
| iOS 14.5+ ATT impact | Major and structural. Without Conversions API, expect Meta-reported ROAS to over-state by 30, 80% on iOS-heavy audiences. With CAPI live, gap narrows to 10, 30%. The card cannot correct for this; it reports what Meta reports. |
| CAPI vs Pixel-only | Pixel-only: ATT-blocked iOS conversions are missing → ROAS under-states (real ROAS higher than card). Meta then auto-fills with modeled conversions → ROAS over-states (modeled ≠ real). Net effect: noisy and slightly inflated. CAPI live: tighter, less modeled fill, more reliable. |
| Conversions vs all-conversions | Click-attributed purchase only. “All Conversions” view (which includes view-through and offline) is a separate metric. |
| View-through conversions | Excluded from the primary action_values used here. View-through is only counted in 1-day view + 7-day click attributed events that touched a click; pure view-only conversions are separate. |
| Frequency cap relevance | High frequency (>5 in 7d) compresses ROAS by exhausting the audience. The card doesn’t filter by frequency, but a falling ROAS alongside high frequency is the creative-fatigue signature. |
| Currency | Account currency. Single-currency per account. |
| Time window | 30D vsP (default 30D vs prior 30D). 1, 4 hour ingest lag on today. |
| Alert trigger | <2 (warn), <1 (critical). Below 2× is unprofitable for most DTC margins; below 1× is bleeding cash. |
| Roles | owner, marketing, finance |
Calculation
Calculated automatically from your Meta Ads (Facebook) data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.Worked example
A US homeware brand running Meta on a 7d/1d attribution window. The 30-day window is 02 Apr 26 to 01 May 26. Account currency USD. CAPI is live (rolled out 12 Mar 26).| Campaign | Spend ($) | Purchase value ($) | Per-campaign ROAS | iOS share |
|---|---|---|---|---|
| Advantage+ Shopping (cold) | 22,400 | 78,400 | 3.50× | 64% |
| Advantage+ Shopping (returning) | 8,200 | 51,800 | 6.32× | 61% |
| Manual broad audience | 4,600 | 9,800 | 2.13× | 67% |
| Lookalike 1% (purchasers) | 3,800 | 14,600 | 3.84× | 60% |
| Account total (this card) | $39,000 | $154,600 | 3.97× | 63% |
- The headline 3.97× is honest by Meta’s measurement, but the business ROAS is closer to 1.2, 1.6×. Real Meta-driven Shopify revenue (a probabilistic blend of UTM truth and modeled lift) is probably 154k. Divide that by spend: 1.3, 1.7×. Don’t quote 3.97× to the CFO without the gap caveat.
- Returning-audience Advantage+ at 6.32× is misleading. Returning customers were going to come back anyway; you’re paying Meta to defend revenue you’d capture for free via email or organic. Same dynamic as Branded Search on Google Ads. The “true acquisition” ROAS is closer to the cold-audience number (3.50×, or 1.4× on the Shopify-truth basis).
- iOS share is 63% on this account, structurally high. That makes the iOS gap especially material. The CAPI rollout in March helped (the gap was probably 50, 70% before; it’s down to 25, 35% now). Without CAPI, the headline ROAS would read closer to 5×, even more inflated.
- Modeled conversions are running at 11% of
action_valuesthis period. Reasonable, indicates CAPI is working (modeled fill dropped from ~22% pre-CAPI). If you see modeled fill >25% on a CAPI-live account, the implementation has gaps; checkevent_iddeduplication and CAPI event coverage. - The 30-day prior window had ROAS 4.21×, slight decline. Spend up 8%, ROAS down 6%. That’s mild scaling pressure, fine for now. If next 30 days shows ROAS down a further 10%+ alongside spend up, hit the brakes; you’re scaling beyond the efficient frontier. Plan a creative refresh in 7, 14 days (frequency on the cold Advantage+ campaign hit 4.7 last week).
- ROAS up + spend up = healthy scaling, expand budget if pacing allows.
- ROAS flat + spend down = budget cut without channel deterioration. Channel is still healthy.
- ROAS up + spend down = pulled back wisely from low-quality inventory; can scale back when audience refreshes.
- ROAS down + spend up = scaling beyond efficient frontier. Cap budget, refresh creative, audit Advantage+ output.
- ROAS down + spend flat = something changed in attribution, conversions, or competitive landscape. Investigate before cutting. Check Conversions Trend and Clicks vs Conversions first.
Sibling cards merchants should reference together
| Card | Why pair it with ROAS | What the combination tells you |
|---|---|---|
| Total Spend | The denominator. ROAS up + spend up is healthy scaling; ROAS up + spend down is just a retreat. | The shape of growth. |
| Total Revenue | The numerator. Tells you whether ROAS moved on cost-side or revenue-side. | If ROAS dropped because revenue cratered (not spend rising), the issue is on the conversion path. |
| ROAS Trend | Daily series. ROAS is volatile day-to-day; the 7-day rolling is the actionable read. | Detect the shape of decline (gradual creative fatigue vs sudden tracking break). |
| Clicks vs Conversions | The broken-tracking canary. Clicks up + conversions flat = tag-fire failure. | ROAS will look like it dropped, but the cause is measurement. Don’t cut spend on a measurement bug. |
| CTR Trend | Click-through rate. CTR drops typically precede ROAS drops by 1, 2 weeks (creative fatigue). | Early-warning shape for ROAS deterioration. |
| GA4 Revenue by Channel | Independent attribution check on Meta’s self-reported action_values. | Meta usually reports 30, 80% higher than GA4. The ratio is your iOS gap. |
| Shopify Total Revenue | The truth side. Real business ROAS = (Shopify revenue × Meta channel share) ÷ Meta spend. | If your business ROAS is 1.3× and Meta-claimed ROAS is 4×, that’s a 3× over-claim, normal post-iOS without CAPI. |
| Google Ads ROAS | Paid-acquisition peer on a different platform. | Different ecosystems, comparable benchmark. Google ROAS is typically tighter (less attribution gap). |
Reconciling against the vendor’s own dashboard
Where to look in Meta Ads Manager: Meta Ads Manager → Campaigns → Columns → “Purchase ROAS (return on ad spend)”. This is the column Meta itself surfaces as the headline efficiency reading. Match the date range to this card’s window and the footer total should reconcile to within sub-percent rounding. Other Ads Manager columns that look similar but aren’t:- Mobile App ROAS: app-purchase ROAS via SDK; separate ecosystem from web. Not in this card.
- Outbound CTR: clicks that left Meta vs clicks within Meta. Not ROAS.
- Conversion Lift / Brand Lift: Meta-run incrementality studies, separate methodology.
| Reason | Direction | Why |
|---|---|---|
| Time zone | Boundary days off | Meta uses ad-account time zone (immutable). This card uses UTC. For a 30-day window the gap averages out; for “today” or “yesterday” it can shift the number meaningfully on US Pacific accounts. |
| Attribution window changes | Direction depends | Default reset from 28d/1d to 7d/1d after iOS 14.5. If your account changed mid-window, Meta retroactively reflows the data; this card matches whatever you’ve configured. A 28d→7d window switch typically drops ROAS 5, 15%. |
| Modeled conversions inclusion | Ours matches Meta UI | Meta blends modeled conversions into action_values; this card reads the same blended field. Both inflate by the same modeled-share. |
| Ingest lag | Lower for “today” | 1, 4 hour ingest lag on Insights. Today’s ROAS reads low until catchup. Yesterday and earlier are stable. |
| Advantage+ opacity | None on the headline | Advantage+ aggregates audience and placement breakdowns invisibly; the headline ROAS reconciles. |
| Card | Expected relationship | What causes legitimate divergence |
|---|---|---|
google_analytics.ga_revenue_by_channel | GA4 Paid Social revenue ÷ Meta spend ≈ this card × 0.5, 0.75 | Meta uses last-click within 7d/1d; GA4 uses last-non-direct click. Meta typically wins more clicks because of the wider attribution window and pixel-fired-on-impression-of-link. Meta inflates by 30, 80% versus GA4 structurally. |
shopify.total_revenue | (Meta action_values) is a subset of Shopify total revenue but Meta-attributed Shopify revenue (UTM-tagged) is much smaller than Meta claims. Meta typically claims 1.5, 2.5× the UTM-truth Shopify number due to iOS gap. | The “true” business ROAS sits between Meta’s claim and Shopify’s UTM count. Use a weighted blend (commonly 40/60 Meta/Shopify) for the CFO read. |
google_ads.gads_roas | Independent paid channel. Comparable benchmark. | Different ecosystem, no overlap. Google’s ROAS is structurally tighter because Google Search has less iOS impact (search is intent-driven, mostly desktop and Android). |
Known limitations / merchant FAQs
Why does Meta say I’m at 15× ROAS but Shopify says I’m at 3× ROAS? The single most common Meta question. Three layers stack:- Different denominator definitions. Meta’s ROAS uses
action_values[purchase]= Meta-claimed revenue including modeled conversions and 7d-click + 1d-view attribution. Shopify’s “Meta-source revenue” uses UTM-tagged orders only. The two are measuring different sets of orders. - iOS 14.5 ATT. Even on the same orders, Meta has Pixel + CAPI + modeling; Shopify has only what’s tagged with the right UTM. iOS users without ATT consent strip UTMs at link click; Shopify counts those orders as Direct. Meta still claims them.
- Last-click vs UTM-truth. Meta credits any purchase that touched a Meta click within 7 days. Shopify only credits orders where the customer arrived via a UTM-tagged Meta link as their last referrer. A user who clicked Meta on Mon, browsed away, returned via Google search Fri, bought, is Meta-attributed in Meta and Google-attributed in Shopify (or Direct, if the Google referrer was lost).
- The Pixel can still fire on opted-in users.
- For opted-out users, Pixel is blocked from receiving advertiser-id (IDFA), so Meta can’t link the conversion back to the user who clicked the ad.
- Meta backfills with statistical modeling (machine-learning estimates) and Conversions API (server-to-server bypass).
- Shopify: Install official Meta Sales Channel app → enable Conversions API → choose “Maximum” data sharing. 30-minute setup. Auto-deduplicates Pixel + CAPI via
event_id. Easiest. - BigCommerce: Meta Pixel app + manual CAPI via Tag Manager + custom event_id. 2, 4 hours.
- Adobe Commerce / Magento: Meta extension + custom server endpoint. 1, 3 days.
- Custom / headless: Build a server-side proxy that mirrors Pixel events. 1, 2 weeks.
- In all cases: deduplicate via
event_id(unique per purchase) and matching event timestamps. Test in Meta Events Manager → Test Events tab; if dedup is working, both Pixel and CAPI events show but Meta credits one. - Allow 7, 14 days for retraining before judging the ROAS lift; Meta’s models recalibrate over that window.
action_values) but typically run 8, 18% of total revenue for Pixel-only DTC accounts. Patterns:
- Pre-CAPI: modeled fill ~20, 30%. Inflated.
- Post-CAPI clean: modeled fill ~5, 12%. Healthy.
- Post-CAPI but still high (>20%): implementation gaps, audit
event_iddeduplication and event coverage.
- Search has less iOS impact (search intent is desktop and Android-heavier).
- Google Tag Manager + Enhanced Conversions has better consent-mode handling.
- Modeled-conversion share is lower (5, 12% on Google vs 8, 18% on Meta).
event_id matching, Meta server-side dedupes; you get the union (whichever event arrived first or whichever has more data wins, depending on Meta’s logic). Without dedup, you double-count and your ROAS reads ~80% inflated. Test it: Meta Events Manager → Test Events → check dedup status indicator. The official Shopify Sales Channel app handles this automatically; custom implementations need explicit dedup logic.