Терминология
- QPS (Queries Per Second) -- запросы к БД/кэшу. Может быть 10-100x больше RPS (один HTTP request делает много SQL-запросов).
- RPS (Requests Per Second) -- HTTP-запросы к API.
- TPS (Transactions Per Second) -- транзакции в финансовых системах.
На практике термины смешивают. Важно при обсуждении уточнять уровень: web, app, DB.
Базовая формула DAU → QPS
Это основа всех расчётов нагрузки.
QPS_avg = DAU × actions_per_user / seconds_per_day
seconds_per_day = 86 400 ≈ 10^5
Обычно округляют до 10^5 для BOTE.
Пример: 10M DAU, 10 actions per user.
QPS_avg = 10^7 × 10 / 10^5 = 10^3 = 1 000 QPS
Peak vs Average
Пользователи не распределены равномерно по суткам. Есть "рабочие часы" и пики.
| Тип сервиса | Peak / Average |
|---|---|
| B2B enterprise | 2x (9-18 в будни) |
| Consumer web (соцсеть) | 3-4x (вечер в часовом поясе) |
| E-commerce | 5-10x (чёрная пятница, Cyber Monday) |
| Streaming (Netflix) | 3-4x (вечер пятницы) |
| Gaming | 5-10x (премьера новой игры) |
| Delivery (food) | 8-10x (обед + ужин) |
Стандартное допущение BOTE: peak = 3 × average. В реальности смотрите на свой паттерн.
Visualization: daily pattern
QPS
│ ╭──╮
│ ╭──╯ ╰╮ ← evening peak
│ ╭──╮ ╭──╯ ╰─╮
│ ╭──╯ ╰────╯ ╰╮
│ ╭─╯ ╰──╮
│ ╭─╯ ╰──╮
│─╯ ╰───
└──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬─→ hour
0 2 4 6 8 10 12 14 16 18 20 22 24
Average = площадь / 24
Peak = ~3x average (для consumer web)
Read / Write ratio
Большинство систем read-heavy. Знание соотношения критично для выбора стратегии (master-replica, caching, CQRS).
| Тип сервиса | Read : Write | Пример |
|---|---|---|
| Social feed | 100:1 | Twitter читают в 100 раз чаще, чем пишут |
| E-commerce catalog | 100:1 | Просмотры товаров vs покупки |
| Messenger | 10:1 | Сообщение пишут раз, читают получатели |
| Blog platform | 1000:1 | Пост публикуется раз, читается тысячи |
| Analytics / logs | 1:100 | Пишут все события, читают редко |
| Payment system | 1:1 | Каждая транзакция читается (для баланса) |
Применение. Если read:write = 100:1, то read-реплики и кэши решают 99% нагрузки. Master с writes остаётся слабо нагружен.
p50 vs p99 vs p99.9
Middle latency обманчива -- нагрузку задают хвосты.
| Метрика | Описание | Что показывает |
|---|---|---|
| p50 (median) | 50% запросов быстрее | "Обычный" пользователь |
| p95 | 5% медленнее | Заметная часть пользователей страдает |
| p99 | 1% медленнее | Каждый 100-й запрос -- долгий |
| p99.9 | 0.1% медленнее | Amazon говорит: каждый 1000-й запрос определяет впечатление |
Правило. При 10 запросах на страницу, если p99 = 1s, вероятность хотя бы одного медленного запроса = 1 - 0.99^10 ≈ 10%. Каждый 10-й пользователь видит тормоза. Поэтому в SLA фиксируют p99, не p50.
Burst patterns
Обычный peak/average 3x -- это "гладкий" peak. Есть ещё burst -- резкие всплески.
Thundering herd
Все клиенты бьют одновременно:
- Cron-задачи на
:00каждый час - Истечение JWT у миллионов пользователей в одно время
- Запуск рекламной кампании ("ссылка в prime-time шоу")
Решения: jitter (+ random(0, 60 sec)), rate limiting, exponential backoff.
Product-specific bursts
- E-commerce: распродажа в 00:00 -- 50x peak за минуты
- Бронирование билетов: открытие продаж -- 100x
- Live streaming: старт трансляции -- 20x
- Новостной пик: breaking news -- 10x для home page
Планируйте под product peak, не под usual peak.
Worked пример: 10M DAU сервис
Разберём полный расчёт на реалистичном сервисе (типа Habr, Medium).
Входные данные
- DAU = 10 000 000
- Actions per user per day = 10 (открыл 5 статей, поставил 2 лайка, написал 1 коммент и т.д.)
- Read : Write = 100 : 1
- Peak / Average = 3 (consumer web)
Средний QPS
Total actions / day = 10M × 10 = 100M = 10^8
Seconds per day = 86 400 ≈ 10^5
QPS_avg = 10^8 / 10^5 = 10^3 = 1 000 QPS
Peak QPS
QPS_peak = 1 000 × 3 = 3 000 QPS
Разбивка read / write
Read_avg = 1 000 × (100/101) ≈ 990 QPS
Write_avg = 1 000 × (1/101) ≈ 10 QPS
Read_peak = 990 × 3 ≈ 3 000 QPS
Write_peak = 10 × 3 ≈ 30 QPS
QPS на уровне БД
Обычно один HTTP-запрос делает 3-10 DB-запросов (одна странница статьи: post + user + comments + tags).
DB QPS_peak = 3 000 × 5 = 15 000 QPS reads
30 × 3 = 90 QPS writes
Что это значит архитектурно
- 3 000 peak RPS -- 3-5 application серверов (Go/PHP FastCGI), каждый держит 1-2k RPS
- 15 000 DB reads/sec -- в голую Postgres не влезет, нужен кэш (cache hit 95%+ → 750 QPS в БД)
- 30 writes/sec -- легко для single Postgres master
- Replica factor: 1 master + 2-3 replicas для read offload
Калькулятор QPS
Хелпер для быстрой оценки.
<?php
declare(strict_types=1);
/**
* QPS estimator: DAU + actions -> average/peak QPS with read/write split.
*/
final class QpsEstimator
{
private const SECONDS_PER_DAY = 86_400;
public function __construct(
private readonly int $dau,
private readonly int $actionsPerUser,
private readonly int $readWriteRatio = 100, // reads per 1 write
private readonly float $peakMultiplier = 3.0,
) {}
/**
* @return array{
* avg: float, peak: float,
* read_avg: float, read_peak: float,
* write_avg: float, write_peak: float
* }
*/
public function estimate(): array
{
$totalActions = $this->dau * $this->actionsPerUser;
$avg = $totalActions / self::SECONDS_PER_DAY;
$peak = $avg * $this->peakMultiplier;
$readShare = $this->readWriteRatio / ($this->readWriteRatio + 1);
$writeShare = 1 / ($this->readWriteRatio + 1);
return [
'avg' => round($avg, 1),
'peak' => round($peak, 1),
'read_avg' => round($avg * $readShare, 1),
'read_peak' => round($peak * $readShare, 1),
'write_avg' => round($avg * $writeShare, 1),
'write_peak' => round($peak * $writeShare, 1),
];
}
/**
* DB-level QPS given amplification factor (1 HTTP req -> N DB queries).
*/
public function dbQps(int $amplificationRead, int $amplificationWrite): array
{
$e = $this->estimate();
return [
'db_read_peak' => round($e['read_peak'] * $amplificationRead, 1),
'db_write_peak' => round($e['write_peak'] * $amplificationWrite, 1),
];
}
}
// Usage:
// $est = new QpsEstimator(dau: 10_000_000, actionsPerUser: 10);
// $est->estimate();
// => ['avg' => 1157, 'peak' => 3472, 'read_peak' => 3437, 'write_peak' => 34, ...]
- Получите DAU (от продакта, аналитики или оценки из MAU × 0.1-0.3)
- Оцените actions per user per day (feed: 20-50, чат: 100+, покупки: 5-10)
- Разделите на 10^5 -- получите avg QPS
- Умножьте на 3 (consumer) или 10 (e-commerce sale) -- получите peak
- Разбейте по read/write (обычно 100:1 или 10:1)
- Умножьте на amplification factor для DB (3-10 queries per request)
- Добавьте запас x2
Частые ошибки
- Считать MAU вместо DAU. MAU может быть 3-10x DAU. Всегда уточняйте.
- Забыть peak. Проектирование под average = падение в peak.
- Игнорировать amplification. 1 RPS на API ≠ 1 QPS на БД.
- Единичное число без p99. "Средняя latency 50 ms" ничего не говорит -- нужен p99.
- Забыть про batch-операции. Cron может за минуту запросить миллион записей -- это не QPS, но грузит БД.
Выводы
- Базовая формула:
QPS_avg = DAU × actions / 10^5, peak = 3× average - Read/write ratio 100:1 -- типичное для social/e-commerce, 1:100 -- для аналитики
- Peak determines capacity, p99 determines SLO
- Amplification factor 3-10 превращает RPS в QPS для БД
- Burst-паттерны (sales, breaking news) могут давать 10-100x от normal peak