Как посчитать ARPU в SQL

ARPU и ARPPU — формулы

ARPU (Average Revenue Per User) — выручка на пользователя:

ARPU = Revenue / Total Users

ARPPU (Average Revenue Per Paying User) — выручка на платящего:

ARPPU = Revenue / Paying Users

Связь: ARPU = Paying Rate × ARPPU.

ARPU за месяц

SELECT
    SUM(amount) AS revenue,
    COUNT(DISTINCT u.user_id) AS total_users,
    SUM(amount) / COUNT(DISTINCT u.user_id) AS arpu
FROM users u
LEFT JOIN orders o ON o.user_id = u.user_id
    AND o.created_at >= '2026-04-01'
    AND o.created_at < '2026-05-01';

Важно: LEFT JOIN чтобы пользователи без заказов тоже попали в знаменатель.

ARPPU за месяц

SELECT
    SUM(amount) AS revenue,
    COUNT(DISTINCT user_id) AS paying_users,
    SUM(amount) / COUNT(DISTINCT user_id) AS arppu
FROM orders
WHERE created_at >= '2026-04-01' AND created_at < '2026-05-01'
  AND status = 'paid';

Знаменатель — только платящие.

ARPU по месяцам

WITH monthly AS (
    SELECT DATE_TRUNC('month', created_at)::DATE AS month,
        SUM(amount) AS rev
    FROM orders WHERE status = 'paid' GROUP BY 1
),
active AS (
    SELECT DATE_TRUNC('month', created_at)::DATE AS month,
        COUNT(DISTINCT user_id) AS users
    FROM events WHERE event = 'app_open' GROUP BY 1
)
SELECT m.month, m.rev / a.users AS arpu
FROM monthly m JOIN active a USING (month)
ORDER BY m.month;

Тренироваться на таких вопросах можно в Telegram-боте Карьерник — там 1500+ задач с реальных собесов с разборами.

Декомпозиция ARPU

WITH data AS (
    SELECT DATE_TRUNC('month', dt)::DATE AS month,
        COUNT(DISTINCT user_id) AS total,
        COUNT(DISTINCT user_id) FILTER (WHERE paid) AS paying,
        SUM(amount) FILTER (WHERE paid) AS revenue
    FROM user_activity
    GROUP BY 1
)
SELECT month,
    revenue / total AS arpu,
    paying::NUMERIC / total AS paying_rate,
    revenue / NULLIF(paying, 0) AS arppu,
    -- Проверка: arpu = paying_rate × arppu
    paying::NUMERIC / total * revenue / NULLIF(paying, 0) AS arpu_check
FROM data;

Полезно видеть ARPU, Paying Rate, ARPPU одновременно для диагностики.

ARPU по сегментам

По каналам

SELECT u.channel,
    SUM(o.amount) / COUNT(DISTINCT u.user_id) AS arpu
FROM users u
LEFT JOIN orders o ON o.user_id = u.user_id
    AND o.created_at >= '2026-04-01'
    AND o.created_at < '2026-05-01'
WHERE u.registered_at < '2026-04-01'  -- активные до начала периода
GROUP BY u.channel;

По платформе

SELECT platform, SUM(amount) / COUNT(DISTINCT user_id) AS arpu
FROM orders JOIN users USING (user_id)
WHERE created_at >= '2026-04-01' AND created_at < '2026-05-01'
GROUP BY platform;

По когорте

WITH cohort AS (
    SELECT user_id, DATE_TRUNC('month', MIN(created_at))::DATE AS cohort_month
    FROM orders GROUP BY user_id
)
SELECT c.cohort_month,
    SUM(o.amount) / COUNT(DISTINCT c.user_id) AS arpu_total
FROM cohort c
LEFT JOIN orders o USING (user_id)
GROUP BY c.cohort_month
ORDER BY c.cohort_month;

MoM ARPU

WITH monthly_arpu AS (
    SELECT DATE_TRUNC('month', o.created_at)::DATE AS month,
        SUM(o.amount) / COUNT(DISTINCT u.user_id) AS arpu
    FROM orders o
    JOIN users u USING (user_id)
    GROUP BY 1
)
SELECT month, arpu,
    LAG(arpu) OVER (ORDER BY month) AS prev_arpu,
    ROUND(100.0 * (arpu - LAG(arpu) OVER (ORDER BY month)) /
        LAG(arpu) OVER (ORDER BY month), 2) AS mom_pct
FROM monthly_arpu
ORDER BY month;

Ловушки

1. ARPU или ARPPU — зависит от задачи

  • Для инвесторов: ARPU (total picture).
  • Для продукта: ARPPU + Paying Rate (детализация).

2. «Активный» пользователь

Что именно в знаменателе ARPU:

  • Все зарегистрированные?
  • DAU за период?
  • MAU за период?

Каждое определение даёт разный ARPU. Фиксируйте.

3. Mix-эффект

ARPU может упасть даже при стабильных сегментах — если изменился mix трафика. Смотрите кейс.

4. Free + paid пользователи

ARPU среди всех vs только активных — разные числа.

5. Refund не учтён

-- ❌ ARPU завышен
SUM(amount)

-- ✅ Net ARPU
SUM(amount - COALESCE(refund, 0))

Нормы ARPU по индустриям (2026, РФ)

  • Мобильные игры: $1–3 monthly.
  • SaaS B2C: 200–2000₽/месяц.
  • E-commerce: зависит от категории, обычно 3000–15000₽.
  • SaaS B2B: $50–5000/месяц.

К слову, набить руку на таких кейсах удобно через тренажёр в Telegram — разбирайте по 10 вопросов в день, через 2 недели тема становится рефлексом.

ARPU в Python

import pandas as pd

revenue = orders[orders['status'] == 'paid']['amount'].sum()
total_users = users['user_id'].nunique()
arpu = revenue / total_users

ARPU vs LTV

ARPU = выручка / пользователь за период (месяц).
LTV = ARPU × expected_lifetime = ARPU / churn_rate.

ARPU — текущий момент. LTV — долгосрочная ценность.

Формула LTV.

Читайте также

FAQ

ARPU или ARPPU — что показывать PM?

Оба. ARPU для общей картины, ARPPU для оптимизации продаж премиум-тарифов.

Как считать ARPU с разовыми покупками?

Revenue за период / количество пользователей за тот же период. Пользователь, купивший несколько раз, учитывается один раз в знаменателе.

ARPU растёт при падении orders — хорошо?

Не всегда. Если активные пользователи платят больше — да. Если просто ушла аудитория с малыми чеками — спорно, проверьте total revenue.

Какое ARPU у Яндекса?

Разные продукты — разное ARPU. Яндекс Плюс — около 300₽/месяц, Такси — зависит от частоты, e-commerce — существенно выше.