Conversion rate: как собрать честную воронку
Как считать conversion rate по воронке: выбрать вход, порядок событий и окно конверсии, найти настоящий drop-off и не перепутать пользователей с сессиями.
Содержание статьи
Когда конверсия падает, команда часто открывает один большой процент и начинает спорить, что чинить: лендинг, форму, цену или продукт. Воронка нужна не для красивого треугольника. Она показывает, на каком конкретном переходе люди теряют контекст, сталкиваются с ошибкой или просто не видят смысла идти дальше.
Коротко
Conversion rate — это доля пользователей, которые вошли в заданный путь и дошли до целевого действия за выбранное окно времени. Смысл метрики полностью зависит от четырёх вещей: кто вошёл, какие шаги обязательны, в каком порядке они идут и сколько времени разрешено на завершение.
- Покажите в отчёте входной шаг и знаменатель, а не только итоговый процент.
- Считайте уникальных пользователей, если вопрос про опыт человека; сессии — если вопрос про конкретную попытку.
- Выбирайте окно по реальному циклу: 20 минут для checkout и несколько дней для B2B onboarding — это разные задачи.
- Разбирайте переходы между шагами, а не только общий conversion rate.
Сначала сформулируйте путь словами
До настройки событий полезно произнести воронку обычной фразой. Например: «Новый пользователь увидел pricing, начал регистрацию, создал workspace и открыл первый отчёт в течение семи дней». Если фразу нельзя сказать без оговорок, воронку ещё рано собирать: скорее всего, вы смешали два разных маршрута.
Один и тот же итоговый event может жить в разных путях. Покупка после повторного визита и покупка в первой сессии — не одна конверсия. Первая больше говорит про весь спрос и маркетинг, вторая — про ясность предложения и friction в checkout.
| Настройка | Вопрос, на который отвечает |
|---|---|
| Единица | Считаем людей, аккаунты, устройства или сессии? |
| Вход | Кто попадает в знаменатель: все визиты, новые пользователи, пользователи с намерением? |
| Порядок | Шаги должны идти строго друг за другом или между ними допустимы другие действия? |
| Окно | Сколько времени пользователю нормально нужно, чтобы закончить путь? |
| Цель | Какой event доказывает результат: payment_succeeded, report_viewed, lead_qualified? |
Воронка должна показывать количество и переход
Итоговая конверсия здесь 11,5%, но для решения важнее не сам процент, а форма пути. Между первым визитом и началом регистрации теряется 71% входа. Потом до первого отчёта доходит заметная часть тех, кто уже создал workspace. Значит, начинать расследование с финального экрана нельзя: сначала нужно понять, почему люди не решаются начать путь.
Значения условные. Под каждым шагом видно долю от входа; именно переходы дают гипотезы для проверки.
Closed funnel, open funnel и порядок событий
Closed funnel считает только тех, кто вошёл с первого шага. Он хорош для диагностики конкретного сценария: например, pricing → registration → first report. Open funnel разрешает пользователю появиться на любом шаге, поэтому удобен для проверки целого процесса и качества данных, но не отвечает на тот же вопрос.
Порядок тоже меняет смысл. Для onboarding чаще нужен порядок «сначала это, потом то»: иначе пользователь мог создать workspace вчера, а открыть pricing сегодня, и система назовёт это одним успешным путём. В продукте между основными шагами обычно допустимы другие действия; требовать exact order стоит только для действительно жёсткого технического процесса.
Если в прошлом месяце в BI считали уникальных пользователей за 7 дней, а в новом отчёте сессии за 24 часа, цифры могут разойтись без единого изменения в продукте. В названии графика лучше сразу писать единицу, окно и режим.
SQL для последовательной onboarding-воронки
Ниже один из прозрачных способов посчитать closed funnel по пользователям. Запрос написан для учебной базы симулятора SQL-аналитика, и путь в нём свой: регистрация → рабочее пространство → отчёт → экспорт. Каждый следующий CTE присоединяется к предыдущему шагу и проверяет окно в семь дней от регистрации. Это важнее, чем просто проверить наличие всех трёх событий у одного user_id: порядок и срок здесь часть определения метрики.
Вход — 4 142 человека, зарегистрированных по 23 августа: у них семь дней уже прошли. Пространство создали 2 485 (60,0%), отчёт после него — 1 611 (38,9% от входа), экспорт после отчёта — 612 (14,8%). Без проверки порядка экспорт нашёлся бы у 912 человек той же когорты: 300 сделали его, не создав отчёта, и последовательная воронка их не считает.
with signup as (
select user_id, signup_date as signup_at
from users
where signup_date + 6 <= date '2026-08-29' -- семь дней прожиты к последнему полному дню
),
workspace as (
select s.user_id, s.signup_at, min(e.event_time) as workspace_at
from signup s
join events e on e.user_id = s.user_id
and e.event_name = 'workspace_created'
and e.event_time >= s.signup_at
and e.event_time < s.signup_at + interval '7 days'
group by s.user_id, s.signup_at
),
report as (
select w.user_id, w.signup_at, min(e.event_time) as report_at
from workspace w
join events e on e.user_id = w.user_id
and e.event_name = 'report_created'
and e.event_time >= w.workspace_at
and e.event_time < w.signup_at + interval '7 days'
group by w.user_id, w.signup_at
),
exported as (
select distinct r.user_id
from report r
join events e on e.user_id = r.user_id
and e.event_name = 'export_completed'
and e.event_time >= r.report_at
and e.event_time < r.signup_at + interval '7 days'
),
steps as (
select 1 as step_no, 'signup' as step, count(*) as users from signup
union all select 2, 'workspace_created', count(*) from workspace
union all select 3, 'report_created', count(*) from report
union all select 4, 'export_completed', count(*) from exported
)
select step_no, step, users,
round(100.0 * users / max(users) over (), 1) as pct_of_entry,
round(100.0 * users / lag(users) over (order by step_no), 1) as pct_of_previous
from steps
order by step_no;Как найти причину drop-off
Большой drop-off — это место для вопроса, а не готовый диагноз. Сравните тех, кто прошёл переход, с теми, кто остановился: канал, платформа, браузер, тариф, скорость загрузки, ошибки, время между шагами. Если конверсия просела только на Android после релиза, она уже не похожа на общую проблему смысла pricing-страницы.
Не забывайте про размер базы. Переход с 8% до 4% в сегменте из 30 пользователей может быть шумом. Падение с 29% до 24% на десятках тысяч пользователей уже стоит разложить по версии приложения и источнику трафика, а затем подтвердить гипотезу экспериментом или качественным исследованием.
- Сравните переходы по каналам, платформам и новым когортам.
- Посмотрите медианное время между шагами, а не только факт прохождения.
- Проверьте ошибки и технические события рядом с проблемным шагом.
- Узнайте, что делают пользователи вместо следующего шага: уходят, возвращаются назад, ищут помощь или идут другим маршрутом.
- Не называйте корреляцию причиной без дополнительной проверки.
Открытая и последовательная воронка
В открытой воронке каждый шаг считается от своей аудитории. Она отвечает на вопрос: сколько пользователей дошло до конкретного действия вообще? В последовательной воронке шаги должны идти в заданном порядке и обычно в одном окне. Она отвечает на другой вопрос: какой процент пользователей прошёл путь от старта до результата без пропуска этапов. Оба режима полезны, но их конверсию нельзя сравнивать как одну метрику.
Выбор режима зависит от сценария. Для checkout важна последовательность: просмотр товара, корзина, оплата. Для исследования функций может быть полезно узнать, сколько зарегистрированных когда-либо создали проект, даже если они сначала посмотрели документацию. Подпишите режим в названии отчёта и зафиксируйте допустимое время между шагами.
| Режим | Знаменатель шага | Риск неправильного вывода |
|---|---|---|
| Последовательная | пользователи, прошедшие предыдущий шаг | путь зависит от порядка и окна |
| Открытая | одна и та же стартовая база | можно принять параллельный сценарий за линейный |
| Обе | заранее определённая когорта | смешать пользователей разных периодов и версий |
Знаменатель и атрибуция меняют конверсию
Конверсия — это не только деление двух чисел. Нужно понимать, кто попал в стартовую когорту и как долго ему разрешено пройти путь. Если в числителе заказ за семь дней, а знаменатель — все пользователи, зарегистрированные за месяц, показатель будет занижен. Если новые пользователи продолжают добавляться в незакрытое окно, вчерашняя конверсия может меняться задним числом.
Отдельно договоритесь об атрибуции: пользователь считается один раз по первой сессии, по первому источнику или по кампании, которая привела к конкретному шагу. Для продуктового анализа обычно полезно хранить исходный acquisition channel и отдельно канал последнего касания. Не смешивайте их в одном поле, иначе объяснение разницы между сегментами станет спором о данных.
- Зафиксируйте стартовое событие и размер когорты.
- Укажите окно: одна сессия, 24 часа, 7 или 30 дней.
- Разделите first-touch и last-touch attribution.
- Отдельно учти повторные попытки и дубликаты заказов.
- Не сравнивайте незрелые когорты с полностью дозревшими.
Одна неделя, один числитель, три конверсии: 11,4%, 9,0% и 8,1%
Окно и атрибуция меняют результат заметно, а сущность знаменателя меняет его молча: в отчёте стоит слово «конверсия», и по нему не видно, кого поделили. Возьмите условную неделю мобильного магазина. Корзину открыли 9 400 уникальных пользователей, это случилось в 12 800 сессиях, и корзин как объектов создано 14 200 — часть людей собирает несколько. Оплат прошло 1 150, сделали их 1 070 человек: 80 покупателей за неделю оформили по два заказа.
Из этих пяти чисел получаются три честные конверсии. По людям: 1 070 / 9 400 = 11,4% — какая доля тех, кто начал покупку, её закончила. По сессиям: 1 150 / 12 800 = 9,0% — какая доля визитов с корзиной закончилась оплатой. По корзинам: 1 150 / 14 200 = 8,1% — сколько собранных корзин доживает до кассы. Все три посчитаны правильно, и разброс между крайними — 3,3 процентных пункта. Если в одном отчёте квартал считали по сессиям, а в следующем по пользователям, «рост на четверть» произойдёт без единого изменения в продукте.
Порядок 11,4 → 9,0 → 8,1 задан данными примера, а не законом. От людей к сессиям растут и знаменатель, и числитель, и конверсия падает, пока знаменатель растёт быстрее: здесь на человека приходится 1,36 сессии с корзиной, а на покупателя — 1,07 оплаченной. У продукта с частыми повторными покупками бывает наоборот: постоянные покупатели дают много оплаченных сессий, и сессионная конверсия честно оказывается выше пользовательской. Поэтому обратный порядок — повод сравнить эти два отношения, а не готовый диагноз. Ошибка сборки вероятна, когда повторных покупок почти нет: тогда в знаменатель попали не все сессии или в числитель — оплаты, которых в этих сессиях не было.
Четвёртая строка в таблице ниже — типовая ошибка, а не вариант расчёта. 1 150 оплат, поделённые на 9 400 пользователей, дают 12,2%, и это число не отвечает ни на один вопрос: в числителе события, в знаменателе люди. У продукта с частыми повторными покупками такая дробь спокойно уходит за 100%, и тогда ошибку замечают. При 12,2% её не замечает никто.
Отдельно от сущности стоит вопрос, кто вообще имел право дойти до шага. Из 9 400 человек 1 100 открыли корзину из стран, где не подключён ни один способ оплаты: они физически не могли купить. Уберите их из базы — и пользовательская конверсия становится 1 070 / 8 300 = 12,9% вместо 11,4%. Та же правка работает и в обратную сторону: если продуктовая команда хочет знать, сколько людей упирается в отсутствие оплаты, их нужно оставить и вынести в отдельный сегмент, а не растворять в общем проценте.
Последняя поправка — повторные попытки. 150 пользователей после отказа банка пробовали оплатить снова, добавив в базу около 300 лишних сессий. Склей попытки одного человека внутри корзины в одну — сессий остаётся 12 500, конверсия 9,2%. Разница невелика, но именно она создаёт ложный сигнал при сравнении периодов: в неделю, когда банк массово отклонял платежи, число попыток подскочит, и сессионная конверсия упадёт сама по себе. Поэтому в названии метрики сущность называется явно: paid_sessions / cart_sessions, а не «конверсия корзины».
Запрос под таблицей выполняется как есть. Сессий и корзин в учебной базе симулятора нет, поэтому события заданы прямо в нём: четыре человека, пять сессий, шесть корзин, две оплаты. Он возвращает 50,0%, 40,0% и 33,3% — тот же порядок, что в таблице.
| Сущность | Знаменатель | Числитель | Конверсия | Вопрос, на который отвечает |
|---|---|---|---|---|
| Пользователи | 9 400 открыли корзину | 1 070 покупателей | 11,4% | какая доля людей довела покупку до конца |
| Сессии | 12 800 сессий с корзиной | 1 150 сессий с оплатой | 9,0% | какая доля визитов закончилась оплатой |
| Корзины | 14 200 созданных корзин | 1 150 оплаченных корзин | 8,1% | сколько корзин доживает до кассы |
| Смесь | 9 400 пользователей | 1 150 оплат | 12,2% | ни на какой: события поделены на людей |
with shop_events (user_id, session_id, cart_id, event_name) as (
-- учебная вставка: в учебной базе нет сессий и корзин
values
(1, 11, 101, 'cart_opened'), (1, 12, 102, 'cart_opened'), (1, 12, 102, 'purchase'),
(2, 21, 201, 'cart_opened'), (2, 21, 202, 'cart_opened'), (2, 21, 201, 'purchase'),
(3, 31, 301, 'cart_opened'), (3, 31, 301, 'cart_opened'),
(4, 41, 401, 'cart_opened')
),
cart as (
select user_id, session_id, cart_id
from shop_events
where event_name = 'cart_opened'
group by 1, 2, 3
),
paid as (
select user_id, session_id, cart_id
from shop_events
where event_name = 'purchase'
group by 1, 2, 3
)
select
round(100.0 * count(distinct p.user_id)
/ nullif(count(distinct c.user_id), 0), 1) as conv_users,
round(100.0 * count(distinct p.session_id)
/ nullif(count(distinct c.session_id), 0), 1) as conv_sessions,
round(100.0 * count(distinct p.cart_id)
/ nullif(count(distinct c.cart_id), 0), 1) as conv_carts
from cart c
left join paid p on p.cart_id = c.cart_id;Назовите сущность в числителе и в знаменателе, и пусть это будет одна и та же сущность. Дальше проверьте право дойти до шага и склейку повторных попыток. Если пользовательская конверсия оказалась ниже сессионной, посмотрите, сколько оплаченных сессий приходится на покупателя: при частых повторных покупках такой порядок нормален, без них — признак того, что числитель и знаменатель собраны по разным правилам.
Drop-off — место для диагностики, а не готовая причина
Большой провал между шагами помогает выбрать место исследования, но не объясняет поведение. На одном и том же участке могут работать разные причины: пользователю неясна ценность, форма не помещается на мобильном экране, платёж отклоняется, событие не отправляется или часть аудитории вообще не должна была проходить этот шаг.
Сначала соберите операционный разрез: пользователи, доля, медианное время, ошибки и повторные попытки. Затем сравните сегменты и версии. Если drop-off появился после релиза только в Safari, это техническая гипотеза. Если он стабильно выше у пользователей из конкретного рекламного обещания, исследуйте качество трафика. Если проблема одинакова везде, можно переходить к UX-исследованию или эксперименту.
| Поле | Зачем |
|---|---|
| users | понимать абсолютный масштаб потери |
| conversion | сравнивать шаги и периоды |
| median time | видеть задержку и повторные попытки |
| error rate | отделять UX-проблему от технической |
| segment | найти локальную причину вместо среднего |
Общая конверсия не дрогнула, потому что сломанный mobile унёс и свой знаменатель
В августе конверсия корзина → оплата была 6,58%, в сентябре — 6,59%. По этому числу дежурный вывод: ничего не случилось, смотрим дальше. Разрежьте по платформе, и картина другая. На мобильных конверсия упала с 6,10% до 4,80%, на desktop осталась 8,20%. Ровная общая линия получилась из двух событий сентября: релиз 1 сентября сломал оплату сохранённой картой в приложении, а маркетинг в тот же месяц перенёс бюджет в desktop-поиск, и доля платформ поменялась с 75/25 на 47/53.
Сложение считается в одну строку. 38 000 × 4,80% + 42 000 × 8,20% = 1 824 + 3 444 = 5 268 оплат. В августе было 3 660 + 1 600 = 5 260. Оплат столько же, сессий тоже 80 000 — и средний процент честно показывает, что ничего не изменилось. Механику подмены веса качеством мы разбирали отдельно: агрегат всегда взвешивает сегменты их размером, а размер в сентябре уехал в сторону здоровой платформы.
Цена вывода «ничего не случилось» считается так же просто. При августовской конверсии те же 38 000 мобильных сессий дали бы 2 318 оплат — значит, на сломанном шаге потеряно 494 покупки за месяц. Это только видимая часть: мобильных сессий с корзиной стало на 22 000 меньше, потому что часть пользователей не доезжала и до корзины. Пересчитывать их по старой конверсии уже некорректно — состав трафика изменился, — но сам провал базы на 37% в одном сегменте это сигнал не слабее, чем провал конверсии.
Здесь же прячется ловушка обратного знака. Когда сегмент ломается, он теряет не только конверсию, но и вес: его доля в знаменателе падает, и вклад его низкого процента в среднее становится меньше. Чем сильнее поломка, тем меньше она видна в общей цифре. Поэтому по каждому разрезу нужно смотреть два числа рядом — конверсию и размер базы, — и настораживаться, когда они падают вместе.
Разрезы добавляются по одному и с абсолютными числами. Сортировать сегменты имеет смысл не по разнице в процентах, а по потере в людях: изменение конверсии, умноженное на базу. Сегмент «iOS 17.4, 900 сессий» с падением на 9 п.п. стоит 81 оплату, а весь mobile с падением на 1,3 п.п. — 494. Первый выглядит драматичнее, второй стоит денег. Заодно проверьте, выдерживает ли сегмент арифметику: на 900 сессиях при конверсии около 5% доверительный интервал примерно ±1,4 п.п., и разница в 2 пункта между такими срезами ещё ничего не значит.
Последнее ограничение метода — число проверок. Шесть разрезов на четыре шага воронки за два месяца дают под пятьдесят сравнений, и хотя бы в одном «падение» найдётся всегда, даже если продукт не менялся. Поэтому список разрезов и порог интереса фиксируют до того, как открывают отчёт, а найденный сегмент подтверждают вторым независимым сигналом: логами ошибок, записями сессий, жалобами в поддержку или экспериментом.
| Месяц | Платформа | Сессий с корзиной | Оплат | Конверсия |
|---|---|---|---|---|
| Август | mobile | 60 000 | 3 660 | 6,10% |
| Август | desktop | 20 000 | 1 600 | 8,00% |
| Август | всего | 80 000 | 5 260 | 6,58% |
| Сентябрь | mobile | 38 000 | 1 824 | 4,80% |
| Сентябрь | desktop | 42 000 | 3 444 | 8,20% |
| Сентябрь | всего | 80 000 | 5 268 | 6,59% |
Условный пример. Ровная линия «всего» — не стабильность, а сумма двух разных историй с меняющимися весами.
Что почитать дальше
Воронка часто начинается ещё до продукта: пользователь должен получить первую ценность, а команда — убедиться, что её определение не подменено удобным кликом. После прохождения воронки следующий вопрос — какие сегменты приносят деньги и не маскирует ли средняя выручка потерю качества.
Материалы по теме

Как посчитать воронку в SQL: шаги, конверсия и drop-off
Пошагово собираем продуктовую воронку в SQL: считаем пользователей на каждом этапе, выбираем знаменатель конверсии и находим место наибольшего отвала.

Конверсия: что это, формула и как считать без ошибок
Конверсия — доля тех, кто сделал целевое действие, среди тех, кто мог его сделать. Формула CR, выбор знаменателя, окно конверсии, шаги воронки, сегменты и почему нельзя усреднять конверсии — на примерах с учебной базы.

Retention по когортам и каналам: как считать D1, D7 и D30
Как считать retention rate, D1/D7/D30 и когортную возвращаемость: выбрать return event, читать heatmap и находить слабые каналы.