Back to blog Product

How Flyweel Builds Channel-Specific ROAS Prediction Models

Reuben Scheckter
How Flyweel Builds Channel-Specific ROAS Prediction Models

When we started building Flyweel, the tempting path was to do what most attribution tools do: pull ROAS data from all connected channels, run a combined regression, and output a single forecast number. It is faster to build and easier to explain. It is also wrong in ways that compound badly when you act on it.

This post explains why we train separate models per channel, what that requires technically, and where the approach still has real limitations we are actively working through.

Why One Model Fits Zero Channels Well

The core problem is that each ad channel has structurally different ROAS behavior. Not just different average returns, but different variance patterns, different lag curves between impression and conversion, and different responses to budget changes.

Google Search ROAS tracks relatively closely with weekly spend fluctuations. When you increase Search budget, you capture more in-market demand within a predictable window. The relationship between spend and return is closer to linear within a given range, which means a model trained on Search data behaves sensibly when applied to new Search data.

Meta (Facebook and Instagram) is a fundamentally different problem. Meta is a push channel: you are targeting people who were not actively looking for your product. Creative fatigue sets in fast. ROAS variance week-over-week is consistently higher on Meta than on Google Search for the same brand. If you train a single model on blended data, the Search signal dominates (it is more stable) and the Meta predictions come out systematically overconfident. You forecast 3.2x on Meta and get 1.8x. That gap is not random noise. It is a structural artifact of the model design.

TikTok compounds this further. TikTok ROAS is partially driven by content virality, which is near-impossible to model from historical ROAS data alone. A single piece of creative can have genuinely anomalous performance that skews the model's view of what normal looks like on the channel. LinkedIn, by contrast, has slower spend pacing and longer consideration cycles, producing a different kind of signal instability entirely.

The bottom line: a single model averaging across these channels produces predictions that are miscalibrated for every channel, slightly in different directions.

What Channel-Specific Training Actually Requires

When we say we train channel-specific models, we mean each connected channel gets its own model instance trained on its own ROAS history. The model sees only the signal patterns for that channel: spend levels, campaign types, day-of-week patterns, and the historical lag between spend and attributed revenue.

For this to work well, each channel needs sufficient data. In practice, we look for a minimum of 60 days of daily ROAS data per channel before we are comfortable making predictions. At 90 days, the models become significantly more reliable. Below 60 days, we surface the forecast with a low-confidence flag rather than suppressing it entirely, because even a noisy signal can be more useful than no signal if the team understands the uncertainty it carries.

Campaign-type segmentation happens within each channel model. A Google account running both branded search and Performance Max campaigns does not behave as a single unit. Branded search has higher ROAS and lower variance almost universally. If you average those together in the training data, you produce a model overfit to the branded floor, which then badly underpredicts Performance Max performance on weeks when branded search volume drops. We segment by campaign type within channel, then weight the forecast contribution at the channel level. The result is that each account gets a forecasting structure reflecting how that account actually behaves, not how the average account in our training data behaves.

The Meta Variance Problem

Meta deserves its own section because it is the channel that causes the most consistent forecasting failures in one-size-fits-all tools.

The structural reason Meta has higher ROAS variance: the audience pool is dynamic in ways that Search is not. On Search, query volume for a given product category changes slowly. On Meta, your effective audience shifts with creative saturation, algorithm updates, and competitor bidding behavior. A creative that was generating 4.0x ROAS in week one can drop to 2.1x by week four, not because the audience got smaller, but because frequency built up among your most responsive segment.

Our Meta-specific model accounts for this by tracking ROAS trend velocity, not just the current ROAS value. If the 7-day trend is significantly below the 30-day trend, the forecast incorporates that momentum rather than averaging across the full window. This makes Meta forecasts less stable. That is correct. Meta ROAS is less stable, and a model that smooths over that instability is giving you false confidence about a channel that genuinely warrants more caution.

In our closed beta, running more than 150 forecasting runs across early-access accounts, Meta ROAS forecasts from our channel-specific model were consistently closer to realized ROAS than blended-model outputs. The improvement was largest precisely in the weeks where Meta's ROAS deviated most from its recent average, which are also the weeks where the cost of a bad allocation decision is highest.

Confidence Bands and What They Tell You

Every forecast in Flyweel comes with a confidence band rather than a point estimate. For Google Search, those bands tend to be tighter. For Meta, they are wider. For TikTok, they can be very wide indeed.

We display the band intentionally because the width is itself useful information. A wide band signals: this channel's behavior is hard to predict right now, so commit a smaller initial budget and reallocate based on early-week data. A tight band signals: this channel is performing predictably, you can commit the full allocation with more confidence.

A point estimate removes that signal entirely. Telling you "Meta ROAS will be 3.0x next week" is technically precise and practically misleading. Telling you "Meta ROAS will be in the 1.8x to 4.1x range, with the central estimate at 3.0x" tells you to hedge the commitment. The band is part of the prediction, not a footnote to it.

Where the Approach Has Real Limits

Honest about limitations is something we try to be more consistently than most product writing in this category allows.

Channel-specific modeling requires sufficient historical data per channel. New accounts, recently restructured accounts, or channels a brand just launched will have wide confidence bands and should be treated accordingly. We flag these cases in the UI, but the underlying constraint is real: you cannot forecast from patterns that do not exist yet in the data.

The models do not incorporate external signals: competitive auction pressure, platform algorithm updates, macro demand shifts, or news events that drive sudden changes in consumer behavior. These factors affect ROAS and are not visible in the historical data we ingest. A major Meta algorithm change can shift ROAS patterns in ways that make the historical model temporarily irrelevant. We will eventually need to incorporate some category of real-time external signal to handle these cases better.

We also do not currently model incrementality: the question of whether your ad spend is generating genuinely new revenue or primarily capturing purchases that would have happened anyway. That is a harder problem that requires holdout testing, and it is a distinct problem from the forecasting one we have focused on first. Our forecasts predict platform-attributed ROAS, not true incremental ROAS. Those two numbers can diverge significantly for brands with strong organic and direct traffic.

Channel-specific ROAS forecasting is materially better than blended forecasting for making allocation decisions. It is still not a complete picture of advertising effectiveness. We would rather tell you that directly than let you discover the gap after making allocation decisions you cannot revisit until month-end.