Conversion rate is the most popular fraction in business. It is also one of the easiest to lie with, accidentally. Change the denominator, stretch the window, or count the wrong “success,” and a 4.2% becomes a crisis or a triumph without the product changing at all. Magic is what happens when nobody writes the formula.
Part 1 of this series built product-shaped funnel stages. Part 2 is the arithmetic and the definitions those stages need: rate = success / eligible, who counts as eligible, and how long you wait before success can still count. If you can defend those three pieces in a meeting, your conversion chart is a tool. If you cannot, it is decoration.
This is Part 2 of Customer analytics basics. We stay practical: formulas, toy numbers, SQL sketches, and the traps that show up every planning season. For broader metric design, see the metrics series. For event quality under the math, see the data quality series. Site-wide paths live at Learn.
What you’ll learn
- The three-part conversion contract: rate, eligible, window
- Step conversion vs overall conversion (and when each is useful)
- How windows, attribution, and delayed success change the number
- Worked toy math you can recompute by hand
- Mistakes, practice drills, and how this sets up cohorts in Part 3
Conversion math in one card
Every conversion metric is three decisions pretending to be one percentage:

- Rate: success count divided by eligible count.
- Eligible: who could have succeeded under the definition (the denominator discipline).
- Window: how long after eligibility you still count a success.
Write them every time. “Signup conversion is 4.2%” is incomplete. “Of users with session_start in week W (eligible), 4.2% had account_created within 1 day (window)” is a metric.
Eligible: the quiet half of the fraction
Most conversion fights are denominator fights. Examples:
- Do you include bots, employees, and QA accounts?
- Do already-logged-in users enter a “signup” funnel?
- For pay conversion, is the base all activated users, all signups, or only users who saw pricing?
- For email CTA conversion, is eligible “delivered,” “opened,” or “clicked an earlier link”?
Rule of thumb: eligible should be the set of actors who could reasonably take the success action under your product rules. If someone never saw the paywall, counting them as a non-converting “pay eligible” user invents a failure that is really a reach problem.
Sometimes you want both rates: “among all signups” and “among pricing-page viewers.” That is two metrics, not one metric with two moods. Name them differently.
Success: one event, one grain
Success should be a clear event or state at a stated grain (user, account, session, order). Mixing grains is a classic self-own: “conversion rate of sessions to paying users” without defining how multi-session users count.
Prefer:
- User-level: share of eligible users who succeed in the window.
- Session-level: share of eligible sessions that succeed (good for UX step tests; bad as a proxy for revenue if users multi-session).
- Account-level: B2B reality when seats and buyers differ.
If Finance cares about paid accounts and Product instruments users, bridge with an explicit rollup. Do not silently average across mismatched grains.
Windows: where honest rates go to die
A 1-day signup window and a 30-day signup window describe different products. Longer windows raise conversion and delay reporting. Shorter windows are faster for ops and miss slow converters.
Practical patterns:
- Same-day / 24h: UX and onboarding friction.
- 7d: common activation windows for consumer apps.
- 14d / 30d: B2B trials, sales-assisted, higher consideration.
- Unbounded: almost never for operating metrics; cohorts never mature.
When you report a rate for last week’s eligible users, say whether the window has fully matured. Day-2 “7d activation” is a partial; label it or you will celebrate incomplete denominators.
Step rate vs overall rate
Step conversion: success at stage N among those who reached stage N-1 (within a step window).
Overall conversion: success at a late stage among those who entered an early stage (for example Visit to Pay).
Overall rates multiply the steps (roughly, when definitions nest). A team can improve Visit→Signup while Pay stays flat if Activate→Pay collapses. Always show the spine of step rates when diagnosing. Overall alone is a summary, not a diagnosis.
Worked example: toy conversion you can recompute
Eligible users last week: 1,000 (signed up, not employees, not bots). Success: first paid plan within 14 days. Successes so far with full window matured: 42.

