Коротко: DAU, WAU и MAU — это число уникальных активных пользователей за день, неделю и месяц соответственно. Разница между ними не только в длине окна: WAU и MAU считаются по уникальным пользователям внутри периода, поэтому их нельзя получить сложением DAU — один и тот же человек за месяц заходит много раз, и суммирование раздует метрику в разы. Ещё важнее выбрать тип окна: календарное (месяц как в календаре) или скользящее (последние 30 дней от каждой даты). Ниже — формулы, различия и рабочие SQL-запросы, которые считают все три метрики из одной таблицы событий.
Что такое DAU, WAU и MAU?
Три метрики измеряют размер активной аудитории на разных горизонтах:
- DAU (Daily Active Users) — сколько уникальных пользователей были активны за один календарный день.
- WAU (Weekly Active Users) — сколько уникальных пользователей были активны хотя бы раз за неделю.
- MAU (Monthly Active Users) — то же за месяц.
Ключевое слово во всех трёх — «уникальных». Если пользователь зашёл в приложение 5 раз за день, в DAU он считается один раз. Именно поэтому в SQL везде будет COUNT(DISTINCT user_id), а не просто COUNT(*).
Второй тонкий момент — определение самой «активности». DAU не считается автоматически: аналитик решает, что такое «активный». Это открытие приложения? Совершённое целевое действие? Просмотр хотя бы одного экрана? В мессенджере активностью может быть отправка сообщения, в банковском приложении — вход, в маркетплейсе — просмотр карточки товара. Одна и та же база событий при разных определениях даёт DAU, отличающийся в 2-3 раза. Поэтому определение активного события фиксируют до расчёта и держат единым для всей команды — иначе метрики из разных дашбордов не сойдутся.
DAU — базовая метрика продуктовой аналитики, о ней подробнее в карточке метрики DAU. А связку активной аудитории с деньгами и удержанием разбирает статья про кривую retention.
Чем скользящее окно отличается от календарного?
Здесь чаще всего путаются. WAU и MAU можно считать двумя принципиально разными способами.
Календарное окно привязано к границам календаря. MAU за октябрь — это уникальные пользователи с 1 по 31 октября. Следующая точка — весь ноябрь. Метрика обновляется раз в месяц, точек на графике мало, зато их легко объяснить бизнесу: «в октябре было 120 тысяч активных».
Скользящее окно (rolling, trailing) считается на каждый день и смотрит на последние N дней назад. Rolling MAU на 15 октября — уникальные пользователи за период с 16 сентября по 15 октября включительно. На 16 октября окно сдвигается на день вперёд. Метрика обновляется ежедневно, график плавный, легко ловить тренд.
| Свойство | Календарное окно | Скользящее окно (rolling) |
|---|---|---|
| Границы | 1-е число месяца / понедельник | Последние 30 (7) дней от даты |
| Частота обновления | Раз в месяц / неделю | Каждый день |
| Точек на графике | Мало | Много, линия плавная |
| Эффект «начала месяца» | Есть (в начале периода метрика низкая) | Отсутствует |
| Когда удобно | Отчётность, сравнение месяцев | Мониторинг, алерты, тренд |
Главная ловушка календарного окна — сравнение неполного периода с полным. Если 5 октября посмотреть на «MAU за октябрь», получится число за 5 дней, а не за месяц, и оно будет выглядеть провалом на фоне сентября. Rolling MAU этой проблемы лишён: он всегда покрывает ровно 30 дней. Для дашбордов мониторинга берут скользящее окно, для управленческой отчётности — календарное.
Какую метрику выбрать под тип продукта?
Выбор между DAU, WAU и MAU как главной метрикой активности зависит от естественной частоты использования продукта. Считать DAU для продукта, которым по своей природе пользуются раз в неделю, бессмысленно — метрика будет низкой не из-за плохого продукта, а из-за неверного окна.
Ориентир по частоте ожидаемого использования:
- Daily-продукты (соцсети, мессенджеры, новости, игры, трекеры) — главная метрика DAU. Ждём, что человек заходит каждый день.
- Weekly-продукты (доставка еды, стриминг, обучающие платформы, фитнес-приложения) — главная метрика WAU. Ежедневный заход не заложен в сценарий.
- Monthly-продукты (банковские выписки, страховки, HR-сервисы, редкие B2B-инструменты) — MAU. Естественный цикл — раз в месяц и реже.
Практический тест: посчитайте, у какой доли активных пользователей интервал между сессиями укладывается в выбранное окно. Если типичный пользователь возвращается раз в 10 дней, DAU будет вечно проседать, а WAU честно покажет здоровье продукта. Выбор главной активной метрики тесно связан с выбором North Star-метрики: активная аудитория часто входит в её формулу.
Ошибка здесь стоит дорого: команда может месяцами «поднимать DAU» в продукте, который по природе weekly, вместо того чтобы работать над удержанием на правильном горизонте.
Почему нельзя суммировать DAU, чтобы получить MAU?
Это самая частая ошибка новичков: «сложу DAU за 30 дней — получу MAU». Нет. Сумма DAU считает пользователя столько раз, сколько дней он был активен, а MAU — ровно один раз за весь месяц.
Разберём на числах. Пусть в продукте всего 3 пользователя за неделю:
| День | Активные пользователи |
|---|---|
| Пн | Аня, Боря |
| Вт | Аня |
| Ср | Аня, Вера |
| Чт | Боря |
| Пт | Аня, Вера |
DAU по дням: 2, 1, 2, 1, 2. Сумма DAU за неделю = 8. А WAU (уникальных за неделю) = 3, потому что всего трое разных людей: Аня, Боря, Вера. Разница почти в три раза — и она тем больше, чем чаще люди возвращаются.
Именно поэтому существует отдельная величина — сумма DAU за период равна не WAU/MAU, а суммарному числу «человеко-дней активности». Это тоже полезная метрика (её иногда называют total active days), но она отвечает на другой вопрос: не «сколько разных людей», а «сколько всего дней активности они дали».
Отношение суммы DAU к MAU, кстати, связано с тем, как часто пользователи возвращаются — по сути это средняя частота визитов, и оно перекликается со stickiness (о нём ниже).
Как посчитать DAU, WAU и MAU в SQL?
Возьмём одну таблицу событий events(user_id, event_time), где каждая строка — действие пользователя. Все три метрики считаются из неё.
DAU по дням — группируем по дате, считаем уникальных:
SELECT
event_time::date AS day,
COUNT(DISTINCT user_id) AS dau
FROM events
GROUP BY event_time::date
ORDER BY day;
Календарные WAU и MAU — та же логика, но группируем по началу недели/месяца через date_trunc:
-- Календарный MAU: уникальные за каждый месяц
SELECT
date_trunc('month', event_time) AS month,
COUNT(DISTINCT user_id) AS mau
FROM events
GROUP BY date_trunc('month', event_time)
ORDER BY month;
-- Календарный WAU: уникальные за каждую неделю (неделя с понедельника)
SELECT
date_trunc('week', event_time) AS week,
COUNT(DISTINCT user_id) AS wau
FROM events
GROUP BY date_trunc('week', event_time)
ORDER BY week;
Скользящий (rolling) MAU — самое интересное. SUM() OVER тут не подходит: он не умеет считать уникальных внутри окна. Надёжный способ — соединить каждый день календаря со всеми событиями за предыдущие 30 дней и посчитать COUNT(DISTINCT):
-- Rolling MAU: для каждого дня — уникальные за последние 30 дней
WITH calendar AS (
SELECT generate_series(
(SELECT min(event_time)::date FROM events),
(SELECT max(event_time)::date FROM events),
INTERVAL '1 day'
)::date AS day
)
SELECT
c.day,
COUNT(DISTINCT e.user_id) AS mau_rolling
FROM calendar c
JOIN events e
ON e.event_time::date > c.day - INTERVAL '30 days'
AND e.event_time::date <= c.day
GROUP BY c.day
ORDER BY c.day;
Rolling WAU — то же самое, но окно - INTERVAL '7 days'. Границы записаны как «строго больше нижней и меньше-либо-равно верхней», чтобы окно покрывало ровно 30 дней без задваивания на стыке.
На больших объёмах такой join бывает тяжёлым. Тогда сначала сжимают события до пар «пользователь — день активности» (одна строка на человека в день), а уже потом джойнят с календарём — так DISTINCT дешевле:
WITH user_days AS (
SELECT DISTINCT user_id, event_time::date AS active_day
FROM events
),
calendar AS (
SELECT generate_series(
(SELECT min(active_day) FROM user_days),
(SELECT max(active_day) FROM user_days),
INTERVAL '1 day'
)::date AS day
)
SELECT
c.day,
COUNT(DISTINCT ud.user_id) AS mau_rolling
FROM calendar c
JOIN user_days ud
ON ud.active_day > c.day - INTERVAL '30 days'
AND ud.active_day <= c.day
GROUP BY c.day
ORDER BY c.day;
Разобрать date_trunc, generate_series и оконные функции с нуля помогает полный гайд по оконным функциям SQL и наш бесплатный курс по SQL. Попрактиковаться в rolling-запросах на живой базе можно прямо в SQL-тренажёре.
Если удобнее считать в Python, та же rolling-логика на pandas выглядит так:
import pandas as pd
# events: DataFrame с колонками user_id, event_time
events['day'] = events['event_time'].dt.normalize()
user_days = events[['user_id', 'day']].drop_duplicates()
# rolling MAU: для каждого дня — уникальные за 30 дней назад
days = pd.date_range(user_days['day'].min(), user_days['day'].max(), freq='D')
rolling_mau = []
for d in days:
window = user_days[(user_days['day'] > d - pd.Timedelta(days=30)) &
(user_days['day'] <= d)]
rolling_mau.append((d, window['user_id'].nunique()))
result = pd.DataFrame(rolling_mau, columns=['day', 'mau_rolling'])
Для боевых объёмов явный цикл заменяют на более быстрые приёмы, но логика та же. Отработать подсчёт уникальных и группировки на pandas можно в Python-тренажёре.
Что такое stickiness и как он связан с этими метриками?
Stickiness («липкость») — метрика вовлечённости, которая показывает, насколько плотно пользователи возвращаются в продукт. Считается предельно просто:
Stickiness = DAU / MAU * 100%
Смысл: какая доля месячной аудитории пользуется продуктом в среднестатистический день. Если MAU = 100 000, а средний DAU = 20 000, то stickiness = 20%. Грубая интерпретация: типичный активный пользователь заходит примерно 6 дней из 30 (0.20 умножить на 30, примерно 6).
Ориентиры очень зависят от типа продукта, но общий порядок такой:
- 20% и выше — сильная вовлечённость, характерно для daily-продуктов (соцсети, мессенджеры).
- 10-20% — здоровый уровень для многих сервисов.
- ниже 10% — продуктом пользуются эпизодически; для monthly-продуктов это норма, для daily — тревожный сигнал.
Важно считать stickiness из согласованных окон: DAU (средний за месяц) делить на MAU за тот же месяц, иначе сравнение бессмысленно. Stickiness хорошо дополняет retention: retention отвечает «вернулись ли», stickiness — «как часто заходят те, кто остался». Подробный разбор с формулами и бенчмарками — в отдельной статье про stickiness DAU/MAU. А то, как в целом устроена воронка активной аудитории от привлечения до дохода, показывают пиратские метрики AARRR.
Какие ошибки в подсчёте активных пользователей встречаются?
Собрал самые дорогие грабли, на которые наступают при расчёте DAU/WAU/MAU:
- **
COUNT(*)вместоCOUNT(DISTINCT user_id). Считаете события, а не людей. Метрика раздувается пропорционально числу действий на пользователя. ВсегдаDISTINCT.
- Суммирование DAU для получения MAU. Разобрали выше: получите человеко-дни, а не уникальных людей. Ошибка завышает MAU в 2-5 раз.
- Смешение календарного и скользящего окна. Сравнивать календарный MAU за неполный текущий месяц с полным прошлым — гарантированный ложный «провал». Держите один тип окна на графике.
- Разные определения «активного» в разных отчётах. В одном дашборде активность — это вход, в другом — целевое действие. Метрики не сходятся, команда спорит о цифрах вместо продукта. Зафиксируйте определение один раз.
- Часовые пояса. DAU по UTC и по московскому времени режут сутки в разных местах. Пользователь, зашедший в 23:30 MSK, попадёт в «завтра» по UTC. Выберите единый пояс для всех расчётов активности.
- Боты, тестовые и внутренние аккаунты. Нагрузочные тесты, сотрудники, краулеры легко добавляют тысячи фейковых активных. Фильтруйте их до расчёта.
- Дубли событий в логах. Ретраи клиента или сбои трубопровода данных плодят повторные записи. Если не дедуплицировать,
DISTINCT user_idспасёт DAU, но total-метрики поедут. Про чистку дублей — дедупликация в SQL.
- Игнорирование сезонности.** Падение DAU в выходные или праздники — часто норма, а не деградация. Сравнивайте день с аналогичным днём недели, а не с вчера. Когда метрика правда упала — помогает фреймворк диагностики падения метрики.
Каждая из этих ошибок по отдельности искажает картину на десятки процентов, а вместе способны нарисовать «рост», которого нет.
С чего начать на практике?
Соберите одну таблицу событий, зафиксируйте определение активности и посчитайте по ней сразу все три метрики плюс stickiness — это лучшее упражнение, чтобы прочувствовать разницу между окнами. В SQL-тренажёре есть задачи на активных пользователей, rolling-окна и оконные функции на настоящем PostgreSQL: первые 5 задач открыты бесплатно, дальше — по Pro. Если готовитесь к собеседованию, DAU/WAU/MAU и stickiness спрашивают почти на каждом продуктовом интервью — потренируйтесь на подборке вопросов для аналитика и прогоните AI мок-собес, где интервьюер задаёт метрические вопросы и разбирает ответы.
Смежные метрики, которые логично разобрать следом: retention D7 и churn — они показывают уже не размер, а качество удержания активной аудитории. А связать активность с деньгами помогает когортный анализ retention в SQL.