Pacing
Pacing is one comparison: what a target was planned to spend by a given day against what it actually spent by that day. Nothing about it is stored. Every figure is computed when you read it, from the daily counts the syncs write and from the plan as it stands right now — so editing a plan at noon changes the pace at noon, and a bar, a chip and a draft's report can never disagree about whether a campaign is behind.
What "planned" means
Three sources, read strictly in this order. The first one that has an answer is the answer, and the surface says which it used.
- The envelope times the phase. If the target has an enabled envelope, the plan for a day is the envelope's peak daily amount scaled by the multiplier of the phase covering that day — and by the whole envelope on a day no phase covers.
- The item's budget over its flight. For a plan item with no envelope, the whole-flight budget divided by the inclusive length of the flight. That is the same arithmetic materializing a plan does when it turns a whole-flight figure into the daily one a platform is told.
- The campaign's own daily budget. For a live campaign with neither, the daily budget the platform is running today, labelled as the platform's own number.
Outside the flight there is no plan for the day, and a campaign with none of the three — a lifetime budget on an open-ended flight is the real case — has no plan at all. Both answer null, which is not zero.
The order is a decision, not a fallback chain: an envelope is what the workspace is willing to run a target at, a plan item's budget is what the plan says, and the live daily budget is the platform's own figure and only gets the last word when nothing above it has one.
What "actual" means, and where it stops
Actual is the sum of daily spend from the flight's start to the last complete day — the workspace's reporting day minus one — and planned to date is summed over exactly the same days.
It stops at yesterday on purpose. Today is a partial day on every platform, and comparing half a day's spend against a whole day's plan would paint every campaign in the workspace behind every morning.
Pace, and the five states
pace = spend to date ÷ plan to date, and it is null when the denominator
is zero. From it:
| State | When | What a reader is shown |
|---|---|---|
on_pace | Within ten percent either side of 1.0 | "On pace" |
behind | Below 0.9 | "Behind plan by 23%" |
ahead | Above 1.1 | "Ahead of plan by 18%" |
over_cap | The account spent more yesterday than its resolved daily cap allows | "Over the account cap yesterday" |
unknown | There is nothing to compare against | "No plan to pace against" |
Ten percent is the band because daily delivery on every platform swings by more than that on its own. A narrower band would paint a campaign amber for a weekend and teach a reader to ignore the colour, which is the only real failure mode a pacing state has.
over_cap is said about the account, not about the campaign, and it is said
first. A workspace that is over its own ceiling needs to hear that before it
hears that one campaign inside it is four percent behind — so an account over
its cap carries that state onto every lane under it, whatever each lane's own
pace is.
The null rule
No rows is unmeasured. It is never zero.
A ratio with a zero denominator has no value, so pace is null and the state is
unknown. A campaign whose metrics have not synced shows no fill and says it
is not measured; a campaign that has genuinely spent nothing against a real plan
shows a pace of 0 and reads as behind. Those are different facts, they render
differently, and neither is written as the other. The same rule runs through
every ratio in Tempio — see Metrics.
The projection
Alongside the pace, Tempio states where the flight lands if the measured pace holds: spend to date, plus the remaining planned days extended at the measured factor. It is labelled a projection everywhere it appears.
Two rules keep it honest. No pace means no factor, so there is nothing to project and the answer is null rather than the plan restated. And the factor is clamped at three: a campaign that spent eight times its plan in its first two days is almost always a data problem — a backfill landing, a currency change — and multiplying the rest of the flight by eight would print a number nobody should act on. Past the clamp the projection is a floor rather than a guess, and the surface says the figure was clamped.
A worked example
An account bills in EUR. Winter Push runs 1–30 November with an envelope of €200.00 a day and one phase: a launch at 150 % over 1–10 November. Today is 16 November, so the last complete day is the 15th.
| Days | Multiplier | Plan per day | Plan for the span |
|---|---|---|---|
| 1–10 Nov | 150 % | €300.00 | €3,000.00 |
| 11–15 Nov | none, so the whole envelope | €200.00 | €1,000.00 |
Plan to date is €4,000.00. Spend to date is €3,200.00.
pace = 3,200 ÷ 4,000 = 0.80— below 0.9, so the state isbehind.- The remaining plan, 16–30 November at €200.00, is €3,000.00.
- The projection is
3,200 + (3,000 × 0.80)= €5,600.00, against a plan of €7,000.00 for the whole flight.
Take the envelope away and the same campaign paces against whatever its platform
daily budget is instead. Take the daily budget away too — a lifetime budget on an
open flight — and there is no plan for any day, so pace is null, the state is
unknown, and nothing is projected.
Where pacing shows up
- The timeline bar: the fill, the state's tone and the state's word.
- The campaign's peek: a sparkline with the planned line over the actual bars, both from the one read.
- The campaign page: a chip with the state and the one number that makes it actionable.
- The account brief: a sentence for each campaign drifting by more than a quarter, under the brief's own ranking rules.
- The chat: one line per campaign that is off pace today, with the accounts over their cap grouped first and the rest ordered by how far they have drifted.
Goals
A goal is a number a campaign or a plan item is held to, measured from the same daily rows over a trailing window:
| Field | What it holds |
|---|---|
| Metric | cpa, roas, ctr, cpm or spend |
| Direction | at_most or at_least |
| Target | Integer minor units for cpa, cpm and spend; basis points for roas and ctr (10,000 basis points is 1.0, or 100 %) |
| Window | The trailing days it is measured over, up to a year |
| Action | flag shows the state. propose also lets the allocator act on it |
A verdict carries the target, the measured actual in the same denomination, and whether it was met. Met is null when nothing could be measured — never false, which would read as measured and missed. A goal set on a plan item transfers to the campaign that item becomes.
Over MCP
| Route | Capability | Scope |
|---|---|---|
pacing.get | get_pacing | read |
goal.create, goal.update | upsert_goal | draft |
goal.remove | delete_goal | draft |
get_pacing takes one campaign or one plan item and answers the day-by-day
series with the planned amount beside the actual for every measured day, then
the totals, the pace, the state, the projection and every goal with its verdict.
Every campaign read carries the state too, without asking for it: list_campaigns,
get_campaign and get_campaign_metrics each return a pacing field per
campaign, and an account over its daily cap rides once on the envelope's
warnings rather than once per row. The warning codes are pacing_behind,
pacing_ahead, pacing_over_cap and goal_missed;
the MCP reference lists what each class and severity means.
Writing a goal needs the draft scope, because that is the scope covering
everything that can become a change. A goal is not itself a change request: it
is a planning row, it changes nothing on a platform, and it is audited with the
values it moved between.
Timeline
The workspace's operating calendar — every live campaign and every planned flight on one axis, grouped by ad account, with pacing on the bar and a drag that writes a change request.
Phases and envelopes
A ceiling per campaign and dated windows that scale it — launch, hold, closing — so budget follows whichever campaign is in its hot window, under a cap the workspace sets.