# Первая тысяча пользователей: что ломается первым

> Не сервер и не нагрузка, а запросы в цикле, пропущенные индексы, тяжёлая работа внутри запроса и лимиты почты. Как найти это заранее.

Published: 2026-04-06 · Source: https://subxcat.com/ru/articles/first-thousand-users · Author: SUBXCAT

Тысяча пользователей — это немного. Сервер, который тянул демо, обычно справится и с ними. Ломается не железо, а допущения, которые были верны, пока в базе было двадцать строк и один тестовый аккаунт. Хорошая новость: эти поломки довольно предсказуемы.

## Запросы в цикле

Самая частая причина медленных страниц в коде, написанном с ИИ, — проблема N+1. Страница загружает список заказов одним запросом, а потом для каждого заказа отдельным запросом подтягивает клиента, отдельным — товары, отдельным — статус доставки. На десяти заказах это тридцать быстрых запросов, и никто ничего не замечает. На пятистах — полторы тысячи, и страница открывается несколько секунд.

Как найти: включи логирование запросов к базе в разработке и открой любую страницу со списком. Если число запросов растёт вместе с числом строк на экране, это оно. Лечится загрузкой связанных данных одним запросом — через `join`, `in (...)` или встроенную подгрузку связей в ORM.

## Пропущенные индексы

Пока таблица маленькая, база читает её целиком за миллисекунды, и отсутствие индекса незаметно. Потом таблица растёт, и тот же запрос начинает занимать сотни миллисекунд — причём сразу у всех.

Первые кандидаты на индекс:

- внешние ключи — Postgres не создаёт для них индекс автоматически;
- колонки, по которым фильтруют чаще всего: владелец записи, статус, дата;
- колонки, по которым сортируют списки с пагинацией.

Проверить конкретный запрос помогает `explain analyze`: если в плане видно последовательное чтение большой таблицы ради нескольких строк, индекса не хватает. Только не добавляй индексы на всё подряд — каждый замедляет запись.

## Списки без пагинации

Эндпоинт, который отдаёт «все проекты пользователя» или «все сообщения в чате», работает, пока их пять. У активного пользователя их становится несколько тысяч, и ответ весит мегабайты. Пагинацию проще добавить сейчас, чем потом объяснять, почему у самых преданных клиентов приложение тормозит сильнее всех.

## Тяжёлая работа внутри запроса

Отправка письма, генерация PDF, обращение к ИИ, обработка картинки — всё это часто выполняется прямо в обработчике HTTP-запроса. Человек ждёт, соединение держится, и если внешний сервис отвечает медленно, запрос падает по таймауту. Хуже всего, когда действие при этом наполовину выполнилось: заказ создан, а письмо не ушло.

Такую работу выносят в очередь фоновых задач. Запрос сохраняет данные и ставит задачу, задача выполняется отдельно, с повторами при ошибке. Человек получает ответ сразу, а не после того, как сторонний сервис соизволит ответить.

## Лимиты почты

Письма с подтверждением, сбросом пароля и уведомлениями внезапно становятся частью критического пути. И у почты есть лимиты, о которых узнают в момент, когда они кончились: суточный предел у почтового ящика или бесплатного тарифа, ограничение на скорость отправки, блокировка за жалобы на спам.

Что проверить:

- какой у отправителя суточный лимит и сколько писем ты отправляешь сейчас;
- настроены ли SPF, DKIM и DMARC — без них письма уходят в спам у заметной части получателей;
- не идут ли рассылки и письма входа через один и тот же канал. Если маркетинговая рассылка выберет лимит, люди перестанут получать коды для входа.

## Соединения с базой

Серверные функции на платформах вроде Vercel или Netlify открывают соединение с базой на каждый экземпляр. При росте трафика экземпляров становится много, и база упирается в предел одновременных соединений. Снаружи это выглядит как случайные ошибки, которые появляются и пропадают. Решение — пулер соединений между функциями и базой; у управляемых баз он обычно уже есть, его просто нужно включить и использовать правильную строку подключения.

## Как найти это заранее

Самый дешёвый способ — сгенерировать на стейджинге в десять раз больше данных, чем у тебя сейчас, и пройти основные сценарии. Медленные страницы видно сразу. Вторая привычка — журнал медленных запросов в продакшне: всё, что дольше, скажем, полусекунды, записывается, и раз в неделю кто-то на это смотрит.

SUBXCAT может пройтись по проекту до того, как эти места найдут пользователи, и починить самые дорогие из них.
