SQLметрикипродуктовая аналитикаDAUretention

DAU, WAU, MAU: в чём разница и как считать

2026-07-10 11 мин

Коротко: DAU, WAU и MAU — это число уникальных активных пользователей за день, неделю и месяц соответственно. Разница между ними не только в длине окна: WAU и MAU считаются по уникальным пользователям внутри периода, поэтому их нельзя получить сложением DAU — один и тот же человек за месяц заходит много раз, и суммирование раздует метрику в разы. Ещё важнее выбрать тип окна: календарное (месяц как в календаре) или скользящее (последние 30 дней от каждой даты). Ниже — формулы, различия и рабочие SQL-запросы, которые считают все три метрики из одной таблицы событий.

Что такое DAU, WAU и MAU?

Три метрики измеряют размер активной аудитории на разных горизонтах:

Ключевое слово во всех трёх — «уникальных». Если пользователь зашёл в приложение 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 для продукта, которым по своей природе пользуются раз в неделю, бессмысленно — метрика будет низкой не из-за плохого продукта, а из-за неверного окна.

Ориентир по частоте ожидаемого использования:

Практический тест: посчитайте, у какой доли активных пользователей интервал между сессиями укладывается в выбранное окно. Если типичный пользователь возвращается раз в 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).

Ориентиры очень зависят от типа продукта, но общий порядок такой:

Важно считать stickiness из согласованных окон: DAU (средний за месяц) делить на MAU за тот же месяц, иначе сравнение бессмысленно. Stickiness хорошо дополняет retention: retention отвечает «вернулись ли», stickiness — «как часто заходят те, кто остался». Подробный разбор с формулами и бенчмарками — в отдельной статье про stickiness DAU/MAU. А то, как в целом устроена воронка активной аудитории от привлечения до дохода, показывают пиратские метрики AARRR.

Какие ошибки в подсчёте активных пользователей встречаются?

Собрал самые дорогие грабли, на которые наступают при расчёте DAU/WAU/MAU:

Каждая из этих ошибок по отдельности искажает картину на десятки процентов, а вместе способны нарисовать «рост», которого нет.

С чего начать на практике?

Соберите одну таблицу событий, зафиксируйте определение активности и посчитайте по ней сразу все три метрики плюс stickiness — это лучшее упражнение, чтобы прочувствовать разницу между окнами. В SQL-тренажёре есть задачи на активных пользователей, rolling-окна и оконные функции на настоящем PostgreSQL: первые 5 задач открыты бесплатно, дальше — по Pro. Если готовитесь к собеседованию, DAU/WAU/MAU и stickiness спрашивают почти на каждом продуктовом интервью — потренируйтесь на подборке вопросов для аналитика и прогоните AI мок-собес, где интервьюер задаёт метрические вопросы и разбирает ответы.

Смежные метрики, которые логично разобрать следом: retention D7 и churn — они показывают уже не размер, а качество удержания активной аудитории. А связать активность с деньгами помогает когортный анализ retention в SQL.

Посчитай DAU, WAU и MAU на живой базе
В тренажёре 425 SQL-задач на настоящем PostgreSQL: оконные функции, rolling-окна, активные пользователи. Первые 5 задач бесплатно, дальше открывается по Pro.
Открыть SQL-тренажёр →