Зауважимо: коли користувачів тисячі, простий 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 рублів. Вартість розраховується індивідуально. Замовте консультацію — ми оцінимо ваш проєкт за один день. Отримайте рекомендації з архітектури та стеку, навіть якщо ви тільки на етапі ідеї.
Зв'яжіться з нами, щоб обговорити впровадження лідерборду у ваш додаток.







