API интеграция: 5 ключевых метрик задержки под нагрузкой
В нагрузочном тесте API легко получить красивый график и бесполезный результат. Среднее время ответа выглядит прилично, запросы в целом проходят, а пользователи всё равно жалуются на зависания.
Ратмир Чеботарев·Обновлено: 14 октября 2026 г.·8 мин

Причина обычно сидит в хвосте распределения: небольшая доля запросов отвечает настолько медленно, что портит впечатление от сервиса и может запускать цепочку таймаутов в соседних системах.
Для анализа задержки нужны не одна «скорость API», а несколько показателей с разным смыслом. Перцентили p50, p95 и p99 показывают, как распределено время ответа. Пропускная способность и доля ошибок помогают понять, что происходит с сервисом под нагрузкой. Это пять метрик, которые стоит читать вместе, а не выносить по одной в презентацию с победным заголовком.
Среднее удобно для отчёта, хвост важен для продакшена
Среднее значение сглаживает картину. Большинство запросов может завершаться быстро, а отдельные операции — ждать ответа базы, внешнего сервиса или освобождения соединения. В общей цифре эти медленные запросы теряются. Для пользователя, которому достался именно такой запрос, утешение в виде хорошего среднего малоубедительно.
Задержку лучше рассматривать как распределение. Это не абстрактное усложнение метрик, а способ увидеть, насколько предсказуемо ведёт себя API. Если сервис обслуживает множество операций, медиана может оставаться стабильной, пока медленный хвост уже растёт. Такой сдвиг часто заметен в p95 или p99 раньше, чем в общей средней величине.
Ключевое условие — тестировать сценарий, похожий на реальную эксплуатацию. Один эндпоинт, который получает лёгкие запросы из локального генератора, не описывает поведение интеграции в целом. В рабочем потоке есть разные типы операций, неодинаковые объёмы данных, сетевые переходы, авторизация, обращения к целевым системам и конкуренция за ресурсы. Нагрузочное тестирование API должно отражать хотя бы существенные особенности этого потока.
При этом у перцентилей есть оговорка: на малом количестве запросов отдельные выбросы заметно влияют на результат. В таком тесте цифра p99 может выглядеть драматично, но выборка недостаточна, чтобы считать её устойчивой характеристикой сервиса. Чем реже измеряемое событие, тем аккуратнее нужно трактовать его оценку.
Среднее показывает, как выглядит масса запросов. Перцентили помогают заметить, что происходит с теми, кому не повезло.
Первые три метрики: p50, p95 и p99
p50 — медианная задержка. Половина запросов завершилась быстрее этого значения, половина — медленнее. Это полезная опорная точка для типичного запроса, но плохой единственный показатель здоровья API. Если p50 хорошая, это ещё не значит, что сервис стабилен для всех клиентов.
p95 показывает границу, в пределах которой завершились 95% запросов. Оставшаяся часть ответила медленнее. Для сервисов, где важна предсказуемость отклика, p95 обычно информативнее медианы: она уже захватывает заметную часть медленного хвоста, но не так чувствительна к единичным экстремальным значениям, как p99.
p99 задаёт границу для 99% запросов. Этот показатель особенно полезен, когда редкие задержки имеют практические последствия: например, вызывают таймауты у клиента или задерживают цепочку интеграционных вызовов. Но p99 требует аккуратной интерпретации. При небольшой выборке несколько медленных запросов могут сильно его сдвинуть, а график получит видимость точности, которой данные не обеспечивают.
| Метрика | Что показывает | Как читать |
|---|---|---|
| p50 | Медианное время ответа | Ориентир для середины распределения; не описывает медленные запросы |
| p95 | Граница для 95% запросов | Показывает поведение основной массы вместе с заметной частью хвоста |
| p99 | Граница для 99% запросов | Помогает отслеживать редкие, но потенциально болезненные задержки |
| Частота запросов | Сколько запросов выполняется за единицу времени | Характеризует пропускную способность, а не задержку отдельного запроса |
| Доля ошибок | Какая доля запросов завершилась ошибкой | Показывает надёжность результата теста, но сама по себе не измеряет время ответа |
Перцентили не заменяют друг друга. Если p50 стабильна, а p95 ухудшается, проблема может затрагивать не каждый запрос, но становится систематической для медленной части потока. Если вместе с p95 резко растёт p99, хвост становится тяжелее. Для диагностики полезно смотреть не только на итоговые числа, но и на то, как они меняются при увеличении нагрузки и в разных сценариях.
Не стоит превращать один перцентиль в универсальный рейтинг API. Для одного сервиса приемлемый бюджет задержки может быть другим, чем для другого. Значение зависит от того, что делает endpoint, кто его вызывает и сколько времени занимает вся пользовательская или межсервисная операция. Универсального норматива p50, p95 или p99 для любого API нет.
Ещё две метрики: пропускная способность и ошибки
Четвёртый показатель — количество запросов и их частота. В k6 метрика http_reqs отражает общее число HTTP-запросов и среднюю частоту запросов в секунду. Она отвечает на вопрос о пропускной способности теста. Задержку отдельного запроса она не измеряет, хотя на графике рядом с задержкой часто выглядит как будто «ещё одна скорость API». Это разные вещи.
Если частота запросов растёт, а p95 остаётся в пределах заданного бюджета, сервис обрабатывает увеличившийся поток без заметного ухудшения соответствующей части распределения. Если частота перестаёт расти, а задержка увеличивается, система может упираться в ограничение. Но сам по себе этот сигнал не объясняет, где именно узкое место: в приложении, базе данных, прокси, сети или внешнем API.
Пятая метрика — доля запросов с ошибками. В k6 для этого используется http_req_failed. Она показывает долю запросов, завершившихся неуспешно. Это не метрика задержки, а соседний показатель, без которого результат нагрузочного теста легко истолковать неправильно.
Например, сервис может отвечать быстро, потому что значительная часть запросов сразу завершается ошибкой. График времени ответа при этом не спасает отчёт. Возможна и обратная картина: запросы формально успешны, но часть из них выполняется слишком долго и провоцирует таймауты на стороне потребителя. Поэтому тестирование производительности API следует читать по трём направлениям: задержка, пропускная способность и ошибки.
В k6 для длительности HTTP-запроса предназначена http_req_duration. В её сводных значениях доступны, среди прочего, p50, p90, p95 и p99. Совместный просмотр этих данных с http_reqs и http_req_failed даёт рабочую картину: сколько запросов обработано, как распределено время ответа и какая часть потока завершилась ошибкой.
Здесь легко устроить антипаттерн: выбрать один красивый показатель, прогнать тест с удобным сценарием и объявить интеграцию готовой. Такой подход особенно бодро ломается после деплоя, когда реальные клиенты отправляют смесь запросов, а внешние зависимости не обязаны вести себя как заглушки в тестовом стенде.
Что именно измеряет график: API целиком или его часть
У задержки есть границы измерения. Полный ответ API может включать сеть, обработку на API-прокси, передачу запроса целевому серверу и формирование ответа. Метрика, измеренная только на стороне прокси или только на целевом сервере, описывает более узкий участок. Сравнивать эти значения напрямую без оговорки — всё равно что сопоставлять время поездки целиком со временем, проведённым в лифте.
В аналитике Apigee общая Response Time включает время целевого сервера и накладные расходы API-прокси. Target Response Time показывает время ответа целевого сервера. Отдельно доступны задержки обработки запроса и ответа на стороне прокси. Такой разбор помогает разделить общую задержку на составляющие и определить, где искать проблему.
Допустим, полное время ответа выросло, а время целевого сервера осталось примерно прежним. Тогда стоит разбирать прокси и связанные с ним этапы, а не сразу отправлять разработчиков переписывать бэкенд. Если растёт время целевого сервера, фокус смещается к приложению или его зависимостям. Это ещё не готовый диагноз, но уже способ не лечить не ту часть системы.
Для наблюдаемости входящих HTTP-запросов OpenTelemetry приводит http.server.duration как пример гистограммы с единицей измерения в миллисекундах. Гистограмма хранит распределение значений и подходит для расчёта статистических показателей, включая перцентили. Важно сохранить понятную границу измерения: какой именно запрос попадает в метрику, где начинается отсчёт и где заканчивается.
Название метрики само по себе ничего не гарантирует. Два дашборда с подписью «API latency» могут показывать разные этапы запроса. Если один считает путь от клиента до полного ответа, а второй измеряет только обработку на сервере, расхождение ожидаемо. Это не обязательно ошибка инструмента; часто это следствие того, что команды выбрали разные точки наблюдения и не договорились об их смысле.
В интеграциях с несколькими сервисами полезно сопоставлять клиентское измерение и серверные метрики. Клиент видит полный путь запроса, сервер — свою часть работы. Разница между ними может включать сеть, прокси и другие промежуточные этапы. Она не обязана точно указывать на конкретный компонент, зато помогает сузить область диагностики.
Как задать цель, а не охотиться за красивой цифрой
Целевые значения задержки должны вытекать из эксплуатационных требований. Сначала определяют, какой сценарий критичен и сколько времени он может занимать в контексте всей операции. Затем выбирают перцентиль, который описывает нужный уровень обслуживания, и фиксируют допустимую долю ошибок. Порог без связи с реальным сценарием — декоративная линия на графике.
В документации k6 примером SLO служит ограничение p95 менее 500 мс. Это иллюстрация того, как можно задать бюджет, а не общий стандарт для API. Для другого сервиса такое значение может оказаться слишком мягким или чрезмерно строгим. Переносить его в продакшен без привязки к требованиям — типичный случай, когда число выглядит солиднее, чем решение за ним.
Рабочая цель должна учитывать конкретную нагрузку. Один и тот же API может вести себя по-разному при одиночных запросах, длительном потоке и коротком всплеске. Поэтому сценарий теста должен соответствовать вопросу, на который команда хочет получить ответ: выдерживает ли сервис ожидаемый поток, что происходит при его увеличении, где ухудшается p95 и когда начинает расти доля ошибок.
Перед тестом полезно зафиксировать несколько условий:
- какие операции входят в сценарий и насколько они похожи на рабочий поток;
- какая точка измерения используется: клиентская, прокси или целевой сервер;
- какой перцентиль считается целевым и для какой нагрузки;
- какой уровень ошибок допустим при прохождении теста;
- достаточно ли запросов для осмысленной оценки хвоста распределения.
Это не бюрократический ритуал. Без таких условий сравнение двух прогонов становится упражнением в чтении графиков по настроению. Изменился сценарий, точка измерения или длительность нагрузки — изменился и смысл результата.
Пороговые значения стоит использовать как часть автоматизированной проверки, а не как украшение отчёта. В k6 можно задать пороги, исходя из эксплуатационных целей, например бюджет p95 и ограничение доли ошибок. Тогда тест оценивает заранее определённое условие, а не только печатает набор цифр, который каждый участник релиза трактует по-своему.
При этом контроль порога не отменяет анализа тренда. Если p95 формально укладывается в бюджет, но ухудшается от прогона к прогону при сопоставимой нагрузке, это повод разобраться до того, как запас исчезнет. Обратная ситуация тоже возможна: единичный выброс портит p99 на маленькой выборке, хотя повторные прогоны не подтверждают системную деградацию. Метрику нужно читать вместе с объёмом данных и условиями теста.
Для оценки API-интеграции минимальный набор получается практичным: p50 описывает середину, p95 и p99 подсвечивают хвост, частота запросов показывает пропускную способность, доля ошибок — надёжность обработки. Сравнивать эти метрики между версиями имеет смысл только при сопоставимых сценариях и одинаковых границах измерения.
Хорошая интеграция не обязана впечатлять одним рекордом задержки. Она должна предсказуемо укладываться в эксплуатационный бюджет под нужной нагрузкой и не обменивать скорость на ошибки. Если в отчёте есть только среднее время ответа, данных для уверенного решения недостаточно. Остальное уже вопрос дисциплины: договориться о цели, корректно измерить и не выдавать график за диагноз.