Раздел 42 · Аналитика данных с нуля

Монетизация: ARPU, ARPPU, LTV

middle~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Бран · продюсер «Хроник Пограничья»

Финансисты спрашивают, сколько нам приносит один игрок и стоит ли новичок тех денег, что мы тратим на рекламу. Дай мне ARPU, ARPPU и этот ваш LTV. И скажи честно, просели ли деньги после 2.0.

В прошлом уроке мы посчитали, сколько людей играет. Теперь считаем, сколько они платят. Все определения мы дали в уроке про метрики, а здесь переводим их в SQL на данных игры.

Сначала чистые деньги

Любая метрика монетизации начинается с выручки, и в purchases нас ждут старые знакомые из урока про дубликаты и босса Пограничья: повторы вебхука с тем же receipt_id, возвраты и покупки тестировщиков. Ботов из прошлого урока выбросим заодно, хотя они и не платят. Соберём чистые покупки в CTE и дальше будем брать деньги только оттуда:

WITH fake AS (
  SELECT id FROM players WHERE email LIKE '%@studio.dev'
  UNION
  SELECT player_id FROM sessions WHERE ended_at - started_at > interval '20 hours'
),
clean AS (
  SELECT *
  FROM purchases
  WHERE status = 'paid'
    AND id IN (SELECT min(id) FROM purchases GROUP BY receipt_id)
    AND player_id NOT IN (SELECT id FROM fake)
)

Три числа месяца

Связка такая: ARPU делит выручку на всех активных, ARPPU только на платящих, и ARPU = доля платящих × ARPPU. Активных за месяц мы уже умеем считать, это MAU.

... ,
mau AS (
  SELECT date_trunc('month', started_at)::date AS month,
         count(DISTINCT player_id) AS mau
  FROM sessions
  WHERE player_id NOT IN (SELECT id FROM fake)
  GROUP BY month
),
rev AS (
  SELECT date_trunc('month', created_at)::date AS month,
         sum(amount_rub) AS revenue,
         count(DISTINCT player_id) AS payers
  FROM clean
  GROUP BY month
)
SELECT m.month, m.mau, r.payers, r.revenue,
       round(100.0 * r.payers / m.mau, 1) AS paying_pct,
       round(r.revenue / m.mau, 2) AS arpu,
       round(r.revenue / r.payers, 2) AS arppu
FROM mau m
JOIN rev r ON r.month = m.month
ORDER BY m.month;
   month    | mau  | payers |  revenue  | paying_pct |  arpu  |  arppu
------------+------+--------+-----------+------------+--------+---------
 2026-01-01 |  539 |     68 |  55387.00 |       12.6 | 102.76 |  814.51
 2026-02-01 |  766 |     95 |  62880.00 |       12.4 |  82.09 |  661.89
 2026-03-01 | 1085 |    110 | 162521.00 |       10.1 | 149.79 | 1477.46
 2026-04-01 | 1006 |    111 | 183764.00 |       11.0 | 182.67 | 1655.53
 2026-05-01 | 1021 |     95 | 122640.00 |        9.3 | 120.12 | 1290.95
 2026-06-01 |  975 |     86 |  70564.00 |        8.8 |  72.37 |  820.51

Связка помогает читать таблицу. В июне ARPU упал в два с половиной раза против апреля. Разложим: доля платящих снизилась с 11,0% до 8,8%, а ARPPU с 1655 до 821 ₽. Значит, упало и то и другое: платят реже, и платящие тратят меньше. Почему так вышло, ответит босс блока H, а пока фиксируем факт.

урок из курса

Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.