# Отчет по нагрузочному тестированию k6

Дата отчета: 2026-05-28

## Объект тестирования

- Стенд: `https://universe.zetcraft.ru`
- Скрипт: [`frontend/scripts/loadtest-endpoints.js`](../frontend/scripts/loadtest-endpoints.js)
- Endpoint'ы:
  - `GET /api/v1/courses`
  - `GET /api/v1/lectures`
  - `GET /api/v1/users/me/stats`

## Профиль нагрузки

Тест запускался в 3 параллельных сценариях:

- `courses_list`
- `lectures_list`
- `user_stats`

Для каждого сценария использовалось `30 VU`, итого максимум `90 VU`.
Длительность активной нагрузки каждого сценария: `15s`.
С учетом `gracefulStop` максимальная длительность выполнения составила `45s`.

## Оборудование и сеть

Тест запускался с машины со следующей конфигурацией:

- CPU: AMD Ryzen 7 8845HS, `10` потоков использовалось для нагрузки.
- RAM: DDR5 5600, `10 GB` доступно.
- Накопитель: NVMe SSD.
- Сеть: `1 Gbit/s`.

## Критерии прохождения

- `checks: rate > 0.95`
- `http_req_duration: p(95) < 1500ms`
- `http_req_failed: rate < 0.01`

## Прогон 1: без паузы между итерациями

Команда запуска:

```bash
BASE_URL="https://universe.zetcraft.ru" VUS=30 DURATION="15s" PAUSE_SECONDS=0 k6 run ./frontend/scripts/loadtest-endpoints.js
```

### Итоги

| Метрика | Значение |
| --- | ---: |
| Статус threshold'ов | пройдено |
| Успешность checks | 100.00% |
| Ошибки HTTP | 0.00% |
| Всего HTTP-запросов | 3508 |
| RPS | 77.95 req/s |
| `http_req_duration` avg | 769.41ms |
| `http_req_duration` med | 38.67ms |
| `http_req_duration` p(90) | 66.61ms |
| `http_req_duration` p(95) | 93.63ms |
| `http_req_duration` max | 36.14s |
| Всего итераций | 3508 |
| Прерванные итерации | 19 |
| Получено данных | 47 MB |
| Отправлено данных | 2.1 MB |

Проверки:

- `status is 200`: успешно.
- `body is not empty`: успешно.

## Прогон 2: пауза 1 секунда между итерациями

Команда запуска:

```bash
BASE_URL="https://universe.zetcraft.ru" VUS=30 DURATION="15s" PAUSE_SECONDS=1 k6 run ./frontend/scripts/loadtest-endpoints.js
```

### Итоги

| Метрика | Значение |
| --- | ---: |
| Статус threshold'ов | пройдено |
| Успешность checks | 100.00% |
| Ошибки HTTP | 0.00% |
| Всего HTTP-запросов | 895 |
| RPS | 19.89 req/s |
| `http_req_duration` avg | 336.11ms |
| `http_req_duration` med | 11.77ms |
| `http_req_duration` p(90) | 32.01ms |
| `http_req_duration` p(95) | 42.19ms |
| `http_req_duration` max | 35.9s |
| Всего итераций | 895 |
| Прерванные итерации | 43 |
| Получено данных | 12 MB |
| Отправлено данных | 675 kB |

Проверки:

- `status is 200`: успешно.
- `body is not empty`: успешно.

## Сравнение прогонов

| Параметр | Без паузы | Пауза 1s |
| --- | ---: | ---: |
| HTTP-запросов | 3508 | 895 |
| RPS | 77.95 req/s | 19.89 req/s |
| Ошибки HTTP | 0.00% | 0.00% |
| Checks | 100.00% | 100.00% |
| p(95) | 93.63ms | 42.19ms |
| Максимальная задержка | 36.14s | 35.9s |

## Вывод

Оба прогона успешно прошли заданные threshold'ы: ошибок HTTP не зафиксировано, все проверки ответов успешны, `p(95)` существенно ниже порога `1500ms`.

При запуске без паузы стенд обработал около `77.95 req/s`, при паузе `1s` - около `19.89 req/s`. Во всех прогонах наблюдались единичные длинные запросы до `35-36s`, при этом они не повлияли на прохождение p95-порога. Это стоит учитывать при дальнейшем анализе хвостовых задержек.
