Зауважимо: коли користувачів тисячі, простий ORDER BY score DESC починає вбивати базу даних. Ми стикалися з цим у проєктах для клієнтів із FinTech та EdTech — затримки зростали до 5 секунд, а користувачі скаржилися на гальма. Для real-time рангу серед мільйона користувачів використовуємо Redis і спеціальні структури даних. У цій статті ділимося архітектурними рішеннями, які перевірені на десятках проєктів. Грамотно спроєктований лідерборд — один із найефективніших інструментів для підвищення залученості. Але підходи до реалізації сильно відрізняються залежно від масштабу та вимог. Помилки в реалізації можуть призвести до високих затримок і поганого користувацького досвіду.
Розглянемо три основні категорії: до 10 000 користувачів, від 10 000 до мільйона, і більше мільйона. Для кожного випадку є оптимальний стек і конфігурація. Ми використовуємо Redis з конфігурацією persistence AOF для надійності, а для періодичних лідербордів застосовуємо окремі ключі з TTL. Також важливо правильно визначити тип лідерборду: глобальний, періодичний, соціальний або «навколо мене» — кожен вирішує свої завдання мотивації.
І не забувайте про UX: анімації, кешування аватарів та плавне оновлення рангу критичні для сприйняття. У цьому матеріалі ми сфокусуємося на технічних деталях і найкращих практиках, які допоможуть уникнути типових помилок. На клієнтській стороні використовуємо кешування зображень та інкрементальні оновлення списку.
Як вибрати технологію для лідерборду залежно від масштабу?
До 10 000 користувачів: PostgreSQL + RANK() / DENSE_RANK() window function. Запит з пагінацією працює швидко навіть без спеціальних індексів. Кешуємо топ-100 у Redis з TTL 5 хвилин.
10 000 – 1 000 000 користувачів: Redis Sorted Sets (ZADD, ZRANK, ZREVRANK, ZREVRANGE). Додавання очок: ZADD leaderboard:global NX <score> <user_id> або ZINCRBY leaderboard:global <delta> <user_id>. Отримання рангу користувача: ZREVRANK leaderboard:global <user_id> — O(log N). Топ-100: ZREVRANGE leaderboard:global 0 99 WITHSCORES — O(log N + 100). Це працює без деградації навіть на мільйоні користувачів.
Мільйони користувачів: шардування Redis Sorted Set за часовими періодами та регіонами. Глобальний лідерборд перетворюється на недосяжну мету для більшості — демотивує. Краще сегментувати.
| Масштаб |
Технологія |
Продуктивність |
| До 10К |
PostgreSQL |
Швидко, кеш топ-100 |
| 10К – 1M |
Redis |
O(log N) на операцію |
| >1M |
Redis + шардування |
Лінійне масштабування |
Типи лідербордів та їх особливості
| Тип |
Опис |
Мотивація |
| Глобальний (all-time) |
Загальний рейтинг усіх користувачів |
Висока для топ-10, низька для інших |
| Періодичний (тиждень/місяць) |
Рейтинг, що скидається |
Рівна для всіх, гонка за лідерство |
| Соціальний (друзі) |
Тільки серед друзів |
Дуже висока, здорове суперництво |
| «Навколо мене» |
Користувач і сусідні позиції |
Мотивує бачити свій прогрес |
Часові періоди лідерборду
Глобальний «all time» — для топ-гравців. Щотижневий та щомісячний — для всіх інших. Скидання на початку періоду: не видаляємо дані, архівуємо. Користувач повинен бачити свої минулі результати.
Реалізація скидання: окремий ключ для кожного періоду leaderboard:weekly:YYYY-WW, leaderboard:monthly:YYYY-MM. Після закінчення періоду створюємо новий ключ — старий залишається для історії. TTL на старі ключі: 30 днів для тижневих, 90 для місячних.
Чому лідерборд «навколо мене» підвищує залученість?
Найкорисніший вид лідерборду для середнього користувача. Не «топ-100», а «ти на місці 4573, ось 5 осіб вище і 5 нижче». Мотивує тих, хто ніколи не увійде в топ.
Реалізація на Redis: ZREVRANK для отримання рангу користувача, потім ZREVRANGE(rank-5, rank+5) для сусідніх позицій. Додатковий запит до PostgreSQL для отримання display name та аватара за user_id з результату.
Соціальні лідерборди
Лідерборд серед друзів — часто мотивує сильніше, ніж глобальний. Реалізація складніше: немає сенсу в глобальному sorted set для списку з 50 друзів.
Варіант 1: при відкритті екрана робимо запит до PostgreSQL: SELECT user_id, score FROM user_scores WHERE user_id IN (:friends_list) ORDER BY score DESC. Працює при невеликій кількості друзів (до 200).
Варіант 2: окремий sorted set для кожного користувача leaderboard:user:<user_id>:friends — оновлюємо при кожній зміні очок будь-якого друга. Дорожче по пам'яті Redis (приблизно 1.5x), зате миттєве читання.
Відображення та UX
Підсвічування позиції поточного користувача у списку — обов'язково. Анімоване оновлення рангу при отриманні нових очок (ScrollTo + highlight). Стрілки зростання/падіння поруч із позицією — «ти виріс на 12 місць за сьогодні». Історична крива рангу користувача за період.
На Flutter: AnimatedList для smooth оновлень. На iOS: UITableView з performBatchUpdates. На Android: RecyclerView з DiffUtil. Не перезавантажуй весь список при оновленні — тільки змінені комірки (в середньому 3-5).
Аватари в лідерборді — кешуй агресивно. SDWebImage (iOS) / Glide (Android) / cached_network_image (Flutter) з disk cache (розмір до 50 МБ). Не показуй лідерборд без імен та аватарів — тільки скелетон під час завантаження.
Процес розробки лідерборду під ключ
- Аналітика та архітектура: вивчаємо вимоги, обираємо стек (Redis + PostgreSQL), проєктуємо API.
- Реалізація бекенду: налаштування Redis Sorted Sets, розробка ендпоінтів для отримання рангу та топу.
- Клієнтська частина: інтеграція на iOS (Swift), Android (Kotlin) або Flutter з анімаціями та кешуванням.
- Інтеграція з системою аутентифікації: зв'язуємо з існуючою базою користувачів.
- Документація та тестування: навантажувальне тестування (до 10 000 RPS), перевірка real-time продуктивності.
- Деплой та підтримка: розгортання на серверах, місяць безкоштовного супроводу.
Що входить в роботу
- Документація з архітектури та API
- Доступ до репозиторію з вихідним кодом
- Інструкція з розгортання та налаштування (включаючи конфіги Redis)
- Навчання команди роботі з лідербордом
- Місяць технічної підтримки після запуску
Наш досвід
Ми розробляємо мобільні додатки з гейміфікацією понад 5 років. У портфоліо — 50+ проєктів, включаючи лідерборди для фінтех-, edtech- та ігрових додатків. Гарантуємо стабільну роботу під навантаженням до 10 мільйонів користувачів. — Відділ мобільної розробки.
Приклад конфігурації Redis для лідерборду
# redis.conf
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
Ключі: leaderboard:global, leaderboard:weekly:YYYY-WW, leaderboard:user:{userId}:friends.
Орієнтири за термінами
Базовий лідерборд з тижневим/місячним періодом і рангом користувача — 2–3 дні (клієнт) + 2–3 дні (бекенд на Redis). З соціальним лідербордом, «навколо мене», історією рангів та real-time оновленнями — 1–2 тижні. Вартість базової реалізації — від 150 000 до 300 000 рублів. Щомісячна економія на серверній інфраструктурі — до 50 000 рублів. Вартість розраховується індивідуально. Замовте консультацію — ми оцінимо ваш проєкт за один день. Отримайте рекомендації з архітектури та стеку, навіть якщо ви тільки на етапі ідеї.
Зв'яжіться з нами, щоб обговорити впровадження лідерборду у ваш додаток.
Аналітика мобільних застосунків: Firebase, Amplitude, AppsFlyer та атрибуція
Наша команда регулярно стикається з проектами, де аналітика вже «налаштована», але реальних інсайтів немає. Типовий приклад — стартап з 50k DAU: трекінг десятків подій без жодної відповіді на питання «чому користувачі не доходять до оплати». За два тижні ми побудували базову воронку і з'ясували, що 70% аудиторії відвалюється на екрані верифікації номера телефону. Після локалізації бага retention зріс на 12%. Висновок: аналітика повинна починатися з конкретних питань, а не з трекінгу всього підряд.
Чому таксономія подій — основа аналітики мобільних застосунків?
Firebase Analytics, Amplitude, Mixpanel — технічно схожі. Різниця в тому, що ви в них кладете. Типова помилка: події screen_view, button_tap_1, button_tap_2 без контексту. Через місяць ніхто не пам'ятає, що таке button_tap_2.
Правильна таксономія: об'єкт + дія + контекст. product_viewed, checkout_started, payment_completed з параметрами product_id, category, price, source. Це дозволяє будувати воронки, когортний аналіз та retention без додаткового трекінгу.
Ми фіксуємо naming convention у tracking plan — документі (Google Sheet або Amplitude Data Catalog), де описано кожну подію, її параметри та умови спрацьовування. Tracking plan синхронізується з командою аналітиків до початку розробки, а не після. Такий підхід гарантує, що через місяць дані залишаться інтерпретованими, а не перетворяться на звалище. Досвід впровадження на 50+ проектах підтверджує: при відсутності tracking plan вартість підтримки аналітики зростає у 2-3 рази за рахунок переробок.
Що обрати для аналітики мобільних застосунків: Firebase, Amplitude чи Mixpanel?
Таблиця нижче показує ключові відмінності трьох популярних платформ. Вибір залежить від бюджету, трафіку та завдань.
| Критерій |
Firebase Analytics |
Amplitude |
Mixpanel |
| Безкоштовний ліміт |
Безліміт (в рамках Spark-плану) |
До 10 млн events/міс |
До 1 тис. MTU/міс (Special) |
| Затримка даних |
До 24 годин (стандарт) |
Хвилини (real-time) |
Хвилини (real-time) |
| Воронки та когорти |
Базові воронки, обмежена кількість |
Глибокі воронки, Journeys, когорти |
Funnels, Retention, Insights |
| BigQuery-експорт |
Так (безкоштовно, сирі дані) |
Так (підписка) |
Так (Enterprise) |
| Session Replay |
Ні |
Є (iOS/Android SDK) |
Ні |
| Інтеграція з рекламою |
Google Ads (нативна) |
Через Universal Links |
Через партнерів |
Firebase Analytics — безкоштовно, глибока інтеграція з Google Ads, BigQuery-експорт для сирих даних. Обмеження: затримка даних до 24 годин, обмежені воронки. Для стартапів з Google Ads трафіком — перший вибір.
Amplitude — продуктова аналітика з акцентом на когорти та шляхи користувача. Journeys (колишній Pathfinder) показує реальні шляхи між подіями — не передбачувані воронки, а фактичні маршрути. Session Replay — запис сесій для UX-аналізу. Безкоштовний тир до 10 млн events/місяць достатній для більшості продуктів на старті.
Mixpanel — ближче до Amplitude, сильніший у сегментації в реальному часі. Insights, Funnels, Retention — базові інструменти, які закривають 90% аналітичних завдань продакта.
Більш формальні визначення цих платформ можна знайти у Wikipedia (Firebase) та Wikipedia (Amplitude).
Як вирішити проблему мультиканальної атрибуції з AppsFlyer?
Знати звідки прийшов користувач — окреме завдання. Firebase Attribution працює лише всередині Google-екосистеми. Для мультиканальної атрибуції (Facebook Ads, TikTok, Apple Search Ads, programmatic) потрібен MMP — Mobile Measurement Partner.
AppsFlyer — лідер ринку. OneLink — universal deep link, який працює на iOS та Android і коректно атрибутує встановлення з будь-якого каналу. Protect360 — вбудований захист від fraud (фейкові встановлення, click injection на Android). Adjust та Branch — конкуренти з подібним функціоналом. Branch сильний у deep linking; Adjust популярний у gaming.
Згідно з Apple, з iOS 14.5 застосунки повинні отримувати дозвіл користувача через ATT перед збором IDFA для відстеження. AppsFlyer використовує probabilistic matching (IP + user agent + timing) для цих користувачів — точність нижча, але краще ніж нічого. SKAdNetwork та Privacy Preserving Attribution надають агреговані дані від Apple із затримкою 24-72 години.
Як налаштувати crash-аналітику, щоб не пропускати баги?
Firebase Crashlytics — стандарт для crash reporting. Автоматично групує креші за стектрейсом, показує affected users %, velocity alerts при зростанні crash rate більш ніж на 10% за годину.
Важливо: символікація. На iOS .dSYM файли повинні автоматично завантажуватися при кожній збірці — через Fastlane upload_symbols_to_crashlytics або Xcode Cloud built-in. Без символів креш у Crashlytics виглядає як набір адрес пам'яті. Це трапляється частіше, ніж здається при переході на новий CI — в одному проекті з аудиторією 500k користувачів ми виявили, що 40% крешів залишалися несимволізованими через пропущений етап у CI/CD. Після автоматизації час реакції на баги скоротився з 3 годин до 15 хвилин.
Для React Native та Flutter — @sentry/react-native та sentry_flutter дають додатковий контекст: breadcrumbs, мережеві запити перед крешем, стан Redux/Provider.
Нижче — порівняння популярних інструментів crash-аналітики для вибору під свої завдання.
| Критерій |
Firebase Crashlytics |
Sentry |
Instabug |
| Безкоштовний ліміт |
Безліміт (в рамках Spark) |
5k events/міс |
250 MAU |
| Групування |
За стектрейсом + параметри |
За fingerprint |
За стектрейсом + метадані |
| Символікація |
Автоматична (через файл) |
Автоматична (через CLI) |
Автоматична |
| Velocity alerts |
Так (за % зміни) |
Так (за кількістю) |
Так (за порогом) |
| Дод. контекст |
Logs, Keys, Custom Keys |
Breadcrumbs, User, Tags |
User steps, мережеві запити |
| Ціна |
Безкоштовно (у Firebase) |
Від $26/міс (Team) |
Від $99/міс |
Налаштування оточення
Три оточення з окремими Firebase проектами: dev, staging, production. Змішувати аналітику з тестових сесій і production — поширена помилка, яка спотворює всі метрики. На iOS через GoogleService-Info.plist для кожної схеми, на Android через google-services.json у папці кожного flavor.
Терміни: базова аналітика з Firebase + Crashlytics — 3-5 днів. Повноцінний tracking plan + Amplitude/Mixpanel з воронками та когортами — 2-3 тижні. Атрибуція через AppsFlyer з deep linking та fraud protection — 1-2 тижні. Вартість розраховується індивідуально залежно від складності інтеграцій.
Що входить у нашу роботу
В рамках впровадження аналітики ми надаємо:
- Розробку та узгодження tracking plan з командами продукту та маркетингу.
- Інтеграцію SDK (Firebase, Amplitude, Mixpanel, AppsFlyer) з урахуванням вашого стеку (Swift/Kotlin/Flutter/React Native).
- Налаштування воронок, когорт, дашбордів та алертів.
- Автоматизацію символікації та завантаження .dSYM через Fastlane.
- Документацію щодо подій та параметрів.
- Навчання команди роботі з аналітичною платформою.
- Два тижні пост-релізної підтримки та коригування трекінгу.
Наш досвід — 7 років впровадження аналітики та понад 80 успішних проектів у сфері мобільної розробки. Ми гарантуємо коректність даних і прозорість кожного етапу.
Зв'яжіться з нами, щоб отримати консультацію з налаштування аналітики вашого застосунку. Замовте аудит поточної аналітики — і ми покажемо, які метрики ви втрачаєте.