Magic Number: как найти действие, которое удерживает пользователей
Что такое magic number в продуктовой аналитике?
Magic number в продуктовой аналитике — это конкретное действие, совершённое минимальное количество раз в ранний период, после которого вероятность удержания пользователя резко возрастает. Формула: «пользователь, совершивший X ≥ N раз за первые D дней, остаётся с вероятностью Y%» — и подтверждается когортным анализом и A/B-тестом.
TL;DR
- -Facebook: 7 друзей за 10 дней → ~3x retention. Slack: 2000 сообщений команды → 93% продолжали платить. Dropbox: 1 расшаренный файл → 4x конверсия в платный план
- -Формула magic number: пользователь совершил действие X ≥ N раз за первые D дней → вероятность удержания резко возрастает
- -SQL-запрос когортного анализа считает частоту действий каждого пользователя в activation window и сопоставляет с 30-day retention
- -AI-промпт кластеризует действия по влиянию на retention — исключает ручную корреляцию и расставляет приоритеты автоматически
- -Финальный шаг — A/B-тест: подталкивание к magic action должно улучшать retention, а не просто коррелировать с ним
У Facebook в 2009 году аналитики нашли закономерность: пользователи, добавившие 7 друзей за первые 10 дней, оставались в продукте значительно чаще остальных. У Slack порог оказался другим: 2000 сообщений в команде. У Dropbox — одно расшаренное действие с файлом. Каждый из этих продуктов нашёл свой magic number: пороговое количество действий, после которого вероятность удержания резко возрастает.
Статья о том, как найти magic number собственного продукта: от сырых событий в базе до конкретного числа, подтверждённого данными. С SQL-запросами для когортного анализа, промптами для AI-корреляции и методологией валидации.
Что такое magic number
Magic number — это конкретное действие, совершённое конкретное число раз в конкретный период, после которого retention пользователя скачкообразно растёт. Не абстрактная метрика вовлечённости, а точная формула: “пользователь, который сделал X минимум N раз за первые D дней, остаётся с вероятностью Y%”.
Примеры из реальных продуктов:
- Facebook: 7 друзей за 10 дней. Retention пользователей с 7+ друзьями в 3 раза выше, чем у остальных.
- Slack: 2000 сообщений в команде. После этого порога 93% команд продолжали платить за продукт.
- Twitter (X): подписка на 30 аккаунтов. Пользователи с 30+ подписками возвращались на 60% чаще.
- Dropbox: 1 файл в shared folder. Одно коллаборативное действие увеличивало вероятность перехода на платный план в 4 раза.
Magic number работает на двух уровнях. На уровне продукта он показывает, куда направить ресурсы: онбординг, UX, маркетинг. На уровне unit-экономики он напрямую влияет на LTV, так как каждый процент прироста retention снижает стоимость привлечения.
Подготовка данных
Перед поиском корреляций нужны чистые данные. Минимальный набор: таблица событий с user_id, event_name, timestamp и таблица пользователей с датой регистрации.
Структура таблиц
-- Таблица событий (events)
-- user_id | event_name | event_timestamp | properties (jsonb)
-- Таблица пользователей (users)
-- user_id | created_at | acquisition_source | plan
Определение retention
Для magic number анализа используется N-day retention: вернулся ли пользователь на день N после регистрации. Стандартный выбор — 30-day retention. Для продуктов с коротким циклом (мессенджеры, игры) подойдёт 7-day. Для B2B SaaS с длинным онбордингом — 60 или 90 дней.
-- Базовая таблица retention: вернулся ли пользователь на 30-й день
WITH user_retention AS (
SELECT
u.user_id,
u.created_at,
CASE
WHEN EXISTS (
SELECT 1 FROM events e
WHERE e.user_id = u.user_id
AND e.event_timestamp::date
BETWEEN u.created_at::date + INTERVAL '27 days'
AND u.created_at::date + INTERVAL '33 days'
) THEN 1
ELSE 0
END AS retained_day30
FROM users u
WHERE u.created_at < NOW() - INTERVAL '33 days'
)
SELECT
COUNT(*) AS total_users,
SUM(retained_day30) AS retained_users,
ROUND(100.0 * SUM(retained_day30) / COUNT(*), 2) AS retention_rate
FROM user_retention;
Окно ±3 дня (27–33) вместо точного 30-го дня сглаживает шум. Пользователь, вернувшийся на 29-й или 31-й день, по поведению не отличается от вернувшегося ровно на 30-й.
Когортный анализ действий в SQL
Задача: посчитать для каждого типа действия, сколько раз его совершил каждый пользователь в первые N дней, и сопоставить с retention.
Подсчёт действий в активационном окне
-- Количество каждого действия на пользователя за первые 14 дней
WITH activation_actions AS (
SELECT
e.user_id,
e.event_name,
COUNT(*) AS action_count
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.event_timestamp BETWEEN u.created_at
AND u.created_at + INTERVAL '14 days'
GROUP BY e.user_id, e.event_name
)
SELECT * FROM activation_actions;
Почему 14 дней? Это стандартное активационное окно. Слишком короткое (1–3 дня) отсечёт пользователей с медленным онбордингом. Слишком длинное (30+ дней) смешает причину и следствие: пользователь не потому остался, что сделал действие на 25-й день, а потому что уже решил остаться.
Корреляция действий с retention
-- Retention rate для каждого действия и порогового количества
WITH user_retention AS (
SELECT
u.user_id,
u.created_at,
CASE
WHEN EXISTS (
SELECT 1 FROM events e
WHERE e.user_id = u.user_id
AND e.event_timestamp::date
BETWEEN u.created_at::date + INTERVAL '27 days'
AND u.created_at::date + INTERVAL '33 days'
) THEN 1
ELSE 0
END AS retained_day30
FROM users u
WHERE u.created_at < NOW() - INTERVAL '33 days'
),
activation_actions AS (
SELECT
e.user_id,
e.event_name,
COUNT(*) AS action_count
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.event_timestamp BETWEEN u.created_at
AND u.created_at + INTERVAL '14 days'
GROUP BY e.user_id, e.event_name
),
thresholds AS (
SELECT generate_series(1, 20) AS threshold
)
SELECT
aa.event_name,
t.threshold,
COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
THEN ur.user_id END) AS users_above,
COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
AND ur.retained_day30 = 1 THEN ur.user_id END) AS retained_above,
ROUND(
100.0 * COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
AND ur.retained_day30 = 1 THEN ur.user_id END)
/ NULLIF(COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
THEN ur.user_id END), 0),
2
) AS retention_rate_above,
ROUND(
100.0 * COUNT(DISTINCT CASE WHEN (aa.action_count < t.threshold
OR aa.action_count IS NULL)
AND ur.retained_day30 = 1 THEN ur.user_id END)
/ NULLIF(COUNT(DISTINCT CASE WHEN aa.action_count < t.threshold
OR aa.action_count IS NULL THEN ur.user_id END), 0),
2
) AS retention_rate_below
FROM user_retention ur
LEFT JOIN activation_actions aa ON ur.user_id = aa.user_id
CROSS JOIN thresholds t
GROUP BY aa.event_name, t.threshold
HAVING COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
THEN ur.user_id END) >= 30
ORDER BY
(ROUND(
100.0 * COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
AND ur.retained_day30 = 1 THEN ur.user_id END)
/ NULLIF(COUNT(DISTINCT CASE WHEN aa.action_count >= t.threshold
THEN ur.user_id END), 0), 2)
-
ROUND(
100.0 * COUNT(DISTINCT CASE WHEN (aa.action_count < t.threshold
OR aa.action_count IS NULL)
AND ur.retained_day30 = 1 THEN ur.user_id END)
/ NULLIF(COUNT(DISTINCT CASE WHEN aa.action_count < t.threshold
OR aa.action_count IS NULL THEN ur.user_id END), 0), 2))
DESC;
Этот запрос перебирает пороги от 1 до 20 для каждого типа события. Для каждой пары (событие, порог) считает retention среди пользователей выше и ниже порога. Результат сортируется по разнице в retention: чем больше разрыв, тем сильнее корреляция.
Фильтр HAVING >= 30 отсекает пороги с малой выборкой. Retention 100% при двух пользователях ничего не значит.
Чтение результатов
Пример выходных данных:
| event_name | threshold | users_above | retained_above | retention_above | retention_below |
|---|---|---|---|---|---|
| invite_teammate | 3 | 847 | 612 | 72.25% | 18.40% |
| create_project | 5 | 1203 | 780 | 64.84% | 22.10% |
| share_document | 2 | 1456 | 890 | 61.13% | 20.50% |
| add_integration | 1 | 634 | 365 | 57.57% | 24.30% |
В этом примере invite_teammate >= 3 даёт максимальный разрыв: 72.25% против 18.40%. Разница в 53.85 п.п. Это сильный кандидат на magic number.
AI-корреляция: промпты для анализа
SQL-запросы дают таблицы. AI помогает интерпретировать результаты, найти неочевидные паттерны и отфильтровать ложные корреляции.
Промпт 1: анализ корреляционной таблицы
Ты product-аналитик. Вот таблица корреляции действий пользователей
с 30-day retention (CSV прилагается).
Задача:
1. Определи ТОП-3 действия с наибольшим разрывом в retention
между пользователями выше и ниже порога.
2. Для каждого кандидата оцени:
- Достаточность выборки (users_above > 100)
- Наличие "перелома" (резкий рост retention на конкретном пороге)
- Риск обратной каузальности: действие вызывает retention
или retention вызывает действие?
3. Предложи финального кандидата на magic number с обоснованием.
Формат ответа: таблица кандидатов + вердикт + следующие шаги.
Промпт 2: поиск скрытых паттернов
Проанализируй сырые события пользователей (CSV прилагается).
Колонки: user_id, event_name, event_timestamp, retained_day30.
Найди комбинации действий, которые предсказывают retention лучше,
чем одиночные события. Например:
- Пользователь сделал A И B (но не обязательно C)
- Пользователь сделал A в первые 3 дня (а не в первые 14)
- Пользователь сделал A минимум N раз И B минимум M раз
Для каждой найденной комбинации укажи:
- Retention rate для группы "выполнили условие"
- Retention rate для группы "не выполнили"
- Размер выборки обеих групп
- Lift (отношение retention выше/ниже порога)
Промпт 3: валидация кандидата
Кандидат на magic number: [действие] >= [порог] за первые [N] дней.
Данные:
- Retention выше порога: X%
- Retention ниже порога: Y%
- Размер выборки: Z пользователей
Проведи критический анализ:
1. Может ли корреляция быть ложной? Какие confounders возможны?
(источник трафика, платный/бесплатный план, время регистрации)
2. Проверь на survivorship bias: не считаем ли мы только тех,
кто и так бы остался?
3. Предложи SQL-запрос для контроля confounders
(стратификация по acquisition source, plan type).
4. Определи минимальный размер A/B теста для подтверждения
каузальной связи (alpha=0.05, power=0.8).
Поиск magic number по шагам
Полный процесс от идеи до подтверждённого magic number.
Шаг 1. Инвентаризация событий
Выгрузить все уникальные event_name с количеством пользователей, совершивших каждое:
SELECT
event_name,
COUNT(DISTINCT user_id) AS unique_users,
COUNT(*) AS total_occurrences,
ROUND(COUNT(*)::numeric / COUNT(DISTINCT user_id), 1)
AS avg_per_user
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.event_timestamp BETWEEN u.created_at
AND u.created_at + INTERVAL '14 days'
GROUP BY event_name
ORDER BY unique_users DESC;
Отфильтровать события, которые совершает менее 5% пользователей: их влияние на общий retention будет минимальным даже при сильной корреляции.
Шаг 2. Корреляционный анализ
Запустить основной запрос из раздела выше. Получить таблицу (event_name, threshold, retention_above, retention_below). Отсортировать по разрыву.
Шаг 3. Визуализация порогов
Для ТОП-5 кандидатов построить график: ось X — порог (1, 2, 3, …, 20), ось Y — retention rate. Искать “перелом”: точку, после которой retention перестаёт расти или растёт значительно медленнее. Это и есть magic number.
-- Данные для графика retention vs threshold по конкретному событию
WITH user_ret AS (
SELECT
u.user_id,
CASE
WHEN EXISTS (
SELECT 1 FROM events e
WHERE e.user_id = u.user_id
AND e.event_timestamp::date
BETWEEN u.created_at::date + INTERVAL '27 days'
AND u.created_at::date + INTERVAL '33 days'
) THEN 1
ELSE 0
END AS retained
FROM users u
WHERE u.created_at < NOW() - INTERVAL '33 days'
),
action_counts AS (
SELECT
e.user_id,
COUNT(*) AS cnt
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.event_name = 'invite_teammate' -- заменить на нужное
AND e.event_timestamp BETWEEN u.created_at
AND u.created_at + INTERVAL '14 days'
GROUP BY e.user_id
)
SELECT
t.n AS threshold,
COUNT(DISTINCT CASE WHEN ac.cnt >= t.n THEN ur.user_id END)
AS users_above,
ROUND(
100.0 * COUNT(DISTINCT CASE WHEN ac.cnt >= t.n
AND ur.retained = 1 THEN ur.user_id END)
/ NULLIF(COUNT(DISTINCT CASE WHEN ac.cnt >= t.n
THEN ur.user_id END), 0),
2
) AS retention_pct
FROM user_ret ur
LEFT JOIN action_counts ac ON ur.user_id = ac.user_id
CROSS JOIN generate_series(1, 20) AS t(n)
GROUP BY t.n
ORDER BY t.n;
Типичный график перелома: retention растёт с 20% при threshold=1 до 65% при threshold=5, потом выходит на плато (67% при threshold=6, 68% при threshold=7). Magic number = 5.
Шаг 4. Контроль confounders
Magic number бесполезен, если корреляция объясняется внешним фактором. Три обязательных проверки:
Источник трафика. Пользователи из органического поиска часто активнее платных. Если invite_teammate >= 3 работает только для органики, это свойство аудитории, а не magic number продукта.
-- Стратификация по источнику трафика
SELECT
u.acquisition_source,
CASE WHEN ac.cnt >= 3 THEN 'above' ELSE 'below' END AS segment,
COUNT(*) AS users,
ROUND(100.0 * SUM(ur.retained) / COUNT(*), 2) AS retention_pct
FROM user_ret ur
JOIN users u ON ur.user_id = u.user_id
LEFT JOIN action_counts ac ON ur.user_id = ac.user_id
GROUP BY u.acquisition_source, segment
ORDER BY u.acquisition_source, segment;
План/тариф. Платящие пользователи удерживаются лучше по определению. Проверить, что magic number работает внутри каждого тарифа отдельно.
Время регистрации. Сезонность, маркетинговые кампании, изменения продукта. Разбить когорты по месяцам и убедиться, что корреляция стабильна.
Шаг 5. Проверка каузальности через A/B тест
Корреляция не доказывает причинно-следственную связь. Единственный способ подтвердить, что действие вызывает retention: провести эксперимент.
Дизайн A/B теста:
- Контроль: стандартный онбординг.
- Тест: онбординг, который подталкивает к magic number действию (подсказки, упрощённый flow, гамификация).
- Метрика: 30-day retention.
- Размер выборки: рассчитать через формулу или калькулятор (Evan Miller, Optimizely).
Для разрыва в retention 20 п.п. (30% vs 50%) при alpha=0.05 и power=0.8 минимальная выборка — около 200 пользователей на группу. Для разрыва в 5 п.п. потребуется уже 1600+ на группу.
Если A/B тест подтверждает: группа с подталкиванием показывает значимо более высокий retention, magic number валиден. Можно перестраивать онбординг вокруг него.
Мониторинг в продакшене
Найденный magic number требует мониторинга. Два ключевых дашборда:
Activation rate
Доля новых пользователей, достигших magic number за активационное окно:
SELECT
DATE_TRUNC('week', u.created_at) AS cohort_week,
COUNT(DISTINCT u.user_id) AS total_users,
COUNT(DISTINCT CASE WHEN ac.cnt >= 3 THEN u.user_id END)
AS activated_users,
ROUND(
100.0 * COUNT(DISTINCT CASE WHEN ac.cnt >= 3 THEN u.user_id END)
/ COUNT(DISTINCT u.user_id), 2
) AS activation_rate
FROM users u
LEFT JOIN (
SELECT user_id, COUNT(*) AS cnt
FROM events
WHERE event_name = 'invite_teammate'
GROUP BY user_id
) ac ON u.user_id = ac.user_id
WHERE u.created_at >= NOW() - INTERVAL '12 weeks'
AND u.created_at < NOW() - INTERVAL '2 weeks'
GROUP BY cohort_week
ORDER BY cohort_week;
Падение activation rate — сигнал о проблеме в онбординге или изменении аудитории.
Стабильность корреляции
Ежемесячно пересчитывать корреляцию magic number с retention. Продукт меняется, аудитория меняется, magic number может сдвинуться. Действие, которое было критичным полгода назад, может потерять значимость после редизайна.
Типичные ошибки
Принять корреляцию за каузацию. Пользователи, которые создали 10 проектов за первую неделю, вероятно, пришли с сильным намерением. Если заставить всех создать 10 проектов, retention не обязательно вырастет.
Игнорировать размер выборки. Magic number с retention 95% на 12 пользователях ничего не стоит. Нужно минимум 100 пользователей в каждой группе, лучше 500+.
Фиксировать magic number навсегда. Facebook нашёл “7 друзей” в 2009. В 2026 их magic number наверняка другой. Пересчёт каждый квартал.
Оптимизировать под метрику, а не под ценность. Если magic number — “отправить 5 сообщений”, задача не в том, чтобы заставить отправлять 5 пустых сообщений. Задача — помочь пользователю получить ценность, которую он получает после 5 реальных сообщений.
Путать активацию и привычку. Magic number описывает порог активации. Дальше работает retention loop. Пользователь прошёл порог, но не нашёл причину возвращаться каждую неделю — retention всё равно упадёт.
С чего начать
- Выгрузить все события за последние 6 месяцев с user_id и timestamp.
- Построить таблицу retention (запрос из раздела “Определение retention”).
- Запустить корреляционный анализ по всем событиям.
- Передать результаты в AI с промптом №1 для интерпретации.
- Визуализировать ТОП-5 кандидатов, найти точку перелома.
- Проверить confounders (источник, план, сезонность).
- Запустить A/B тест с подталкиванием к magic number.
- Настроить мониторинг activation rate и стабильности корреляции.
Весь процесс от выгрузки до первых результатов A/B теста занимает 3–6 недель. Корреляционный анализ — 1–2 дня. Основное время уходит на набор выборки для эксперимента.
Magic number — не серебряная пуля. Это инструмент фокусировки: вместо размытого “улучшить онбординг” появляется конкретная цель с измеримым результатом. Продукт, который знает свой magic number, направляет каждый новый экран, каждый email и каждое push-уведомление на достижение одного числа. И измеряет, работает ли это.