MAU: как считать и интерпретировать

Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.

Что такое MAU

MAU — Monthly Active Users. Сколько уникальных пользователей сделали целевое действие за последние 30 дней (или за календарный месяц — об этом ниже). Базовая метрика для продуктов, где использование не каждый день: e-commerce, банкинг, B2B-сервисы, образование с длинными циклами.

В отличие от DAU, MAU сглаживает дни недели и сезонные провалы. Один и тот же пользователь зашёл во вторник или в субботу — MAU всё равно прибавит +1.

MAU полезна не сама по себе, а в связке. Соло-MAU мало что говорит: "у нас миллион MAU" — а как часто заходят, какая когорта живёт долго, кто платит? Без ответов на эти вопросы MAU — просто большое число.

Calendar MAU vs rolling 28-day MAU

Есть две основные версии MAU.

Calendar MAU — уникальные активные за календарный месяц (1–31 марта, 1–30 апреля). Просто считать, привычно для отчётов, но имеет один большой минус: длина месяца меняется (28–31 день), поэтому сравнения месяцев между собой кривые.

Rolling 28-day MAU — уникальные активные за последние 28 дней относительно каждой даты. Сглажено, длина окна одинаковая, удобно для графика. Стандарт во многих больших продуктах.

Что выбирать:

  • Для борд-репортов и финансовых обзоров — calendar MAU (привычнее).
  • Для оперативного мониторинга и графика — rolling 28-day MAU (стабильнее).
  • Не миксуйте: если в дашборде "MAU = 1.2M" в одной плитке и "MAU = 1.15M" в другой — разберитесь, какое определение где.

SQL-шаблоны для MAU

Calendar MAU за прошлый месяц:

SELECT
  DATE_TRUNC('month', event_time AT TIME ZONE 'Europe/Moscow') AS month,
  COUNT(DISTINCT user_id) AS mau
FROM events
WHERE event_name = 'question_answered'
  AND event_time >= DATE_TRUNC('month', NOW() - INTERVAL '6 month')
GROUP BY 1
ORDER BY 1;

Rolling 28-day MAU по дням — здесь нужен корректный паттерн. COUNT(DISTINCT) в оконке Postgres не поддерживает, поэтому используем коррелированный подзапрос или left join по сетке дат:

WITH days AS (
  SELECT generate_series(
    CURRENT_DATE - INTERVAL '90 day',
    CURRENT_DATE - INTERVAL '1 day',
    INTERVAL '1 day'
  )::DATE AS day
)
SELECT
  d.day,
  (SELECT COUNT(DISTINCT e.user_id)
     FROM events e
    WHERE e.event_name = 'question_answered'
      AND e.event_time >= d.day - INTERVAL '27 day'
      AND e.event_time <  d.day + INTERVAL '1 day') AS mau_28d
FROM days d
ORDER BY d.day;

Не пытайтесь через COUNT(DISTINCT user_id) OVER (...) — Postgres его не поддерживает.

На больших объёмах считайте инкрементально: храните факт активности юзера за день, и для rolling MAU агрегируйте предрасчитанную таблицу user_active_days.

Как читать MAU вместе с DAU

Соло-MAU — слабый сигнал. Гораздо полезнее два варианта связки.

DAU/MAU = stickiness. Какая часть месячных юзеров заходит в среднем за день. 0.1–0.2 — нормально для большинства продуктов, 0.5+ — высокая вовлечённость (мессенджеры, соцсети). Падающая stickiness при стабильном MAU — тревога: люди "числятся" активными за месяц, но реже заходят.

DAU vs MAU тренды. Если DAU и MAU растут параллельно — рост честный. Если MAU растёт, а DAU стоит — продукт ловит новых юзеров, но не вовлекает их регулярно.

Для интерпретации полезно смотреть когорты MAU: какая доля юзеров пришла в этом месяце впервые, а какая — старые. Если MAU держится только на новых — старые когорты протухают.

Когда MAU — плохая метрика

MAU не для всех продуктов:

  • Сценарии раз в год. Сервис подачи декларации, оформление визы — MAU мало что показывает, нужен YAU (yearly) или ARPU.
  • Очень редкое использование. В продуктах, где норма заходить раз в полгода, MAU будет дикий шум.
  • B2B с тяжёлым онбордингом. Один аккаунт = десятки seats; MAU надо считать по seats, не по аккаунтам.
  • Чисто транзакционные сервисы. Если важна сумма транзакций, MAU — вторична.

Для таких случаев лучше: WAU + MAU + retention curves, или сразу Cohort retention в нужном окне.

Частые ошибки

  • MAU = последние 30 дней, но в ретро всё равно по календарным. Несовместимые определения путают команду.
  • Без таймзоны. Подсчёт по UTC сдвигает сутки, особенно у пользователей в восточных регионах.
  • Не уникальные юзеры. Считают события, получают завышенные значения.
  • Сравнивают месяцы разной длины. Февраль 28 дней vs январь 31 — это уже −10% "падения" из ничего.
  • Раздувают MAU мусором. Боты, тестовые аккаунты, технические юзеры. Чистка таблицы юзеров — обязательна.
  • Меняют определение тихо. Сегодня MAU = "залогинился", через месяц = "сделал действие". Ломаются все сравнения.

Связанные темы

FAQ

Какое окно использовать — 28 или 30 дней?

28, если хотите сглаженный график (28 = 4 полные недели, без эффекта дня недели). 30, если нужен привычный "месяц" для отчётов.

Можно ли считать MAU как сумму DAU?

Нельзя. Это даст событийный счёт, а не уникальных юзеров. MAU всегда меньше суммы DAU за месяц.

MAU больше DAU — это норма?

Да, всегда. MAU включает всех, кто хоть раз был активен в окне, DAU — только за один день.

Как сравнивать MAU между продуктами?

Через stickiness и retention. Абсолютные MAU несравнимы, потому что зависят от размера рынка и канала привлечения.

Что делать, если MAU растёт, а revenue не растёт?

Проверять конверсию из MAU в платящих и LTV когорт. Часто рост MAU идёт за счёт сегмента, который не монетизируется.

Когда MAU не подходит вообще?

Для редких сценариев (раз в год, раз в полгода). Там работают yearly active users или cohort retention с длинным окном.


Хочешь прокачать SQL и метрики? Открой тренажёр Карьерника — задачи на MAU, DAU, retention и оконные функции.