Rules compare averages
“If ROAS > 4, add 20%.” Yesterday’s average decides tomorrow’s budget, but an average says nothing about what the next pound will do.
The Engine
Rule-based optimisers compare yesterday’s averages, so they plateau. ROASt fits a response curve to every campaign’s own history and moves each pound to its highest marginal return. Then it checks its own predictions against what actually happened, every night.
30-day trial · no card · flat pricing, never % of spend
Every rules engine eventually hits the same wall. It’s mathematical, not a missing feature.
“If ROAS > 4, add 20%.” Yesterday’s average decides tomorrow’s budget, but an average says nothing about what the next pound will do.
Every campaign saturates. The first £100 buys cheap conversions; the last £100 fights for expensive ones. Two campaigns with identical averages can hide wildly different headroom.
The real question is never “which campaign is best”. It’s “where does the next pound return most”. That’s a calculus problem, not a rules problem.
Every decision comes from your last 91 days of daily campaign data, recent days weighted more heavily. Fifteen deterministic signals, computed the same way every night. No model guesses.
The primary scoring signal. Revenue over spend, with more weight on recent days: yesterday tells the engine more than six weeks ago did, so a day’s influence decays with age. The half-life is configurable and defaults to 14 days.
roas_w 4.31 · half-life 14d · window 91dA response curve refitted nightly from each campaign’s own spend and revenue history. The curve prices the next pound rather than the average one, and its influence scales with the confidence of the fit. Low-confidence curves are ignored, never trusted.
hill fit · conf 0.83 · marginal +£2.40 / £1Demand you aren’t serving, split by cause. Share lost to budget is proven appetite going unserved, and earns a growth tilt. Share lost to rank means bids are the problem, so those campaigns get a target nudge instead of more money.
is_budget 14% · is_rank 6%How far a campaign’s own numbers can be trusted. Data coverage, conversion volume and stability blend into one score; low-confidence campaigns lean on portfolio-wide evidence instead of being over-funded or starved on noise.
coverage 0.40 · volume 0.35 · stability 0.25The last 7 days against the prior 14. Outliers are capped and volatile campaigns get less say, so a spike gets verified before it gets chased.
7d vs prior 14d · trend +0.38The other ten
The newest days are always incomplete. Recent revenue is scaled down until attribution catches up.
Per-day multipliers learned from each campaign’s own history, scored against tomorrow’s day.
Spend rising while ROAS falls reads as saturation, and dampens allocation.
Tracking outages and one-day spikes are flagged and heavily down-weighted, not learned from.
During events the expected uplift is normalised and thresholds widen. A sale reads as a sale, not as genius.
Campaigns still learning are guaranteed a floor, so a slow start can’t spiral into no budget.
Efficient campaigns with proven unmet demand earn a push beyond their base share.
Thin campaigns borrow evidence from the whole portfolio until their own data carries weight.
Last night’s prediction errors adjust today’s ceilings, floors and dampening.
When a platform doesn’t report impression share, peer campaigns stand in, at a discount.
Shaping the month
What’s left of the month is re-planned on every run: flat, front-loaded, end-loaded, or modelled from your own seasonality. Spend is shaped on purpose, never front-loaded by accident.
A slice of each day’s budget (10% by default) that campaigns earn with evidence: strict early in the month, looser toward the end, so nothing underspends.
Most optimisers never look back. ROASt records what it predicted, waits for attribution to complete, then scores itself against what actually happened. And adjusts.
When recommendations are staged, the engine records its predictions: ROAS, spend utilisation, impression share lost to budget, confidence.
It waits for attribution to complete. The window is dynamic: small changes use the base lag; large increases get extra days for smart bidding to ramp.
Predicted-vs-actual updates the engine’s calibration biases: spend ceilings, ROAS floors, confidence dampening, saturation steepness.
Confidence is earned, not assumed: learned values blend toward safe defaults until evidence accumulates, and a dormant portfolio decays back toward caution with a 14-day half-life.
Flume writes briefs and answers questions in plain English. Every budget and target decision is deterministic signal math you can audit line by line.
Pure math, wrapped in safety layers tuned to how each ad platform actually behaves. Watch a run land: staged, executed, confirmed.
Every recommendation is staged and visible before anything is pushed. Review and approve, or let trusted portfolios run nightly. One kill switch halts everything instantly (repeated failures trip it on their own), and dry-run mode stages without pushing.
After every push, ROASt reads the values back from the platform API to confirm the changes actually landed. Discrepancies are logged and surfaced, never assumed away.
Per-run step limits plus rolling cumulative caps. The closer a campaign gets to its cap, the smaller each step becomes, so budgets never flicker.
Google learning-phase locks. Meta’s 48-hour dwell after big changes. Microsoft ghost-budget freezes. The adapters are the final safety layer, tuned to each platform’s learning mechanics.