Как посчитать ARPDAU в SQL
Содержание:
Зачем ARPDAU
В мобильной игре revenue 100 000$ в день. Радует. Аналитик копает: DAU выросло с 500 тыс. до 800 тыс. за месяц, а revenue — только с 90 тыс. до 100 тыс. ARPDAU упал с 0,18$ до 0,125$. Новые юзеры пришли менее платящие — органика или плохие источники.
ARPDAU — рабочая метрика mobile gaming, freemium-приложений и медиа: показывает «качество» каждого активного пользователя в день. В статье — SQL и нюансы (не путать с ARPU).
Что такое ARPDAU
ARPDAU (Average Revenue Per Daily Active User) — средняя выручка с одного активного пользователя в день.
ARPDAU(day) = Revenue(day) / DAU(day)ARPDAU обычно усредняют за период (неделя/месяц) как:
Period ARPDAU = Total revenue / Sum of DAU per dayНе делите period revenue / period unique users — это будет ARPU, а не ARPDAU.
Базовый расчёт
Данные: events(user_id, event_date), transactions(user_id, amount, paid_at).
WITH daily_dau AS (
SELECT
event_date,
COUNT(DISTINCT user_id) AS dau
FROM events
WHERE event_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY event_date
),
daily_revenue AS (
SELECT
paid_at::DATE AS day,
SUM(amount) AS revenue
FROM transactions
WHERE paid_at::DATE >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY 1
)
SELECT
d.event_date AS day,
d.dau,
COALESCE(r.revenue, 0) AS revenue,
COALESCE(r.revenue, 0)::NUMERIC / NULLIF(d.dau, 0) AS arpdau
FROM daily_dau d
LEFT JOIN daily_revenue r ON r.day = d.event_date
ORDER BY d.event_date;Важно: LEFT JOIN с DAU как ведущей таблицей — иначе дни без транзакций потеряются (а они валидны: ARPDAU = 0).
ARPDAU по сегментам
По платформе (iOS / Android)
WITH daily AS (
SELECT
e.event_date,
u.platform,
COUNT(DISTINCT e.user_id) AS dau
FROM events e
JOIN users u ON u.user_id = e.user_id
WHERE e.event_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY e.event_date, u.platform
),
revenue AS (
SELECT
t.paid_at::DATE AS day,
u.platform,
SUM(t.amount) AS revenue
FROM transactions t
JOIN users u ON u.user_id = t.user_id
WHERE t.paid_at::DATE >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY 1, u.platform
)
SELECT
d.platform,
SUM(COALESCE(r.revenue, 0))::NUMERIC
/ NULLIF(SUM(d.dau), 0) AS arpdau_30d
FROM daily d
LEFT JOIN revenue r ON r.day = d.event_date AND r.platform = d.platform
GROUP BY d.platform
ORDER BY arpdau_30d DESC;Обычно iOS ARPDAU в 2-4 раза выше Android.
По стране
Агрегируем каждую сторону отдельно, чтобы JOIN не множил строки:
WITH daily_dau AS (
SELECT u.country, e.event_date, COUNT(DISTINCT e.user_id) AS dau
FROM events e
JOIN users u ON u.user_id = e.user_id
WHERE e.event_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY u.country, e.event_date
),
daily_revenue AS (
SELECT u.country, t.paid_at::DATE AS day, SUM(t.amount) AS revenue
FROM transactions t
JOIN users u ON u.user_id = t.user_id
WHERE t.paid_at::DATE >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY u.country, t.paid_at::DATE
)
SELECT
d.country,
SUM(COALESCE(r.revenue, 0))::NUMERIC / NULLIF(SUM(d.dau), 0) AS arpdau_30d
FROM daily_dau d
LEFT JOIN daily_revenue r ON r.country = d.country AND r.day = d.event_date
GROUP BY d.country
ORDER BY arpdau_30d DESC;Tier-1 (US, JP, KR, UK, AU) обычно даёт ARPDAU в 5-10 раз выше Tier-3.
ARPDAU vs ARPU vs ARPPU
| Метрика | Что считаем | Когда используют |
|---|---|---|
| ARPDAU | Revenue / DAU за день | mobile gaming, freemium с ежедневной активностью |
| ARPU | Period revenue / period unique users | subscription, SaaS — реже daily активность |
| ARPPU | Period revenue / period paying users | оценка качества платящей базы |
В одной игре могут быть: ARPDAU = 0,25$, ARPU = 1,80$, ARPPU = 40$. Каждая метрика отвечает на свой вопрос.
-- За месяц апрель 2026
WITH stats AS (
SELECT
COUNT(DISTINCT user_id) AS mau,
COUNT(DISTINCT CASE WHEN amount > 0 THEN user_id END) AS paying_users,
SUM(amount) AS total_revenue,
COUNT(DISTINCT user_id || '|' || event_date::TEXT) AS total_active_days
FROM combined_events_transactions
WHERE event_date >= '2026-04-01' AND event_date < '2026-05-01'
)
SELECT
total_revenue::NUMERIC / NULLIF(total_active_days, 0) AS arpdau,
total_revenue::NUMERIC / NULLIF(mau, 0) AS arpu_30d,
total_revenue::NUMERIC / NULLIF(paying_users, 0) AS arppu_30d
FROM stats;Динамика ARPDAU
Снова агрегируем каждую сторону до JOIN, иначе SUM revenue умножится на число events_per_user_per_day:
WITH daily_dau AS (
SELECT event_date AS day, COUNT(DISTINCT user_id) AS dau
FROM events
WHERE event_date >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY 1
),
daily_revenue AS (
SELECT paid_at::DATE AS day, SUM(amount) AS revenue
FROM transactions
WHERE paid_at::DATE >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY 1
),
daily AS (
SELECT d.day, d.dau, COALESCE(r.revenue, 0) AS revenue
FROM daily_dau d
LEFT JOIN daily_revenue r ON r.day = d.day
)
SELECT
day,
dau,
revenue,
revenue::NUMERIC / NULLIF(dau, 0) AS arpdau,
AVG(revenue::NUMERIC / NULLIF(dau, 0)) OVER (
ORDER BY day
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS arpdau_7d_avg
FROM daily
ORDER BY day;7-day rolling смягчает дневной шум — выходные и события (релизы, акции) дают +30-50% к ARPDAU.
Частые ошибки
Ошибка 1. Делить period revenue на period unique users
Это даёт ARPU (per user за период), а не ARPDAU. Если revenue 1М$ за месяц при 100К уникальных юзеров = ARPU 10$. ARPDAU для тех же данных мог быть 0,3$.
Ошибка 2. Не учитывать users с нулевой revenue
Если делать SUM(amount) / COUNT(DISTINCT user_id) только по платящим — это ARPPU, не ARPDAU. ARPDAU включает всех активных, даже неплатящих.
Ошибка 3. Дни без транзакций пропадают
INNER JOIN dau и revenue потеряет дни с 0 revenue. Нужен LEFT JOIN с COALESCE.
Ошибка 4. Дабл-каунт user × day
Если пользователь активен в этот день и в этот же день купил — он одна activity-точка. Не суммировать его как 2 events.
Ошибка 5. ARPDAU без timezone-нормализации
В Tier-1 регионах день начинается в разное время. Стандартизуйте по UTC или по timezone каждого юзера, чтобы границы дней не плыли.
Ошибка 6. Сравнивать ARPDAU mobile vs PC
ARPDAU в гипер-кэжуал мобайле — 0,05-0,10$. В midcore PC — 0,80-1,50$. Это разные продукты, бенчмарки разные.
Связанные темы
- Метрики продукта DAU/MAU/ARPU
- Как посчитать DAU в SQL
- Stickiness и DAU/MAU ratio
- Как посчитать ARR в SQL
FAQ
Какой ARPDAU считается хорошим?
Hyper-casual mobile — 0,05-0,15$. Mid-core mobile — 0,30-0,80$. AAA mobile — 1-3$. Подписочный media — 0,15-0,40$. Сравнивайте только в своей категории.
ARPDAU или LTV — что важнее?
LTV — это «сколько юзер принесёт за весь жизненный цикл». ARPDAU — «сколько приносит сегодня». LTV — стратегия, ARPDAU — операционная метрика. Обе важны.
ARPDAU включает рекламу или только in-app purchases?
Зависит от продукта. В hyper-casual обычно вся монетизация — реклама → ARPDAU = ads revenue / DAU. В midcore — IAP + ads. Уточните, что считаете.
Что делать, если ARPDAU падает?
Декомпозируйте: 1) Состав DAU изменился? (новые vs возвращающиеся, страны). 2) Платящая база? (paying users / DAU). 3) Средний платёж? (ARPPU). 4) Цены/набор продуктов изменился? Найдите конкретный сегмент с провалом.
ARPDAU вырос, а revenue упал — как такое?
DAU упал быстрее, чем revenue: меньше активных юзеров, но оставшиеся платят больше. Часто после оттока casual-аудитории остаются «киты». Хорошо для unit-экономики, но плохо для общего бизнеса.