Как посчитать MAU в SQL
Содержание:
Зачем MAU
«Сколько у нас активных пользователей за месяц?» — самый частый вопрос менеджмента. Цифра звучит просто, но: считать calendar month (1-30 апреля) или rolling 30 дней? Включать ли регистрации, не закончившие onboarding? Что считать «active»?
MAU — фундаментальная метрика для большинства продуктов. В статье — SQL и нюансы.
Что такое MAU
MAU (Monthly Active Users) — уникальные пользователи, совершившие минимум одно действие за период в месяц.
MAU = COUNT(DISTINCT user_id) where date ∈ месяцЧто считать «active» — определяется командой: открыл приложение, или совершил key event (например, отправил сообщение, оформил заказ).
Базовый расчёт
Данные: events(user_id, event_date, event_type).
SELECT
DATE_TRUNC('month', event_date) AS month,
COUNT(DISTINCT user_id) AS mau
FROM events
WHERE event_date >= '2026-01-01'
AND event_date < '2026-05-01'
GROUP BY 1
ORDER BY 1;Важно: DATE_TRUNC('month', ...) группирует по календарному месяцу. Если месяц неполный — MAU занижен.
Calendar MAU vs Rolling 30-day
Calendar MAU
Активные за календарный месяц (1-30/31 числа). Простой и понятный.
Rolling 30-day MAU
Активные за последние 30 дней (катящееся окно). Не зависит от границ месяца, гладкая кривая.
WITH dates AS (
SELECT generate_series('2026-04-01'::DATE, '2026-04-30'::DATE, INTERVAL '1 day')::DATE AS day
)
SELECT
d.day,
COUNT(DISTINCT e.user_id) AS rolling_mau
FROM dates d
JOIN events e
ON e.event_date > d.day - INTERVAL '30 days'
AND e.event_date <= d.day
GROUP BY d.day
ORDER BY d.day;Rolling MAU не имеет «провалов» на стыке месяцев и лучше для долгосрочных трендов.
MAU по сегментам
SELECT
DATE_TRUNC('month', e.event_date) AS month,
u.acquisition_channel,
COUNT(DISTINCT e.user_id) AS mau
FROM events e
JOIN users u ON u.user_id = e.user_id
WHERE e.event_date >= '2026-01-01'
GROUP BY 1, 2
ORDER BY 1, mau DESC;Или по типу события:
SELECT
DATE_TRUNC('month', event_date) AS month,
COUNT(DISTINCT user_id) AS open_app_mau,
COUNT(DISTINCT CASE WHEN event_type = 'purchase' THEN user_id END) AS purchase_mau
FROM events
WHERE event_date >= '2026-01-01'
GROUP BY 1;«Качественный MAU» (с key event) обычно меньше total MAU.
Частые ошибки
Ошибка 1. Считать неполный месяц. 13 мая 2026 — MAU за май неполный. Используйте month-to-date.
Ошибка 2. Дубли user_id.
Если в events user_id записан с пробелами / разными регистрами — DISTINCT не сработает. Нормализуйте.
Ошибка 3. Включать ботов.
Без фильтра is_bot = false MAU завышен. В мобайле особенно (тестовые установки, эмуляторы).
Ошибка 4. Timezone.
DATE_TRUNC в UTC даёт MAU «по UTC». Для МСК-продукта приведите к нужной зоне: event_date AT TIME ZONE 'Europe/Moscow'.
Ошибка 5. Confusion с unique users за period. «Unique users за квартал» ≠ MAU × 3. Юзер мог быть активен 1 раз во всём квартале — считается 1 раз в total quarterly, но входил бы в MAU каждого месяца, если был активен в каждый.
Ошибка 6. Calendar vs rolling. Сравнение «MAU апреля calendar» с «MAU last 30d rolling» — некорректно. Зафиксируйте определение.
Связанные темы
- Как посчитать DAU в SQL
- Stickiness и DAU/MAU ratio
- Как посчитать active days в SQL
- Метрики продукта DAU/MAU/ARPU
FAQ
MAU или DAU?
DAU — для высокочастотных (соцсети, мессенджеры). MAU — для среднечастотных (e-com, банк, СМИ). Большинство продуктов считают обе.
Calendar или rolling?
Calendar — для отчётности по периодам. Rolling — для трендов. В дашборды обычно ставят обе.
Что значит «active»?
Договоритесь в команде. Чаще всего «открыл приложение/сайт». Но «качественный MAU» считают по key event.
Размер MAU vs market?
Total addressable market (TAM) → serviceable addressable market (SAM) → MAU. Доля MAU/SAM показывает penetration.
MAU упал — что делать?
Декомпозиция: 1) acquisition (новые юзеры падают?), 2) retention (старые отваливаются?), 3) engagement (тот же юзер реже заходит?). Каждое — отдельный fix.