Все статьи

Как подготовить Full Stack приложение к 100 000 пользователей: Load Testing, Redis, PostgreSQL, CDN и масштабирование архитектуры

Полное руководство для Full Stack разработчика: масштабирование React + FastAPI SaaS, оптимизация базы данных, балансировка нагрузки, кеширование, очереди задач, отказоустойчивость и расчёт инфраструктурных затрат

30 минут чтения

Представим, что вы создали 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

Object Storage

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 пользователей, но и значительно более высокую нагрузку при соответствующей архитектуре и инфраструктуре.


Наверх