Rate = 42 / 1000 = 4.2%. That is the whole trick. The arguments hide in the definitions behind 42 and 1000.
Three ways to fake a better number without product work:
- Drop 200 “low intent” signups from eligible after seeing results (denominator 800 → 5.25%).
- Extend the window to 45 days and count late payers without saying so.
- Count trial starts as “converted” while Finance only counts paid after trial.
Three ways to make the number look worse by accident:
- Include incomplete windows (eligible users from yesterday in a 14-day metric).
- Double-count users who pay, refund, and pay again as two successes or zero, inconsistently.
- Join billing on email while product uses user_id, dropping matches.
SQL sketch for the honest 4.2%:
-- Eligible: signups in cohort week, quality filters applied upstream
-- Success: first paid subscription within 14 days of signup
-- Report only when cohort_week_end + 14 days <= current_date
WITH eligible AS (
SELECT user_id, signup_at
FROM analytics.user_signups
WHERE cohort_week = DATE '2026-09-29'
AND is_employee = FALSE
AND is_bot = FALSE
),
success AS (
SELECT e.user_id
FROM eligible e
JOIN analytics.subscriptions s
ON s.user_id = e.user_id
AND s.first_paid_at >= e.signup_at
AND s.first_paid_at < e.signup_at + INTERVAL '14' DAY
AND s.counts_as_paid = TRUE
GROUP BY 1
)
SELECT
(SELECT COUNT(*) FROM eligible) AS eligible_users,
(SELECT COUNT(*) FROM success) AS converted_users,
1.0 * (SELECT COUNT(*) FROM success)
/ NULLIF((SELECT COUNT(*) FROM eligible), 0) AS conversion_rate;If a model or assistant wrote that query, re-check the interval bounds, the paid flag, and the employee filter. The tutorial How to check AI-written SQL is written for exactly this class of “looks right, wrong join” failure.
Comparing conversion across channels and experiments
Channel comparison needs the same eligible and window rules. Paid search users may convert faster than organic; that does not mean you should use a 1-day window for paid and a 14-day window for organic in the same slide. If lag structures differ, show both a short operational window and a mature window, labeled.
In experiments, conversion as primary metric still needs Part 2 of Experimentation culture: no peeking theater, guardrails for revenue quality (refunds), and a stopping rule. A conversion lift with a refund explosion is not a win.
Micro conversions and vanity steps
Teams love intermediate conversions (clicked CTA, opened modal, started checkout) because they move more often. Use them as diagnostics, not as the only success for a revenue hypothesis. Optimizing modal opens can reduce pay conversion if you train users to dismiss noise. Tie micro metrics to the stage spine from Part 1 so they have a job.
Uncertainty without a stats lecture
With 42 successes on 1,000 eligibles, the rate is roughly 4.2%, but sampling noise is not zero. For small N, week-to-week swings of a point may be noise. For board storytelling, prefer mature large cohorts and confidence intervals or at least “N =” on the chart. You do not need a PhD; you need to stop declaring war over 41 vs 42 successes.
Rule of thumb many teams use: do not sweat the third decimal place when N is small; sweat definition drift when N is large.
Definition card template
metric_name: signup_to_paid_14d
rate: converted_users / eligible_users
eligible: >
users with account_created in cohort period,
not employee, not bot, not purged
success: >
first subscription with counts_as_paid
and first_paid_at within 14 days of account_created
window: 14 days from eligibility timestamp
grain: user
mature_when: cohort_end + 14 days <= report_date
owner: growth_analytics
finance_aligned: yes (counts_as_paid flag shared)
version: 3
effective_from: 2026-07-01Common mistakes
- Denominator shopping after seeing results.
- Immature windows reported as final.
- Session rates labeled as user rates.
- Trial starts called “revenue conversion.”
- Mixed time zones so “same day” means different things in app and warehouse.
- Unique success events that fire twice (double thank-you page) inflating numerator.
- No version field when definitions change, so trends lie.
How to practice this week
- Pick one conversion KPI on your dashboard. Write rate, eligible, window in three bullets without looking at code.
- Open the SQL or BI definition. Diff your bullets against reality. Note every mismatch.
- Recompute last fully matured cohort by hand or with a small query. Match the dashboard within rounding.
- If you cannot match, file a data quality issue before the next exec review.
- Add “N eligible” and “window mature?” notes to the chart subtitle.
Quick recap
Conversion is success over eligible inside a window. The percentage is the easy part. Eligibility, grain, maturity, and versioning are the craft. Toy numbers help: 42 / 1000 = 4.2% only means something when 42 and 1000 are boringly well defined.
Next in Customer analytics basics: cohorts, so you stop averaging brand-new users with veterans and calling it “retention.”
Sources
- Croll and Yoskovitz, Lean Analytics (input vs output metrics; conversion in context): https://leananalyticsbook.com/
- Kohavi et al. on metrics for online experiments (guardrails and definition care): https://www.cambridge.org/core/books/trustworthy-online-controlled-experiments/D97B26382EB0EB2DC2019A7ECBD9E84D
- Amplitude Docs on conversion and funnels: https://help.amplitude.com/hc/en-us/articles/230403928-Funnel-Analysis
- Mixpanel Docs on conversion windows and attribution settings: https://docs.mixpanel.com/docs/reports/funnels
- Google Analytics help on conversion paths and counting methods (platform-specific, still useful conceptually): https://support.google.com/analytics/answer/5963952
