Where we are
You have decomposed a purchase funnel (ecommerce, b4), a spend funnel (marketing, b5), and a perception funnel (branding, b6). Internet and traffic is different: the top-line is not a purchase at all, it is attention sold to advertisers. That splits the session into two trees that connect - a monetization product (ad revenue) sitting on top of an engagement bridge (DAU). Learning to hold both, and to see where they meet, is the whole point of today.
Ad revenue is engagement times price 7 min live
The top-line of an ad-supported product is Ad revenue = Impressions x Fill rate x price. Fill rate is the share of ad slots that actually get sold; price is what each impression earns. But impressions are not a raw input - they are produced by the engagement loop: Impressions = DAU x sessions per user x ad slots per session. So the tree is two levels deep, and that second level is where all the interesting drops hide.
LiveThe three drivers, and the eCPM footnote3 min▶
Read the top level first, then the sub-level.
- Impressions - how many ad slots were shown. Produced entirely by engagement (the sub-tree).
- Fill rate - the share of those slots that got sold to an advertiser. Below 100% means unsold inventory - demand-side, not engagement.
- Price per impression - what each sold impression earns.
Self-studyWhy impressions get their own sub-tree2 min read▶
You could treat impressions as a single leaf, but then a revenue drop would only ever point at "impressions fell" - true but useless. Splitting impressions into DAU x sessions x slots tells you why they fell: fewer people, fewer visits each, or fewer ad slots shown per visit. Each has a different owner and a different fix. The depth of a tree is the resolution of your diagnosis - go one level deeper and a vague answer becomes an ownable one.
- DAU down - a retention or acquisition problem. Product and growth own it.
- Sessions per user down - an engagement or habit problem. Product owns it.
- Slots per session down - an ad-load or layout change. Monetization owns it, and it trades against user experience.
The engagement loop behind DAU 5 min live
DAU is not a multiplicative product - it is a flow bridge. Each period's active users are last period's users, plus new and resurrected users, minus the ones who churned: DAU = Start + New + Resurrected - Churned. The bridge pattern from b2, applied to people. And this is the leading side of the whole business - engagement moves first, ad revenue follows.
{
"root": {
"label": "Ending DAU", "op": "bridge",
"children": [
{ "label": "Start DAU", "value": 2000000, "unit": "users" },
{ "label": "New", "value": 180000, "unit": "users" },
{ "label": "Resurrected", "value": 40000, "unit": "users" },
{ "label": "Churned", "value": 220000, "unit": "users", "sign": -1 }
]
}
}
LiveLeading engagement, lagging revenue3 min▶
At baseline the bridge nets to 2,000,000 - inflows (180K new + 40K resurrected) exactly offset the 220K churned, so DAU holds flat. That is the number that feeds the impressions sub-tree in Part 1. The bridge is leading: churn rising this week is an early warning that impressions, and therefore ad revenue, will fall in the weeks ahead. Ad revenue is the lagging confirmation.
The classic internet drops 4 min live
An ad-revenue drop always resolves to one of two sides - the engagement side (fewer impressions) or the price side (fill rate or eCPM). Here is the field guide.
LiveSymptom to branch to cause3 min▶
- DAU falls - fewer people, so fewer impressions. Retention slipping or acquisition drying up. Branch: Impressions to DAU. Engagement side.
- Sessions or slots fall - same users, fewer impressions each. A habit change, or an ad-load cut. Branch: Impressions to sessions or slots. Engagement side.
- Fill rate falls - impressions held but fewer sold. Weak ad demand, a seasonal lull, or ad-blocker adoption. Branch: Fill rate. Price side.
- eCPM falls - impressions sold but each earns less. Seasonality (post-holiday cliff), a mix shift to cheaper geos, or a soft ad market. Branch: price. Price side.
Two top-lines, one business. Engagement (DAU) and monetization (ad revenue) connect at exactly one node - impressions. A product team can be winning on DAU while revenue falls because eCPM collapsed in a soft ad market; a sales team can be winning on price while revenue falls because the base is shrinking. The two-level tree is what lets the two teams stop blaming each other and point at the actual branch.
Diagnose an ad-revenue drop ★ 12 min · everyone builds
Here is the full two-level ad-revenue tree. Read the baseline, then press Simulate a drop - one leaf falls and its path up to Ad revenue lights coral. Your job: say whether the drop was on the engagement side (a leaf inside Impressions) or the price side (fill rate or price-per-impression).
{
"unit": "$",
"root": {
"label": "Ad revenue / day", "op": "x",
"children": [
{ "label": "Impressions", "op": "x",
"children": [
{ "label": "DAU", "value": 2000000, "unit": "users" },
{ "label": "Sessions / user", "value": 3 },
{ "label": "Ad slots / session", "value": 4 }
]
},
{ "label": "Fill rate", "value": 0.85, "pct": true },
{ "label": "Rev / impression", "value": 0.01, "unit": "$" }
]
}
}
Read the baseline: 2.0M DAU x 3 x 4 = 24M impressions, x 85% fill x $0.01 = about $204K/day.
Press Simulate a drop. Follow the coral trail. Did it start inside Impressions, or at Fill rate or Rev/impression?
Name the side: a leaf inside Impressions is the engagement side (people or usage); Fill or price is the price side (ad market).
Say it: "Ad revenue fell X% - it was the [engagement / price] side, specifically [leaf]." Press Reset and repeat.
LiveAn engagement proxy from the events table3 min▶
The store's events table logs user actions with a date - the closest thing to an engagement signal in the seed. Run this to count distinct active users per week, the store-scale analogue of a DAU trend.
SELECT strftime(CAST(event_date AS DATE), '%Y-W%W') AS week,
COUNT(DISTINCT customer_id) AS active_users,
COUNT(*) AS events
FROM events
GROUP BY week
ORDER BY week;
Your turn ★ 10 min · everyone builds
Three tasks: edit the DAU bridge, run an engagement query, then a short thinking exercise.
LiveQ1 · Double the churn on the DAU bridge3 min▶
Go back to the DAU bridge in Part 2. Edit Churned from 220,000 up to 440,000. Ending DAU falls from 2.0M to about 1.78M - the inflows can no longer offset the losses. Now trace it forward in your head: fewer DAU means fewer impressions in Part 1, which (holding fill and price) means ad revenue falls by the same percentage. One churn number, felt two trees down.
LiveQ2 · Active users by event type4 min▶
Build an engagement breakdown: for each event type, how many distinct users performed it and how many times. On a real ad product this is how you spot which action is carrying engagement - and which is quietly a churn signal (support tickets, cancel surveys).
SELECT event_type,
COUNT(DISTINCT customer_id) AS users,
COUNT(*) AS events
FROM events
GROUP BY event_type
ORDER BY users DESC;
Self-studyQ3 · Ad revenue flat but DAU down - what rose?take home▶
Ad revenue held flat this quarter, but DAU is clearly down. Write a paragraph: what must have risen to compensate, and is that healthy? Work it from the tree - if impressions fell (fewer DAU) yet revenue held, then fill rate or price per impression must have risen to offset it. That can happen for good reasons (a stronger ad market, better ad targeting lifting eCPM) or fragile ones (cramming more ad slots per session, which degrades the experience and accelerates the very churn dragging DAU down). Argue whether the compensation is durable or a short-term patch that borrows revenue from the future by taxing the user experience.
Try it yourself - this week ◐ 20-30 min total
- Write your product's engagement-to-money tree. If you are ad-supported, use ad revenue; if you are usage-billed, the same two-level shape works (usage x price).
- Build your own DAU (or WAU/MAU) bridge: start, new, resurrected, churned. Fill in real numbers for last period and see whether a flat level is hiding busy flows.
- Find your two top-lines and name the single node where they connect. For an ad product it is impressions; for yours it may be sessions, API calls, or transactions.
- Check your units once, on purpose: is any price quoted per-thousand (eCPM, CPM) while you multiply it by a raw count? That is the 1,000x bug waiting to happen.
- Bring your engagement bridge to b8 - B2B SaaS, where the same churn flow drives ARR instead of impressions.
Frameworks this session draws on
Internet metrics blend the ad-tech revenue identity with the engagement-loop thinking that product teams live by. This page draws on:
Three questions before you go 🎯 ◐ 90 seconds
1 · Ad revenue decomposes as...
Ad revenue is a multiplicative product of impressions, fill rate, and price per impression, with impressions themselves a product of DAU, sessions per user, and ad slots per session. That second level is where a vague "impressions fell" becomes an ownable diagnosis.
2 · DAU = Start + New + Resurrected - Churned is which decomposition pattern?
A bridge moves from a starting stock to an ending stock via signed flows: new and resurrected add, churned subtracts. It is the pattern for any level driven by inflows and outflows - users, subscribers, cash.
3 · Ad revenue is flat but DAU fell. What must have happened?
Fewer DAU means fewer impressions, so for revenue to hold, fill rate or eCPM must have risen. That can be a stronger ad market (durable) or cramming more ad slots per session (fragile - it taxes the experience and can feed the churn dragging DAU down).