All posts
Engineering

The Two Rules That Decide What a Funnel Number Means

The cohort is fixed by the first step, and revenue is cumulative down the funnel. Neither is visible on the chart, and both explain why two systems disagree.

Jay Patel11 min read
range recruits+ one window

Somebody will eventually put your funnel's conversion rate next to a number from another system and ask why they disagree. The honest answer is almost never "one of them is wrong." It is that the two numbers count different people over different intervals, and nobody wrote down which.

A funnel looks like the simplest report in analytics: five boxes, each smaller than the last. In practice it is a query with several decisions baked into it, and two of those decisions determine what every figure on the screen means. Neither is visible on the chart. Both are the reason a funnel and a dashboard tile that should obviously agree do not.

Rule one: the first step defines the population

The cohort is the set of visitors whose first step falls inside your selected date range. Their later steps are then counted for those same people, wherever those steps happen to land in time.

This has a consequence people find surprising, and it is worth stating in the strongest form: changing the first step changes who the funnel is about. It is not like changing a filter on a table, where you see a subset of the same rows. It recruits an entirely different group of humans, and every number below moves for reasons that have nothing to do with the pages at those later steps.

Two funnels, identical from step two onward:

  • Step one equals /pricing: the cohort is people who landed on the pricing page exactly.
  • Step one starts_with /pricing: the cohort now also includes /pricing/enterprise and /pricing-faq.

The second funnel will show a different step-three rate, and the difference is not a step-three phenomenon. It is a different set of people arriving at step three.

The practical rule

Before you compare two funnels, check that they share a first step. If they do not, you are comparing two populations, and every difference downstream is confounded by that. This is the single most common cause of "the funnel says one thing and the dashboard says another."

Why there is a tail

The other half of the cohort rule is the part that looks like a bug until you try to design it any other way.

Visitors are recruited by a first step inside your date range. Their later steps are counted for up to one conversion window past the end of that range.

Remove the tail and a seven-day funnel over a seven-day range becomes arithmetically incapable of completing: a visitor who enters on the last day has zero time left to finish. Every funnel would understate its own final step by an amount that depends on the range you happened to pick.

Remove the entry rule instead (let anyone who takes any step inside the range count) and you get the opposite failure. The funnel starts recruiting a second group of visitors whose earlier steps happened before the range began, so they appear at step three having never appeared at step one. Now step three can exceed step two, and the funnel stops being a funnel.

So: entry fixed by the first step, exit extended by one window. Both halves are load-bearing, and each one is there to stop a specific way the number goes wrong.

Who is in the cohort

The range recruits. The window follows. Nothing about the later steps is limited to the range you picked, and nothing outside the range recruits.

01

Before the range

Visitors who took step one here are NOT in the cohort, even if their later steps land inside your range.

02

Inside the range

Step one here recruits the visitor. This is the only thing the date range decides.

03

Up to one window after

Later steps for recruited visitors still count here. Without this the last day of every range would be structurally unable to convert.

04

Beyond one window

Nothing counts. The window is the definition of converting, so past it is a drop.

Rule two: revenue is cumulative, and it is not per-step

A funnel step shows revenue. Almost everyone reads it as "revenue generated at this step." It is not.

A step's revenue is the revenue of every visitor who reached that step. Because a funnel narrows as you descend, and because revenue attaches to people rather than to stages, this number rises as you go down. Step four's revenue is a subset of the people counted at step one, and their revenue is counted at both.

The rule that follows is short: never add the revenue column up. The total is meaningless. It is the same money counted once per step the payer reached, and a four-step funnel over paying customers will produce a figure roughly four times your actual revenue if you sum it.

What the column is genuinely for is the per-visitor value beside it: a step's revenue divided by its visitor count. That number goes up as you descend for a real reason (the people still present at step four are more likely to have paid), and the shape of that rise is informative. A jump between two steps says the visitors who made it past that step are worth substantially more than the ones who did not, which is an argument for spending effort on exactly that transition.

Three funnel numbers that look similar and are not

Each answers a different question. Mixing them up is the second most common source of funnel disagreements, after the cohort rule.

