Представим, что вы создали SaaS-приложение на React, FastAPI и PostgreSQL.
На старте у продукта было 100 пользователей.
Затем появились первые платные клиенты, интеграции, командные аккаунты и дополнительные функции.
Через несколько месяцев в системе зарегистрировано 10 000 пользователей.
А теперь бизнес ставит новую цель — 100 000 пользователей.
Возникает закономерный вопрос:
Выдержит ли текущая архитектура такую нагрузку?
На первый взгляд кажется, что для масштабирования достаточно купить более мощный сервер.
Но реальные проблемы обычно возникают сразу в нескольких местах.
Например:
PostgreSQL начинает медленно выполнять запросы;
FastAPI исчерпывает пул соединений;
Redis становится узким местом;
тяжёлые операции блокируют HTTP-запросы;
Frontend загружает слишком много JavaScript;
API не выдерживает пикового трафика;
фоновые задачи накапливаются в очереди;
внешние сервисы отвечают медленно;
инфраструктурные расходы растут быстрее выручки.
Главная сложность заключается в том, что 100 000 зарегистрированных пользователей не означают 100 000 одновременных подключений.
Для правильного масштабирования нужно сначала понять профиль нагрузки, а затем измерить производительность каждого компонента.
В этой статье разберём, как подготовить Full Stack приложение к росту: от оценки RPS и Load Testing до оптимизации PostgreSQL, Redis, CDN, очередей, Kubernetes, Observability и Capacity Planning.
Часть 1. Что означает 100 000 пользователей
1. Почему количество зарегистрированных пользователей не равно нагрузке
100K Users Scaling начинается не с выбора сервера, а с понимания пользовательской активности.
Представим три приложения.
Первое — корпоративная CRM, в которой пользователи работают преимущественно днём.
Второе — образовательная платформа с пиковыми нагрузками во время занятий.
Третье — социальное приложение с постоянной активностью.
У всех может быть 100 000 зарегистрированных пользователей.
Но требования к инфраструктуре будут совершенно разными.
2. DAU, MAU и Concurrent Users
DAU, MAU и Concurrent Users — ключевые показатели для оценки нагрузки.
DAU — Daily Active Users.
MAU — Monthly Active Users.
Concurrent Users — количество одновременно активных пользователей.
Например:
Registered Users: 100 000
Monthly Active Users: 45 000
Daily Active Users: 12 000
Peak Concurrent Users: 1 500
Это условный сценарий, а не универсальная пропорция.
3. Что такое RPS
Requests Per Second (RPS) — количество HTTP-запросов в секунду.
Например:
GET /api/projects
GET /api/tasks
POST /api/comments
GET /api/notifications
Каждый пользователь может генерировать несколько запросов за короткое время.
Поэтому RPS зависит от поведения пользователей и архитектуры Frontend.
4. Как приблизительно рассчитать RPS
RPS Calculation for SaaS:
Допустим:
12 000 DAU;
80 API-запросов на активного пользователя в день;
24 часа наблюдения.
Получаем:
[RPS_{avg}=\frac{12,000\times80}{86,400}\approx11.1]
Средняя нагрузка — около 11 запросов в секунду.
Но реальная активность распределена неравномерно.
5. Почему Peak RPS важнее среднего
Peak Traffic Calculation:
Если пиковая нагрузка в 10 раз выше средней:
[RPS_{peak}=11.1\times10\approx111]
В таком сценарии система должна выдерживать примерно 111 RPS в пике.
Это лишь иллюстрация.
Настоящий Peak Multiplier нужно определять по метрикам продукта.
6. Что такое Throughput
Application Throughput — объём успешно обработанной работы за единицу времени.
Например:
Requests per second
Jobs per minute
Payments per hour
Documents processed per minute
Высокий RPS не всегда означает высокую полезную производительность.
Если API быстро возвращает ошибки, такой Throughput не является успехом.
7. Что такое Latency
API Latency — время обработки запроса.
Например:
GET /api/projects
Response Time: 120 ms
Но одного среднего времени ответа недостаточно.
8. Что такое P50, P95 и P99
P95 P99 Latency:
Метрика | Значение |
P50 | 50% запросов быстрее указанного времени |
P95 | 95% запросов быстрее указанного времени |
P99 | 99% запросов быстрее указанного времени |
Например:
P50: 80 ms
P95: 250 ms
P99: 900 ms
Это означает, что небольшая часть запросов существенно медленнее остальных.
Именно такие задержки часто ухудшают пользовательский опыт.
9. Почему Average Latency вводит в заблуждение
Average vs Percentile Latency:
Представим:
95 requests: 100 ms
5 requests: 5000 ms
Среднее время ответа будет значительно выше типичного.
Но и одно среднее значение не покажет, насколько плохо чувствуют себя пользователи на медленном хвосте распределения.
Поэтому полезно отслеживать несколько Percentiles.
10. Что такое Capacity Planning
Capacity Planning — процесс оценки ресурсов, необходимых для текущей и будущей нагрузки.
Он включает:
CPU;
RAM;
Database Connections;
Disk IOPS;
Network Bandwidth;
Cache Memory;
Queue Capacity;
External API Limits.
Capacity Planning должен опираться на измерения, а не только на предположения.
Часть 2. Архитектура масштабируемого Full Stack приложения
11. Базовая архитектура React + FastAPI
React FastAPI SaaS Architecture:
Users
|
v
React Frontend
|
v
FastAPI
|
v
PostgreSQL
Для небольшого проекта такая архитектура вполне достаточна.
Но при росте нагрузки появляются дополнительные компоненты.
12. Production Architecture для 100K пользователей
Scalable Full Stack Architecture:
Users
|
v
DNS / CDN
|
v
Load Balancer
|
+---------+---------+
| | |
v v v
FastAPI FastAPI FastAPI
| | |
+---------+---------+
|
+----------+----------+
| | |
v v v
Redis PostgreSQL Queue
| |
v v
Read Replica Workers
|
v
Monitoring + Logging + Tracing
Не все компоненты нужно внедрять одновременно.
Архитектура должна усложняться по мере появления реальных ограничений.
13. Vertical Scaling vs Horizontal Scaling
Vertical Scaling vs Horizontal Scaling:
Vertical Scaling | Horizontal Scaling |
Более мощный сервер | Больше экземпляров приложения |
Проще внедрить | Требует балансировки |
Есть аппаратный предел | Лучше подходит для распределения нагрузки |
Может быть выгодным на старте | Полезно при росте и требованиях к доступности |
Для небольших SaaS Vertical Scaling часто является разумным первым шагом.
14. Почему не стоит начинать с микросервисов
Monolith vs Microservices Scaling:
Модульный монолит может обслуживать большую аудиторию.
Проблемы производительности часто связаны с:
неэффективными SQL-запросами;
отсутствием кеширования;
неправильными индексами;
блокирующими операциями;
плохим управлением соединениями.
Микросервисы не исправляют эти проблемы автоматически.
15. Что такое Stateless Backend
Stateless FastAPI Architecture:
Stateless Backend не хранит критическое пользовательское состояние только в памяти конкретного экземпляра приложения.
Например:
Request 1 -> FastAPI Instance A
Request 2 -> FastAPI Instance B
Оба экземпляра должны корректно обслуживать пользователя.
Сессии, кеш и бизнес-состояние должны храниться в подходящих общих системах.
Часть 3. Load Testing
16. Что такое Load Testing
Load Testing — проверка поведения приложения под ожидаемой нагрузкой.
Цель — определить:
максимальную устойчивую производительность;
задержки;
ошибки;
потребление ресурсов;
узкие места.
Нагрузочные тесты должны моделировать реальные пользовательские сценарии.
17. Load Testing vs Stress Testing
Load Testing vs Stress Testing:
Load Testing проверяет ожидаемую нагрузку.
Stress Testing увеличивает нагрузку до достижения пределов системы.
Например:
Load Test:
100 RPS
Stress Test:
100 -> 200 -> 400 -> 800 RPS
Stress Testing помогает понять, как система деградирует при перегрузке.
18. Что такое Spike Testing
Spike Testing — проверка резкого роста трафика.
Например:
Normal Load: 50 RPS
Sudden Spike: 500 RPS
Recovery: 50 RPS
Такой сценарий может возникать после маркетинговой рассылки или запуска новой функции.
19. Что такое Soak Testing
Soak Testing — длительное тестирование под стабильной нагрузкой.
Например:
150 RPS for 8 hours
Оно помогает обнаруживать:
Memory Leaks;
накопление соединений;
деградацию производительности;
рост очередей;
проблемы с Background Workers.
20. Какие инструменты использовать
Load Testing Tools:
k6;
Locust;
JMeter;
Gatling;
Vegeta.
Для FastAPI особенно удобны k6 и Locust.
Выбор зависит от сценариев, языка тестов и требований команды.
Часть 4. Нагрузочное тестирование через k6
21. Как установить k6
k6 Load Testing можно использовать локально или в CI/CD.
Пример теста:
import http from "k6/http";
import { check } from "k6";
export const options = {
vus: 50,
duration: "2m",
};
export default function () {
const response = http.get(
"https://staging.example.com/api/projects"
);
check(response, {
"status is 200": (r) => r.status === 200,
});
}
Здесь 50 Virtual Users выполняют запросы в течение двух минут.
22. Почему VUs не равны RPS
Virtual Users vs RPS:
Количество виртуальных пользователей не определяет RPS напрямую.
Результат зависит от:
времени ответа;
количества запросов в сценарии;
Think Time;
сетевых задержек;
скорости выполнения теста.
Поэтому RPS нужно измерять отдельно.
23. Как тестировать несколько API
k6 API Scenario Testing:
import http from "k6/http";
import { sleep } from "k6";
export default function () {
http.get("https://staging.example.com/api/projects");
sleep(1);
http.get("https://staging.example.com/api/tasks");
sleep(2);
}
В реальном тесте нужно добавить аутентификацию и проверку ответов.
24. Как задать Performance Thresholds
k6 Performance Thresholds:
export const options = {
vus: 50,
duration: "2m",
thresholds: {
http_req_failed: ["rate<0.01"],
http_req_duration: ["p(95)<500"],
},
};
Это означает:
доля неуспешных HTTP-запросов меньше 1%;
P95 времени ответа меньше 500 мс.
Пороговые значения должны соответствовать требованиям конкретного продукта.
25. Как тестировать целевой RPS
k6 Constant Arrival Rate:
export const options = {
scenarios: {
api_load: {
executor: "constant-arrival-rate",
rate: 100,
timeUnit: "1s",
duration: "5m",
preAllocatedVUs: 100,
maxVUs: 300,
},
},
};
Сценарий пытается запускать 100 итераций в секунду.
Если одна итерация содержит один HTTP-запрос, это приблизительно соответствует целевым 100 RPS.
Нужно следить за dropped_iterations: при нехватке Virtual Users или ресурсов генератора фактическая нагрузка может оказаться ниже заданной.
26. Почему нельзя тестировать только один Endpoint
Realistic Load Testing Scenarios:
Реальная нагрузка состоит из разных операций.
Например:
60% Read Requests
25% Search Requests
10% Write Requests
5% Heavy Operations
Это условный профиль.
Для точных тестов нужно использовать реальные метрики Production.
27. Как создать тестовые данные
Load Testing Data Preparation:
Для достоверного тестирования нужны:
реалистичное количество пользователей;
реальные размеры таблиц;
распределение организаций;
история операций;
достаточное количество документов;
типичные размеры Payload.
Тестирование пустой базы данных почти ничего не говорит о поведении системы с миллионами записей.
28. Почему нагрузочные тесты нужно запускать в Staging
Production-Like Load Testing:
Лучше использовать окружение, максимально похожее на Production.
Важно учитывать:
конфигурацию базы данных;
количество Workers;
сетевые задержки;
размер данных;
кеш;
внешние зависимости.
Нагрузочные тесты непосредственно в Production допустимы только при контролируемом плане, ограничениях и готовности к откату.
Часть 5. FastAPI Performance
29. Как масштабировать FastAPI
FastAPI Horizontal Scaling:
Можно запустить несколько экземпляров приложения:
Load Balancer
|
+-- FastAPI 1
|
+-- FastAPI 2
|
+-- FastAPI 3
Балансировщик распределяет запросы между экземплярами.
30. Async vs Sync в FastAPI
FastAPI Async Performance:
Асинхронность полезна для операций ожидания:
запросов к базе;
HTTP API;
Redis;
сетевых сервисов.
Но async def не ускоряет CPU-Bound вычисления автоматически.
31. Почему Blocking Code опасен
FastAPI Blocking Event Loop:
Плохой пример:
import time
async def slow_operation():
time.sleep(5)
time.sleep() блокирует поток, в котором выполняется Event Loop.
Для асинхронной паузы используется:
import asyncio
async def slow_operation():
await asyncio.sleep(5)
А CPU-Bound работу лучше выносить в подходящий Worker или Process Pool.
32. Как выбрать количество Workers
Uvicorn Workers Configuration:
Пример:
uvicorn app.main:app \
--host 0.0.0.0 \
--port 8000 \
--workers 4
Количество Workers зависит от:
CPU;
памяти;
характера нагрузки;
числа соединений;
контейнерных лимитов.
Нет универсального значения, подходящего для всех FastAPI-приложений.
33. Почему больше Workers не всегда лучше
FastAPI Worker Scaling Limits:
Каждый Worker потребляет память и может создавать собственный пул соединений к PostgreSQL.
Например:
4 Workers
Pool Size: 10
Potential Base Connections: 40
Если увеличить число Workers до 20, потребность в соединениях может значительно вырасти.
Поэтому масштабирование Backend нужно согласовывать с Capacity Planning базы данных.
34. Как настроить HTTP Timeouts
FastAPI Production Timeouts:
Важно согласовать:
Load Balancer Timeout;
Reverse Proxy Timeout;
Application Timeout;
Database Timeout;
External API Timeout.
Если Timeout настроены неправильно, медленные запросы могут удерживать ресурсы слишком долго.
35. Что такое Backpressure
Backpressure in Web Applications — ограничение поступающей работы, когда система не успевает её обрабатывать.
Например:
Incoming Requests
|
v
Concurrency Limit
|
+-- Accepted
|
+-- Rejected / Deferred
Контролируемый отказ иногда лучше, чем полная деградация всех запросов.
Часть 6. Load Balancing
36. Что такое Load Balancer
Load Balancer распределяет входящий трафик между несколькими экземплярами приложения.
Например:
Users
|
v
Load Balancer
|
+-- API 1
+-- API 2
+-- API 3
Это помогает масштабировать приложение горизонтально.
37. Какие алгоритмы балансировки существуют
Load Balancing Algorithms:
Round Robin;
Least Connections;
Weighted Round Robin;
Hash-Based Routing.
Подходящий алгоритм зависит от характеристик трафика и возможностей балансировщика.
38. Как настроить Nginx Load Balancing
Nginx FastAPI Load Balancing:
upstream fastapi_backend {
server api1:8000;
server api2:8000;
server api3:8000;
}
server {
listen 80;
location /api/ {
proxy_pass http://fastapi_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
}
}
Это упрощённый пример для внутренней сети.
В Production дополнительно нужны TLS, корректная конфигурация доверенных Proxy Headers, Timeouts и Health Checks.
39. Что такое Health Check
Application Health Checks:
Например:
GET /health/live
GET /health/ready
Liveness показывает, работает ли процесс.
Readiness показывает, готов ли экземпляр принимать трафик.
Эти проверки решают разные задачи.
40. Почему Readiness Check важен
FastAPI Readiness Probe:
Экземпляр может быть запущен, но ещё не готов обслуживать запросы.
Например:
не завершена инициализация;
не создан пул соединений;
не загружена конфигурация.
Readiness помогает исключать такие экземпляры из балансировки.
При этом проверка не должна создавать чрезмерную нагрузку на зависимости.
Часть 7. PostgreSQL под высокой нагрузкой
41. Почему PostgreSQL часто становится Bottleneck
PostgreSQL Performance Bottleneck:
Основные причины:
медленные SQL-запросы;
отсутствие индексов;
N+1 Queries;
слишком много соединений;
длительные транзакции;
блокировки;
недостаток памяти;
высокая Disk I/O.
Прежде чем увеличивать сервер, нужно определить конкретную причину.
42. Что такое EXPLAIN ANALYZE
PostgreSQL EXPLAIN ANALYZE показывает фактический план выполнения SQL-запроса.
Например:
EXPLAIN (ANALYZE, BUFFERS)
SELECT *
FROM tasks
WHERE organization_id = 42
ORDER BY created_at DESC
LIMIT 50;
Это помогает увидеть:
тип сканирования;
использование индексов;
время выполнения;
количество обработанных строк;
обращения к буферам.
Важно: EXPLAIN ANALYZE действительно выполняет запрос. Для изменяющих SQL-команд это особенно существенно.
43. Как создать Composite Index
PostgreSQL Composite Index Optimization:
Если запрос фильтрует по организации и сортирует по времени:
CREATE INDEX idx_tasks_org_created
ON tasks (
organization_id,
created_at DESC
);
Такой индекс может существенно ускорить запрос.
Но индексы нужно выбирать на основании реальных Query Plans.
44. Почему слишком много индексов плохо
PostgreSQL Index Overhead:
Каждый индекс требует:
места на диске;
обновления при INSERT;
обновления при UPDATE;
обслуживания.
Поэтому нельзя создавать индекс на каждое поле без анализа.
45. Что такое N+1 Query Problem
N+1 Queries SQLAlchemy:
Например:
1 Query: Load Projects
100 Queries: Load Tasks for Each Project
Вместо 101 запроса можно использовать подходящую стратегию загрузки связанных данных.
Например, selectinload или joinedload в SQLAlchemy — в зависимости от структуры данных.
46. Как мониторить медленные запросы
PostgreSQL Slow Query Monitoring:
Полезные инструменты:
pg_stat_statements
;
PostgreSQL Logs;
EXPLAIN ANALYZE;
Database Metrics;
Distributed Tracing.
pg_stat_statements помогает находить запросы с большим суммарным временем выполнения.
47. Что такое Connection Pooling
PostgreSQL Connection Pooling:
Создание соединений к базе данных имеет стоимость.
Connection Pool позволяет повторно использовать уже открытые соединения.
Например:
FastAPI
|
v
Connection Pool
|
v
PostgreSQL
Но слишком большой пул может перегрузить PostgreSQL.
48. Что такое PgBouncer
PgBouncer PostgreSQL — лёгкий Connection Pooler.
Архитектура:
FastAPI Instances
|
v
PgBouncer
|
v
PostgreSQL
Он помогает управлять большим количеством клиентских соединений.
49. Session Pooling vs Transaction Pooling
PgBouncer Pooling Modes:
Session Pooling закрепляет серверное соединение на время клиентской сессии.
Transaction Pooling использует серверное соединение на время транзакции.
Transaction Pooling может быть эффективнее, но требует проверки совместимости с особенностями драйвера, Prepared Statements и Session-Level State.
50. Когда нужны Read Replicas
PostgreSQL Read Replicas:
Если приложение выполняет много тяжёлых запросов на чтение, можно использовать реплики.
Например:
Writes -> Primary PostgreSQL
Reads -> Read Replica
Но репликация обычно асинхронная.
Поэтому возможен Replication Lag.
51. Почему Read Replica не всегда подходит
Read After Write Consistency:
Пользователь создал задачу и сразу открыл список.
Если чтение отправлено на отстающую реплику, новая задача может временно отсутствовать.
Поэтому для операций, требующих немедленной согласованности, может понадобиться чтение из Primary.
52. Что такое Database Partitioning
PostgreSQL Partitioning — разделение большой таблицы на части.
Например:
audit_logs
|
+-- 2026_01
+-- 2026_02
+-- 2026_03
Partitioning полезен для некоторых больших таблиц с предсказуемыми условиями фильтрации и жизненным циклом данных.
Но он не ускоряет автоматически любые запросы.
53. Почему важен VACUUM
PostgreSQL VACUUM Autovacuum:
PostgreSQL использует MVCC.
После обновлений и удалений могут оставаться устаревшие версии строк.
Autovacuum помогает:
очищать устаревшие версии;
поддерживать статистику;
предотвращать некоторые проблемы с Transaction ID.
Неправильная настройка Autovacuum может приводить к росту таблиц и деградации производительности.
Часть 8. Redis и кеширование
54. Зачем нужен Redis при масштабировании
Redis Caching for SaaS:
Redis можно использовать для:
кеширования API;
Rate Limiting;
временных данных;
распределённых счётчиков;
некоторых механизмов очередей;
хранения сессий при подходящей архитектуре.
Но Redis не должен становиться обязательной зависимостью для каждой операции без необходимости.
55. Что такое Cache-Aside Pattern
Cache-Aside Pattern:
Request
|
v
Check Redis
|
+-- Hit -> Return Data
|
+-- Miss -> Query PostgreSQL
|
v
Save to Redis
|
v
Return Data
Это одна из наиболее распространённых стратегий кеширования.
56. Как кешировать данные в FastAPI
FastAPI Redis Cache:
import json
async def get_project(project_id: str):
cache_key = f"project:{project_id}"
cached = await redis.get(cache_key)
if cached is not None:
return json.loads(cached)
project = await project_service.get(project_id)
await redis.set(
cache_key,
json.dumps(project),
ex=60,
)
return project
Это упрощённый пример.
Для Multi-Tenant SaaS Cache Key должен учитывать границы доступа, а кешируемые данные не должны обходить Authorization.
57. Почему Cache Key должен учитывать Tenant
Multi-Tenant Redis Caching:
Опасный вариант:
project:123
Если идентификаторы не являются глобально уникальными или доступ зависит от контекста, такой ключ может привести к неправильному возврату данных.
Более безопасная структура:
tenant:42:project:123
При этом Authorization всё равно должна выполняться корректно.
58. Что такое Cache Invalidation
Cache Invalidation Strategy:
Когда данные изменяются, кеш может устареть.
Например:
Update Project
|
v
Commit PostgreSQL
|
v
Invalidate Cache
Инвалидацию нужно проектировать с учётом Race Conditions.
Для некоторых данных достаточно короткого TTL.
59. Что такое Cache Stampede
Cache Stampede возникает, когда много запросов одновременно обнаруживают отсутствие кеша и обращаются к базе.
Например:
1000 Requests
|
v
Cache Miss
|
v
1000 Database Queries
Это может создать резкий всплеск нагрузки.
60. Как защититься от Cache Stampede
Cache Stampede Prevention:
Полезные методы:
TTL Jitter;
Single Flight;
Distributed Lock;
Stale-While-Revalidate;
предварительное обновление популярных ключей.
Выбор зависит от допустимой устарелости данных.
61. Что такое Cache Hit Ratio
Redis Cache Hit Ratio:
[HitRatio=\frac{CacheHits}{CacheHits+CacheMisses}]
Например:
Cache Hits: 9000
Cache Misses: 1000
Hit Ratio: 90%
Высокий Hit Ratio полезен, но не является самоцелью.
Важнее снижение нагрузки на Backend и улучшение Latency.
62. Почему Redis тоже может стать Bottleneck
Redis Performance Bottleneck:
Проблемы возникают при:
больших значениях;
чрезмерном количестве ключей;
горячих ключах;
тяжёлых командах;
недостатке памяти;
сетевых ограничениях.
Поэтому Redis также требует мониторинга.
Часть 9. CDN и оптимизация React
63. Что такое CDN
Content Delivery Network (CDN) — сеть серверов, доставляющих контент пользователям из географически близких точек.
CDN особенно полезен для:
JavaScript;
CSS;
изображений;
шрифтов;
статических файлов.
64. Почему React Frontend стоит отдавать через CDN
React CDN Deployment:
Например:
User
|
v
CDN Edge
|
v
Static React Assets
Это уменьшает нагрузку на Backend и часто улучшает скорость загрузки.
65. Как настроить Cache Headers
HTTP Cache-Control:
Для версионированных статических файлов можно использовать:
Cache-Control: public, max-age=31536000, immutable
Но HTML-файл приложения обычно требует другой политики кеширования, чтобы пользователи получали актуальные ссылки на Assets.
66. Что такое Code Splitting
React Code Splitting:
Вместо загрузки всего приложения сразу можно разделить JavaScript на части.
Например:
import { lazy } from "react";
const AdminPage = lazy(
() => import("./pages/AdminPage")
);
Это помогает уменьшить Initial Bundle.
67. Что такое Lazy Loading
React Lazy Loading:
Необязательные компоненты можно загружать только при необходимости.
Например:
большие Charts;
Admin Modules;
Rich Text Editors;
дополнительные страницы.
Но чрезмерное дробление может увеличить количество сетевых запросов.
68. Какие Web Vitals важны
Core Web Vitals React:
LCP — Largest Contentful Paint;
INP — Interaction to Next Paint;
CLS — Cumulative Layout Shift.
Они помогают оценивать реальный пользовательский опыт.
69. Почему Backend Performance не равен Frontend Performance
Frontend vs Backend Performance:
API может отвечать за 100 мс.
Но интерфейс всё равно будет медленным, если:
загружается огромный Bundle;
выполняется тяжёлый JavaScript;
слишком много React Re-Renders;
изображения не оптимизированы;
основной поток браузера заблокирован.
Поэтому Frontend нужно измерять отдельно.
Часть 10. Background Jobs и очереди
70. Почему тяжёлые задачи нужно выносить из HTTP
Background Jobs Scaling:
Например:
генерация PDF;
отправка Email;
обработка изображений;
создание отчётов;
синхронизация с внешними API.
Такие операции лучше выполнять через Background Workers, если пользователю не требуется немедленный результат.
71. Архитектура очередей задач
Task Queue Architecture:
FastAPI
|
v
Message Broker
|
v
Background Workers
|
v
PostgreSQL / Object Storage
Для реализации можно использовать Celery с подходящим Broker.
72. Почему очередь не решает проблему бесконечной нагрузки
Queue Backpressure:
Если задачи поступают быстрее, чем Workers их обрабатывают, очередь будет расти.
Например:
Incoming: 100 jobs/min
Processing: 60 jobs/min
Backlog Growth: 40 jobs/min
Поэтому нужно измерять Queue Lag и Processing Rate.
73. Как масштабировать Workers
Celery Worker Scaling:
Можно увеличивать количество Workers.
Но нужно учитывать:
CPU;
RAM;
Database Connections;
External API Limits;
Idempotency;
размер очереди.
Масштабирование Workers не должно перегружать общие зависимости.
74. Почему важен Idempotency
Idempotent Background Jobs:
Фоновая задача может выполниться повторно из-за Retry или сбоя.
Например, задача создания счёта не должна создавать два одинаковых счёта.
Для этого используют:
Idempotency Keys;
Unique Constraints;
State Checks;
Transactional Processing.
75. Что такое Dead Letter Queue
Dead Letter Queue (DLQ) — место для сообщений, которые не удалось обработать после заданного числа попыток.
Это помогает:
расследовать ошибки;
повторно обрабатывать сообщения;
не блокировать основную очередь.
Конкретная реализация зависит от используемого Broker.
Часть 11. Rate Limiting и защита от перегрузки
76. Зачем нужен Rate Limiting
API Rate Limiting защищает Backend от чрезмерного количества запросов.
Например:
Free Plan:
60 requests/minute
Pro Plan:
600 requests/minute
Это условные значения.
Реальные лимиты зависят от бизнес-модели и возможностей инфраструктуры.
77. Что такое Token Bucket
Token Bucket Algorithm — алгоритм ограничения частоты запросов.
У пользователя есть определённое количество токенов.
Каждый запрос расходует токен.
Токены постепенно восстанавливаются.
Это позволяет допускать короткие всплески активности.
78. Почему Rate Limiting нужен на нескольких уровнях
Multi-Layer Rate Limiting:
Например:
CDN / WAF
|
v
API Gateway
|
v
FastAPI
|
v
Business Quotas
Каждый уровень решает свою задачу.
WAF защищает от некоторых типов нежелательного трафика.
API Rate Limiting ограничивает частоту запросов.
Business Quotas контролируют использование платных ресурсов.
79. Что такое Load Shedding
Load Shedding — контролируемый отказ от части работы при перегрузке.
Например:
Critical API Requests -> Prioritized
Noncritical Analytics -> Deferred
Это позволяет сохранить доступность важных функций.
80. Почему нужны Request Size Limits
API Request Size Limits:
Большие Payload могут потреблять много памяти и CPU.
Поэтому полезно ограничивать:
размер JSON;
размер файлов;
количество элементов в Bulk Request;
глубину сложных структур;
Page Size.
Ограничения нужно применять на подходящих уровнях инфраструктуры.
Часть 12. Observability и SLO
81. Что такое Observability
Observability for Full Stack Applications — способность понимать внутреннее состояние системы по её внешним сигналам.
Основные сигналы:
Logs;
Metrics;
Traces.
Дополнительно полезны Profiles и другие диагностические данные.
82. Какие метрики отслеживать
Full Stack Monitoring Metrics:
Компонент | Метрики |
FastAPI | RPS, Error Rate, P95, P99 |
PostgreSQL | Query Latency, Connections, Locks |
Redis | Hit Ratio, Memory, Evictions |
Queue | Backlog, Queue Lag, Failed Jobs |
React | LCP, INP, CLS |
Infrastructure | CPU, RAM, Disk, Network |
Метрики должны быть связаны с пользовательским опытом.
83. Что такое SLI
Service Level Indicator (SLI) — измеримый показатель качества сервиса.
Например:
Percentage of successful API requests
Или:
Percentage of requests under 500 ms
84. Что такое SLO
Service Level Objective (SLO) — целевое значение SLI.
Например:
99.9% of API requests succeed
over a rolling 30-day window
SLO должен быть реалистичным и соответствовать требованиям продукта.
85. Что такое Error Budget
Error Budget — допустимый объём нарушений SLO.
Например, при SLO 99.9% допустимая доля неуспешных запросов составляет 0.1% в выбранном периоде.
Error Budget помогает принимать решения о скорости релизов и надёжности.
86. Как настроить Alerting
Production Alerting Strategy:
Полезные сигналы:
высокий Error Rate;
рост P95/P99;
исчерпание Database Connections;
увеличение Queue Lag;
нехватка диска;
частые Restart;
ошибки критических бизнес-операций.
Alerts должны быть связаны с действиями, которые команда действительно может выполнить.
Часть 13. Отказоустойчивость
87. Что такое High Availability
High Availability Architecture — архитектура, снижающая вероятность недоступности сервиса.
Например:
Load Balancer
|
+-- Instance A
|
+-- Instance B
Если один экземпляр выходит из строя, второй может продолжить обработку запросов.
Но доступность всей системы зависит и от общих компонентов.
88. Что такое Single Point of Failure
Single Point of Failure (SPOF) — компонент, отказ которого приводит к отказу всей системы.
Например:
3 FastAPI Instances
1 PostgreSQL Server
Несколько Backend Instances не обеспечивают полной отказоустойчивости, если единственная база данных недоступна.
89. Что такое Database Failover
PostgreSQL Failover — переключение на резервный экземпляр базы данных при отказе основного.
Реализация зависит от:
Managed Database;
Replication;
Orchestration;
требований к RPO и RTO.
Failover нужно регулярно тестировать.
90. Что такое RPO и RTO
RPO vs RTO:
RPO — Recovery Point Objective.
Максимально допустимая потеря данных по времени.
RTO — Recovery Time Objective.
Максимально допустимое время восстановления сервиса.
Например:
RPO: 5 minutes
RTO: 30 minutes
Это условные цели, которые должны определяться бизнес-требованиями.
91. Почему Backup не равен High Availability
Backup vs High Availability:
Backup помогает восстановить данные.
High Availability помогает уменьшить простой.
Они решают разные задачи.
Для Production нужны и резервное копирование, и план восстановления.
92. Почему нужно тестировать Disaster Recovery
Disaster Recovery Testing:
Недостаточно просто включить автоматические Backups.
Нужно регулярно проверять:
возможность восстановления;
целостность данных;
время восстановления;
доступность ключей шифрования;
корректность инструкций.
Часть 14. Autoscaling и Kubernetes
93. Что такое Autoscaling
Application Autoscaling — автоматическое изменение количества ресурсов в зависимости от нагрузки.
Например:
Low Traffic -> 2 API Instances
High Traffic -> 8 API Instances
Но Autoscaling не происходит мгновенно.
Поэтому нужно учитывать время запуска экземпляров.
94. Что такое Horizontal Pod Autoscaler
Kubernetes Horizontal Pod Autoscaler (HPA) изменяет количество Pod на основании выбранных метрик.
Например:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: fastapi-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: fastapi
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Это упрощённый пример.
Для работы CPU-Based HPA нужны корректные Resource Requests и доступные метрики.
95. Почему CPU Autoscaling не всегда достаточно
Autoscaling Metrics Selection:
Высокая нагрузка может проявляться не только через CPU.
Например:
Queue Lag;
Request Concurrency;
Latency;
Custom Business Metrics.
Но Autoscaling по Latency требует осторожной настройки, поскольку задержка может расти из-за внешней зависимости.
96. Нужен ли Kubernetes для 100K пользователей
Kubernetes vs Docker Compose Production:
Не обязательно.
Для многих SaaS достаточно:
Managed Containers;
Load Balancer;
Managed PostgreSQL;
Redis;
CDN;
Background Workers.
Kubernetes полезен при сложной инфраструктуре и развитых операционных требованиях.
Но он увеличивает стоимость сопровождения.
Часть 15. Инфраструктурные расходы
97. Почему нужно считать Infrastructure Cost
SaaS Infrastructure Cost Optimization:
Рост пользователей должен сопровождаться контролем затрат.
Основные категории:
Compute;
Database;
Redis;
Storage;
CDN;
Network Egress;
Monitoring;
Background Workers;
External APIs.
98. Пример условного бюджета
100K Users Infrastructure Cost Estimate:
Компонент | Условный бюджет в месяц |
API Compute | $300 |
PostgreSQL | $500 |
Redis | $100 |
Workers | $200 |
Object Storage | $80 |
CDN / Traffic | $150 |
Monitoring | $120 |
Итого | $1 450 |
Это исключительно иллюстративный расчёт, а не рыночная котировка или гарантия достаточной мощности.
Реальные расходы могут отличаться в разы в зависимости от региона, провайдера, трафика, объёма данных и требований к доступности.
99. Что такое Cost per Active User
Cost per Active User:
[CostPerActiveUser=\frac{MonthlyInfrastructureCost}{MonthlyActiveUsers}]
Например:
[\frac{1450}{45000}\approx $0.032]
В этом условном сценарии инфраструктурные расходы составляют около 3.2 цента на одного MAU в месяц.
Но этот показатель не учитывает все операционные и бизнес-расходы.
100. Почему оптимизация стоимости важна для SaaS
SaaS Unit Economics:
Если инфраструктурные расходы растут быстрее выручки, масштабирование может ухудшить экономику продукта.
Поэтому нужно измерять:
Cost per Tenant;
Cost per Request;
Cost per Background Job;
Storage Cost;
External API Cost.
Особенно важно учитывать дорогие AI-функции и обработку больших файлов.
Часть 16. Практический план масштабирования
101. Этап 1. Измерить текущую систему
Scaling Roadmap Step 1:
Сначала соберите:
RPS;
P95/P99;
Error Rate;
CPU;
RAM;
PostgreSQL Connections;
Slow Queries;
Redis Hit Ratio;
Queue Lag.
Без этих данных оптимизация превращается в угадывание.
102. Этап 2. Оптимизировать самые дорогие запросы
Scaling Roadmap Step 2:
Найдите:
Slow SQL;
N+1 Queries;
неэффективную пагинацию;
тяжёлые API Endpoints;
повторные запросы Frontend.
Оптимизируйте их до добавления новых серверов.
103. Этап 3. Добавить кеширование
Scaling Roadmap Step 3:
Определите данные, которые:
часто читаются;
редко изменяются;
дорого вычисляются;
допускают ограниченную устарелость.
Добавьте Redis Cache там, где он действительно снижает нагрузку.
104. Этап 4. Вынести тяжёлые операции
Scaling Roadmap Step 4:
Перенесите:
отчёты;
Email;
импорт;
обработку файлов;
длительные интеграции;
в Background Jobs.
Добавьте Retry, Idempotency и Monitoring.
105. Этап 5. Масштабировать Backend
Scaling Roadmap Step 5:
Сделайте FastAPI Stateless.
Добавьте Load Balancer.
Запустите несколько экземпляров приложения.
Проверьте, что Database Connections и Redis выдерживают новую конфигурацию.
106. Этап 6. Оптимизировать PostgreSQL
Scaling Roadmap Step 6:
Проверьте:
индексы;
Query Plans;
Connection Pooling;
VACUUM;
Lock Contention;
Disk IOPS;
Slow Queries.
При необходимости рассмотрите PgBouncer и Read Replicas.
107. Этап 7. Оптимизировать Frontend
Scaling Roadmap Step 7:
Используйте:
CDN;
Code Splitting;
Lazy Loading;
Image Optimization;
Browser Caching;
Performance Monitoring.
Это помогает уменьшить нагрузку на инфраструктуру и улучшить UX.
108. Этап 8. Провести Load Testing
Scaling Roadmap Step 8:
Проверьте:
Normal Load
Peak Load
Spike Load
Stress Load
Long Duration Load
Измерьте пределы системы.
Не ограничивайтесь успешным прохождением одного теста.
109. Этап 9. Настроить отказоустойчивость
Scaling Roadmap Step 9:
Добавьте:
Health Checks;
Readiness Checks;
Backups;
Failover Strategy;
Recovery Procedures;
Incident Alerts.
Проверьте, как система ведёт себя при отказе отдельных компонентов.
110. Этап 10. Повторять Capacity Planning
Scaling Roadmap Step 10:
Рост пользователей — непрерывный процесс.
Поэтому Capacity Planning нужно пересматривать при изменении:
количества пользователей;
поведения клиентов;
функциональности;
размера данных;
тарифов;
инфраструктуры.
Часть 17. Типичные ошибки масштабирования
111. Ошибки при подготовке приложения к 100K пользователей
Первая ошибка — считать зарегистрированных пользователей одновременной нагрузкой.
Вторая — выбирать инфраструктуру без измерения RPS.
Третья — ориентироваться только на Average Latency.
Четвёртая — не отслеживать P95/P99.
Пятая — увеличивать количество серверов, не оптимизируя SQL.
Шестая — запускать слишком много FastAPI Workers.
Седьмая — не учитывать Database Connection Limits.
Восьмая — использовать Redis без стратегии Cache Invalidation.
Девятая — не защищаться от Cache Stampede.
Десятая — хранить состояние только в памяти одного Backend Instance.
Одиннадцатая — выполнять тяжёлые задачи внутри HTTP Request.
Двенадцатая — не контролировать Queue Lag.
Тринадцатая — не использовать Idempotency для фоновых операций.
Четырнадцатая — тестировать только пустую базу данных.
Пятнадцатая — проводить Load Testing без реалистичных сценариев.
Шестнадцатая — не учитывать внешние API Limits.
Семнадцатая — считать Read Replicas полностью синхронными.
Восемнадцатая — не проверять Backup Restore.
Девятнадцатая — использовать Kubernetes без операционной необходимости.
Двадцатая — не измерять Infrastructure Cost.
Эти ошибки масштабирования Full Stack приложений могут привести к деградации производительности, росту расходов и снижению доступности сервиса.
Часть 18. Production Checklist
112. Чек-лист приложения на 100 000 пользователей
100K Users Production Checklist:
Traffic
Измерен DAU.
Измерен MAU.
Измерены Concurrent Users.
Измерен Average RPS.
Измерен Peak RPS.
Определён профиль пользовательских запросов.
Backend
FastAPI не блокирует Event Loop тяжёлыми операциями.
Настроены Timeouts.
Настроены Concurrency Limits.
Backend поддерживает Horizontal Scaling.
Есть Health Checks.
Есть Readiness Checks.
PostgreSQL
Проверены Slow Queries.
Используется EXPLAIN ANALYZE.
Оптимизированы индексы.
Устранены критические N+1 Queries.
Настроен Connection Pooling.
Контролируется число соединений.
Мониторится Autovacuum.
Проверяются Lock Contention и Disk I/O.
Redis
Есть стратегия кеширования.
Есть Cache Invalidation.
Настроен TTL.
Контролируется Cache Hit Ratio.
Есть защита от Cache Stampede.
Проверены Memory Limits.
Frontend
Статические Assets доставляются эффективно.
Используется CDN при необходимости.
Оптимизирован JavaScript Bundle.
Есть Code Splitting.
Настроен Browser Caching.
Измеряются Core Web Vitals.
Background Jobs
Тяжёлые задачи вынесены из HTTP.
Настроены Retries.
Есть Idempotency.
Мониторится Queue Lag.
Есть обработка Failed Jobs.
Контролируется Concurrency.
Reliability
Есть Load Balancer.
Есть Backups.
Проверено восстановление.
Определены RPO и RTO.
Есть Incident Runbooks.
Настроен Alerting.
Testing
Проведён Load Testing.
Проведён Stress Testing.
Проведён Spike Testing.
Проведён Soak Testing.
Используются реалистичные данные.
Зафиксированы Performance Thresholds.
Cost
Измеряются Compute Costs.
Измеряются Database Costs.
Измеряются Storage Costs.
Измеряется Network Egress.
Контролируются External API Costs.
Есть регулярный Cost Review.
FAQ
Может ли FastAPI обслуживать 100 000 пользователей?
Да. Но фактическая пропускная способность зависит от профиля запросов, архитектуры, базы данных, инфраструктуры и оптимизации.
Сколько серверов нужно для 100 000 пользователей?
Универсального числа нет. Нужно знать Peak RPS, Latency Targets и ресурсоёмкость запросов.
Что важнее: RPS или Concurrent Users?
Оба показателя полезны. RPS показывает интенсивность запросов, а Concurrent Users — уровень одновременной активности.
Что такое P95 Latency?
Время, быстрее которого выполняется 95% измеренных запросов.
Что такое P99 Latency?
Время, быстрее которого выполняется 99% измеренных запросов.
Что такое Load Testing?
Проверка поведения системы под ожидаемой нагрузкой.
Чем Load Testing отличается от Stress Testing?
Load Testing проверяет нормальную нагрузку, а Stress Testing помогает найти пределы системы.
Что такое Spike Testing?
Тестирование резкого увеличения нагрузки.
Что такое Soak Testing?
Длительное тестирование под устойчивой нагрузкой.
Что лучше для FastAPI: k6 или Locust?
Оба инструмента подходят. k6 удобен для сценариев на JavaScript, Locust — для Python-ориентированных тестов.
Нужно ли использовать Redis для 100K пользователей?
Не обязательно, но Redis может значительно помочь при повторяющихся чтениях, Rate Limiting и некоторых других задачах.
Что такое Cache Stampede?
Ситуация, когда много запросов одновременно обращаются к Backend после Cache Miss.
Что такое PgBouncer?
Connection Pooler для PostgreSQL.
Когда нужны Read Replicas?
Когда нагрузка на чтение достаточно велика и её можно безопасно распределить с учётом Replication Lag.
Нужен ли PostgreSQL Partitioning?
Не всегда. Он полезен для некоторых больших таблиц, но требует анализа запросов.
Что такое Stateless Backend?
Backend, который не зависит от локального состояния одного экземпляра для корректной обработки запросов.
Зачем нужен Load Balancer?
Чтобы распределять запросы между несколькими экземплярами приложения.
Что такое Horizontal Scaling?
Увеличение количества экземпляров сервиса.
Что такое Vertical Scaling?
Увеличение ресурсов одного сервера.
Что такое Backpressure?
Механизм ограничения поступающей работы при нехватке ресурсов.
Что такое Load Shedding?
Контролируемый отказ от части нагрузки для сохранения работоспособности важных функций.
Что такое CDN?
Сеть доставки контента, которая помогает ускорять загрузку статических ресурсов.
Нужно ли использовать Kubernetes?
Не обязательно. Для многих SaaS достаточно Managed Containers и других управляемых сервисов.
Что такое SLO?
Целевое значение измеримого показателя качества сервиса.
Что такое Error Budget?
Допустимый объём нарушений выбранного SLO.
Что такое High Availability?
Архитектурный подход, направленный на снижение времени недоступности сервиса.
Что такое RPO?
Максимально допустимая потеря данных по времени.
Что такое RTO?
Максимально допустимое время восстановления сервиса.
Сколько стоит инфраструктура для 100K пользователей?
Стоимость сильно зависит от нагрузки, объёма данных, провайдера и требований к доступности. Оценивать её нужно через Capacity Planning и реальные тесты.
Можно ли масштабировать монолит до 100K пользователей?
Да. Хорошо спроектированный модульный монолит может обслуживать большую аудиторию без перехода на микросервисы.
Как понять, что пора масштабироваться?
По устойчивому росту Latency, Error Rate, Queue Lag, насыщению ресурсов и результатам Load Testing.
Заключение
Подготовка Full Stack приложения к 100 000 пользователей — это не задача покупки более мощного сервера.
Это процесс систематического измерения, оптимизации и масштабирования архитектуры.
React должен быстро загружаться и эффективно работать в браузере.
FastAPI должен обрабатывать запросы без ненужных блокировок и поддерживать горизонтальное масштабирование.
PostgreSQL должен использовать эффективные индексы, подходящие Query Plans и контролируемое количество соединений.
Redis должен снижать нагрузку, а не создавать новые проблемы с устаревшими данными.
CDN помогает ускорять доставку статических ресурсов.
Background Workers позволяют выполнять тяжёлые операции независимо от HTTP-запросов.
Load Balancer распределяет трафик между экземплярами Backend.
Observability показывает, где возникают задержки и ошибки.
Load Testing помогает проверить систему до того, как реальные пользователи столкнутся с проблемами.
Capacity Planning позволяет заранее оценивать потребность в ресурсах.
High Availability и Disaster Recovery уменьшают последствия отказов.
А контроль инфраструктурных расходов помогает сохранить устойчивую экономику SaaS.
Главный принцип масштабирования: сначала измеряйте, затем находите узкое место, оптимизируйте его и только после этого добавляйте ресурсы.
Не нужно внедрять Redis, Kafka, Kubernetes и микросервисы одновременно.
Начните с производительного монолита, хороших SQL-запросов, понятных метрик и реалистичных нагрузочных тестов.
Затем добавляйте новые компоненты по мере появления подтверждённой необходимости.
Так можно построить Full Stack приложение, которое будет расти вместе с продуктом и выдерживать не только 100 000 пользователей, но и значительно более высокую нагрузку при соответствующей архитектуре и инфраструктуре.