learn-metric-decomposition-with-phoebe / Builder session 7 of 10
Learn Metric Decomposition with Phoebe · Builder track · Session 7 of 10

Internet and traffic deep dive

An ad-supported internet business runs on two top-lines that most teams confuse - engagement (how much people use the product) and monetization (how much that use earns). Ad revenue decomposes into impressions times fill rate times price, and impressions themselves decompose into the engagement loop underneath. Today you build both as live trees - a two-level ad-revenue product and a DAU flow bridge - and trace a revenue drop back to whether it was people or price.

🟡 Builder track Analysts · PMs · founders · ops Live tree simulator + SQL 45 min
0-3 · Recap 3-20 · Ad revenue & the DAU loop 20-42 · Diagnose a revenue drop 42-45 · Q&A
Part 0

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.

Live - presented in session Self-study - read after class ▶ Live tree - editable & runnable Framework sources covered
★ What you walk out with today Ad revenue written as Impressions x Fill rate x price-per-impression, with impressions themselves broken into DAU x sessions x ad-slots; a DAU flow bridge (Start + New + Resurrected - Churned); and the reflex to trace an ad-revenue drop to either the engagement side (fewer impressions) or the price side (fill rate, eCPM).
Part 1 · covers the multiplicative pattern, two levels deep

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.

Ad revenue $204K / day Impressions 24,000,000 Fill rate 85% Rev / impression $0.01 x x DAU 2.0M Sessions / user 3 Slots / session 4 2.0M x 3 x 4 = 24M impressions. x 85% fill x $0.01 per impression ($10 eCPM per 1,000) = $204K/day.
🔍 Click to zoom - ad revenue over impressions, fill, and price, with impressions split into the engagement loop
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.
The /1000 trap - read this Advertisers quote eCPM - earnings per thousand impressions - so an eCPM of $10 is $0.01 per single impression. The tree multiplies impressions by the per-impression price, so we store $0.01, not $10. If you ever plug an eCPM straight into an impression count, you will be off by 1,000x. Keep the units matched: per-impression price against an impression count.
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.
Part 2 · covers the flow-bridge pattern, leading vs lagging

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 DAU bridge: inflows exactly offset the losses Start DAU 2,000,000 + New 180,000 + Resurrected 40,000 - Churned 220,000 Ending DAU 2,000,000 (flat) 180K new plus 40K resurrected exactly offsets 220K churned - flat hides two moving flows.
🔍 Click to zoom - a flat DAU can be two big flows cancelling out, not calm
Watch the flows, not just the level A flat DAU can hide a business quietly falling apart - churn and new-user inflow both climbing, netting to the same level while the base rots underneath. The bridge shows the flows the level conceals. Steer by the inflow and churn leaves, not the DAU total.
Part 3 · covers the diagnosis playbook, symptom to branch

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.
Real world

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.

Demo 1 of 2

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;
Demo 2 of 2

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.

Double the churn leaf and the bridge cannot keep up ✓ Baseline churn 220,000 180K new + 40K resurrected minus 220K churned Ending DAU = 2,000,000 ✗ Churn doubles to 440,000 180K new + 40K resurrected minus 440K churned Ending DAU = about 1.78M Fewer DAU means fewer impressions - the same percentage fall reaches ad revenue next.
🔍 Click to zoom - a churn number felt two trees down, all the way to ad revenue
Why edit, not simulate On the bridge, "Simulate a drop" cuts a random leaf by 15-35%. If it happens to cut Churned, DAU rises - because less churn is good. For a churn increase, edit the leaf up by hand. Losses are the one place a "drop" in the input is a gain in the output.
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.

Homework

Try it yourself - this week ◐ 20-30 min total

Framework sources

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:

Ad-revenue identity (impressions x fill x eCPM) - the ad-tech monetization canonPart 1 · the two-level revenue product and the eCPM /1000 discipline
Amplitude North Star Playbook - the engagement loop and DAU accountingPart 2 · the flow bridge of new, resurrected, and churned users
Lean Analytics (Croll & Yoskovitz) - the metrics of a media / user-generated businessPart 3 · engagement top-line versus monetization top-line
Check yourself

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).

Builder session 7 cheat sheet · pin this

Ad revenueImpressions x Fill rate x price per impression. A two-level multiplicative tree.
Impressions sub-treeImpressions = DAU x sessions per user x ad slots per session. Depth = diagnosis resolution.
eCPM /1000 trapeCPM is per 1,000 impressions. $10 eCPM = $0.01 per impression. Match units or be off 1,000x.
DAU bridgeDAU = Start + New + Resurrected - Churned. A flow bridge; churn carries sign -1.
Two top-linesEngagement (DAU) and monetization (ad revenue). They connect at one node: impressions.
Engagement vs price sideDAU/sessions/slots = engagement side. Fill rate/eCPM = price side. Trace which one moved.
Watch flows, not levelA flat DAU can hide climbing churn and inflow. The bridge shows what the level conceals.
Running skillBuild the two-level tree and the DAU bridge, trace people vs price. Next: b8, B2B SaaS.