NumberWhat it countsDirection down the funnelSafe to sum?
Step visitorsDistinct visitors who reached this step within the windowFalls, alwaysNo: a visitor appears at every step they reached
Step revenueRevenue from every visitor who reached this stepRisesNo: the same money is counted at each step
Per-visitor valueStep revenue divided by step visitorsRisesNo: it is a ratio, and ratios do not add
Drop between stepsVisitors at step N minus visitors at step N+1Varies, and this is the pointYes: the drops do sum to the total loss

What a page step actually matches

The third thing worth knowing before you trust a number is what your step definitions are doing, because a step that matches slightly more or slightly less than you intended produces a perfectly plausible funnel that is measuring the wrong pages.

A page step matches on the URL path. No query string, no fragment. /pricing?utm_source=chatgpt#compare is /pricing for matching purposes, which is what you want: campaign parameters and anchor links are not different pages, and a funnel that treated them as different would fragment into noise the first time somebody shared a link.

Seven operators are available, and one of them behaves differently from the other six:

OperatorMatches when the path…
equalsis exactly the value
not_equalsis anything else
containscontains the value anywhere
not_containsdoes not contain the value
starts_withbegins with the value
ends_withends with the value
wildcardmatches a pattern where * stands for any run of characters

Only wildcard treats its value as a pattern. Everywhere else the value is literal, all of it. /report_2024 under contains matches the four literal characters _202 and never matches /reportX2024, because the underscore is an underscore and not a single-character wildcard from some regex dialect. That literalness is deliberate: a step definition that silently interpreted punctuation as syntax would be a trap that only fires on the paths that happen to contain punctuation, which is most of them.

The operator that quietly changes your cohort

contains on a short value is the one to watch. A first step of contains /pro matches /pricing, /products, /promo and /profile. It will run, it will produce a funnel, and the cohort will be four unrelated groups of people wearing one label. Prefer starts_with for a section and equals for a specific page, and reach for contains only when you know what else it catches.

Reconciling a funnel against another number

When a funnel disagrees with a dashboard tile, work through these in order. In practice the disagreement resolves at step one or two nearly every time.

1. Are the populations the same? The tile probably counts sessions or events in the range. The funnel counts visitors recruited by a first step. These are different denominators before anything else is considered, and a session is not a person, so a returning buyer is several sessions and one funnel visitor. Most "discrepancies" die here.

2. Are the intervals the same? The tile counts inside the range. The funnel counts inside the range plus one window. If your window is thirty days and your range is thirty days, the funnel's effective interval is twice the tile's.

3. Is the step definition what you think it is? Run the step's operator against your ten most-visited paths by hand. A contains that catches an extra section is invisible on the chart and obvious in that list.

4. Only now, look at the data. If the first three are aligned and the numbers still differ, you have something worth investigating. If you skipped them, you do not: you have a definitions mismatch that will consume an afternoon and resolve into "they were never the same number."

2 to 8

Steps per funnel. Every step you add multiplies the ways a definition can drift from the question you meant to ask

start with three

1h to 90d

Conversion window, 7 days by default. It belongs in the funnel's name if you keep more than one version around

part of the definition

180 days

Maximum results range. Recruiting is capped by the range; counting is not, because of the window tail

range recruits, window follows

Keep the definitions in version control

A funnel is a measurement instrument. An instrument that changes without a diff makes every number recorded before the change unexplainable, and the change is invariably discovered six weeks later by someone trying to work out why a chart has a step in it.

Funnels here are created and edited over HTTP for exactly that reason. Put the definitions in the repository next to everything else that decides what a number means, and when a rate moves you can check whether the instrument moved first. That is the same argument as freezing a prompt set before you measure visibility with it, and it fails the same way when skipped: a series that quietly stopped being comparable to itself.

Frequently asked

Usually because they count different populations. A funnel counts visitors recruited by its first step inside your date range and nobody else, while a dashboard tile typically counts sessions or events in that range regardless of what those visitors did earlier. Check whether the first step excludes people the tile includes, and whether your conversion window extends the funnel's effective interval past the range, before treating the gap as a data problem.

Sources & further reading

  1. 01URL Standard: paths, queries and fragments, WHATWG
  2. 02Payment Intents API, Stripe Docs
  3. 03Cohort analysis, Wikipedia
Share