Зміст
Коротко
Застосунок для конвертації й шарингу файлів спочатку робив всю роботу всередині HTTP-запиту. Зі зростанням розмірів файлів користувачі чекали сотні мілісекунд там, де відповідь могла прийти одразу. Автор виніс важку обробку в BullMQ і Redis — і отримав вимірюваний виграш за затримкою й пропускною здатністю.
Що сталося
Перша версія була простою: завантаження → конвертація в тому ж процесі, що обробляє API → відповідь із результатом. На маленьких файлах це працювало. Коли обсяги зросли, з'єднання трималося відкритим, поки сервер зайнятий CPU й диском — хоча клієнту в цей момент потрібен був лише факт «прийнято в роботу».
Новий потік: завантаження → задача в BullMQ → миттєва відповідь API → воркер конвертує → оновлення статусу → користувач отримує файл. Redis зберігає чергу; воркери масштабуються за паралелізмом; повтори й обробка збоїв вбудовані в модель черги.
Автор прогнав навантажувальний тест із 20 паралельними запитами. p95 затримки API впав приблизно в 212 разів (з 800 мс до 3,8 мс). Пропускна здатність зросла в 4,8 раза (з 1,3 до 6,2 запитів на секунду). Прискорилася не сама конвертація — змінилася архітектура: важка робота пішла з критичного шляху запиту.
Чому це важливо
Синхронна обробка в API здається простішою, поки навантаження низьке. Але будь-який довгий I/O або CPU в обробнику запиту б'є по таймаутах, пулі з'єднань і UX. Патерн «прийняти швидко, обробити окремо» — базовий для файлів, відео, звітів, розсилок.
Ціна асинхронності чесна: потрібні Redis, процеси-воркери, моніторинг черги й відкладена узгодженість — користувач не отримує файл у тій самій відповіді, що завантаження. Якщо бізнес вимагає миттєвого результату в одному HTTP-циклі, синхронний шлях може лишитися виправданим. Для конвертації й шарингу це рідко так.
На практиці
- Відокремте прийом файлу від важкої обробки — API повертає
jobIdі статус. - Оберіть чергу з повторами й чергою «мертвих» задач (BullMQ на Redis — поширений варіант у Node.js).
- Масштабуйте воркери, а не лише репліки API — задачі, що навантажують CPU, живуть там.
- Віддавайте клієнту опитування статусу, webhook або SSE для стану «готово».
- Заміряйте p95/p99 API окремо від часу повної обробки задачі.
- Задокументуйте компроміс: простіший код vs інфраструктура й затримка до результату.
Підсумок
Історія на Dev.to — коротке, але цифрами підкріплене нагадування: часто виграш дає не «прискорення функції», а винесення роботи з HTTP-запиту. BullMQ + Redis окупилися для файлового сервісу; ваш поріг може бути іншим, але принцип універсальний.