Як прискорити API у 5 разів змінивши формат даних (і чому це спірне рішення)
Один з API-ендпоінтів, який віддавав історію транзакцій обсягом 15 000+ записів, працював вкрай повільно — середній час відповіді становив 847 мс. Спроби оптимізувати базу даних майже не дали результату: SQL-запит виконувався приблизно за 94 мс, тобто вузьке місце було не в БД.
У чому була проблема
Профайлінг показав несподіваний результат: близько 722 мс витрачалося на серіалізацію даних у JSON і передачу payload мережею.
Прийняте рішення
Замість JSON було використано MessagePack — бінарний формат серіалізації, який підтримує ті самі структури даних, але зберігає їх у компактнішому та ефективнішому вигляді.
Результати (15 000 записів)
- ⏱ Час відповіді: 847 мс → 159 мс (прискорення у 5.3×)
- 📦 Розмір payload: 4.2 MB → 1.1 MB (—74%)
- 🧠 Парсинг на клієнті: 194 мс → 41 мс
Уся зміна обійшлася приблизно в 47 рядків коду — правки на бекенді (Python) і фронтенді (JavaScript).
Обмеження та нюанси
- Відповіді у MessagePack нечитабельні для людини — у браузері це виглядає як бінарні дані, а не JSON
- Для маленьких відповідей виграш мінімальний або відсутній
Але найцікавіше було у коментарях
Автор зазначив, що пагінація не використовувалася, оскільки її заборонив продакт. У відповідь коментатори справедливо зауважили: проблема була не в JSON як такому.
JSON є де-факто стандартом для API і чудово працює у звичайних request—response сценаріях. Але в цьому випадку ендпоінт фактично перетворився на bulk-експорт даних. Перехід на MessagePack просто зменшив payload і приховав архітектурну проблему.
Висновок
Система могла залишитися на JSON, якби дизайн був іншим:
- пагінація
- стрімінг (chunked responses)
🌎 Оригінал: medium.com
Якщо вам цікаво читати шортси англомовних статей українською, то ви можете більше для себе знайти у моєму блозі crynet.dev
7 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарівНа подкасті ми обговорювали кейс як 72 години шукали 5 секунд. І проблема виявилася як раз реалізації обробки JSON. Може він і не до чого — це інструмент, зрозуміло, завжди людський фактор, адже і ліби і функції пише людина (чи AI :) ) youtu.be/TqYQP6N9QW0
О, цікавий випадок
Якщо в транзакціях є дата і час, це може бути вузьким місцем.
1. Average bandwidth в США 200 Mbps
2. Response body JSON — 5 МБ
3. Тоді очікувана затримка «чисто» на передачу 5MB/200Mbps=5/200*0.1~0.25 секунди
Відповідно я не зовсім певен на рахунок впливу «серіалізація, парсинг» тощо.
Стиснути відповідь можна і гзіпом на стороні веб-сервера, підозрюю буде ще менше рядків коду, якщо вони когось в час ші цікавоять
В статті сказано, що стиснення було. Лише для тестів його вимкнули
А чому не більш поширені протобафи?
Мб щоб не перероблювати багато? А тут, по суті, просто лібу заінсталили і все