Як налаштувати HTTP-кешування API: ETag, Last-Modified, Vary

Сплески навантаження та повільні відповіді API б'ють по конверсії та утриманню клієнтів. Ми налаштовуємо HTTP-кешування під ключ: розбираємо причини відмов, проєктуємо режими та впроваджуємо так, щоб повторні запити віддавалися миттєво. У результаті час відповіді скорочується в рази, а інфраструктура перестає зростати разом із трафіком.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Як налаштувати HTTP-кешування API: ETag, Last-Modified, Vary
Середній
від 1 дня до 3 днів
Часті запитання

HTTP-кешування API: де ламається і що втрачає замовник

HTTP-кешування — це шар, який стоїть між клієнтом і бекендом і вирішує, чи можна віддати вже готову відповідь, не піднімаючи застосунок.

Коли його немає, кожен запит мобільного клієнта, кожне перемальовування інтерфейсу і кожен повторний виклик з інтеграції йдуть у базу й перераховують один і той самий результат.

На середньому API це перетворюється на зростання затримок API: час відповіді зростає не лінійно, а ступенями, бо черга запитів починає чекати на звільнення з'єднань з базою.

Далі вмикається ефект доміно. Навантаження на бекенд зростає разом із кількістю клієнтів, а не разом з обсягом реально нових даних — типова картина, коли 80% трафіку припадає на ті самі довідники, каталоги та списки.

За пікового навантаження запас за ресурсами закінчується раніше, ніж надходить основний трафік, і починаються відмови під час піків: спочатку поодинокі таймаути, потім масові помилки на найбільш «гарячих» ендпоінтах, які якраз і викликаються найчастіше.

Кешування API знімає це навантаження на рівні протоколу, а не за рахунок додавання серверів.

Заголовки ETag і Last-Modified дозволяють клієнту запитати «чи змінилося» і отримати коротку відповідь замість повного тіла, Vary розводить кеш за потрібними ознаками запиту, а коректні директиви свіжості визначають, скільки відповідь живе без звернення до застосунку. У результаті повторні запити закриваються на межі, а бекенд займається лише новими даними.

Розбираємо, де саме ламається HTTP-кешування в реальних API і як налаштувати його так, щоб затримки та відмови перестали бути вузьким місцем.

Що дає кероване кешування: вимірювані ефекти

HTTP-кешування перестає бути «налаштуванням на око», коли кожна відповідь має валідатор: ETag або Last-Modified.

Клієнт надсилає If-None-Match / If-Modified-Since, сервер відповідає 304 Not Modified без тіла — час відповіді API на повторних запитах падає в рази, бо мережею їде лише заголовок, а не корисне навантаження.

Бекенд при цьому не перезбирає відповідь: розвантаження йде не за рахунок кешу на боці клієнта, а за рахунок того, що важка логіка взагалі не запускається.

Заголовок Vary вирішує другу половину задачі — коректний поділ кешу за Accept-Encoding, Authorization та мовою. Без нього проксі віддає одному клієнту відповідь, зібрану для іншого: чужі права, неправильну локаль, стиснення не під той формат.

Це і є окремий клас відмов — не падіння сервісу, а тиха видача неправильних даних, яку ловлять уже в проді. Кероване кешування прибирає його на рівні контракту, а не латками в коді.

Стабільність під навантаженням — наслідок. Коли частка повторних запитів, закритих валідацією, зростає, пікове навантаження на бекенд перестає масштабуватися разом із кількістю клієнтів: ті самі сервери тримають більше трафіку, а час відповіді залишається передбачуваним. Розбираємо, як це налаштовується на практиці — від вибору валідатора до політики для проксі та CDN.

Підходи до кешування: порівняння режимів і обмежень

Кешування — це не «увімкнути й забути», а вибір режиму під профіль трафіку. Нижче — реальні альтернативи, між якими доводиться обирати під час проєктування API, з їхньою застосовністю та обмеженнями. Окремо варто дивитися на те, хто керує політикою: застосунок, зворотний проксі чи клієнт.

Варіант Коли підходить Обмеження
Без кешування Персональні дані, платіжні операції, відповіді, що залежать від прав користувача Кожен запит іде до джерела, зростає навантаження й затримка
Cache-Control: no-store Чутливі відповіді, які не можна залишати на диску Не дає виграшу за швидкістю, лише захищає дані
max-age + public Публічні довідники, каталоги, контент, що рідко змінюється Застарівання даних у межах TTL, потрібне скидання під час оновлення
ETag + If-None-Match Ресурси, які змінюються нечасто, але мають бути свіжими Зайвий round-trip на перевірку, відповідь 304 замість тіла
Last-Modified + If-Modified-Since Файли, статика, документи з датою зміни Точність до секунди, хибні спрацювання під час перезбереження
Vary за заголовками Контент залежить від мови, авторизації, типу пристрою Дробить кеш на багато варіантів, зростає обсяг сховища
Керовані політики на проксі Єдині правила для десятків сервісів Вимагають узгодження із застосунком, інакше конфлікт заголовків

Комбінувати режими доводиться майже завжди: ETag для динаміки, max-age для статики, Vary там, де відповідь залежить від контексту запиту. Ключовий ризик — неузгодженість заголовків між застосунком і проксі: клієнт отримує застарілу відповідь або, навпаки, кеш не працює взагалі.

Вибір підходу фіксується в керованих політиках на рівні шлюзу, а не в коді кожного сервісу. Так правила залишаються передбачуваними, а обмеження кешування видно до релізу, а не після інциденту.

Як ми впроваджуємо кешування: етапи інженерної роботи

Кешування API — це не «увімкнути плагін», а послідовність рішень: де стоїть кеш, за яким ключем він розрізняє відповіді та в який момент дані вважаються застарілими. Нижче — як ми ведемо таку роботу, щоб після запуску поведінка була передбачуваною, а не «наче працює».

  1. Аудит заголовків. Знімаємо реальні відповіді API і дивимося, що віддає сервер зараз: чи є Cache-Control з осмисленим max-age, чи проставляється ETag або Last-Modified, чи не губиться Vary на заголовках авторизації та мови. Часто з'ясовується, що частина відповідей кешується там, де не повинна, а частина — навпаки, не кешується взагалі.
  2. Проєктування політик. Для кожного типу ресурсу визначаємо режим: публічні довідники — довгий max-age зі stale-while-revalidate, персональні дані — private без спільного кешу, змінювані сутності — валідація через ETag і відповідь 304. Окремо фіксуємо ключ кешу та набір полів у Vary.
  3. Налаштування кешу. Прописуємо заголовки на рівні застосунку та проміжного шару, синхронізуємо їх між собою, щоб проксі не переписував політику застосунку. Налаштовуємо коректну роботу з умовними запитами If-None-Match і If-Modified-Since.
  4. Перевірка інвалідації. Проганяємо сценарії зміни даних: оновлення запису, зміна прав доступу, публікація нової версії. Переконуємося, що після запису клієнт і проміжний кеш отримують свіжі дані, а не віддають застарілі.
  5. Навантажувальна перевірка. Дивимося частку відповідей 304 і влучань у кеш, час відгуку до і після. Мета — зростання частки валідованих відповідей і зниження навантаження на джерело.
  6. Передача документації. Віддаємо карту політик за ендпоінтами, правила інвалідації та інструкцію для розробників: які заголовки змінювати можна, а які зламають кеш.
  7. Супровід. Після запуску відстежуємо метрики влучань і коригуємо max-age там, де дані змінюються частіше, ніж передбачалося.

Опишіть вашу задачу — повернемося з оцінкою та планом робіт.

Що замовник отримує на руки: конфігурації та регламенти

Робота з HTTP-кешуванням закінчується не «увімкнули заголовки й забули», а набором артефактів, які залишаються в репозиторії та живуть довше за підрядника. Кожен пункт нижче — те, що можна відкрити, перевірити й передати новому інженеру без усних пояснень.

  • Конфігурації кешу — робочі файли для зворотного проксі та застосунку: правила щодо Cache-Control (max-age, s-maxage, stale-while-revalidate), генерація ETag і Last-Modified, налаштування Vary під Accept-Encoding та авторизацію. З коментарями, чому обрано саме такий набір директив для кожного типу відповіді.
  • Схеми потоків — діаграми шляху запиту: клієнт → CDN → зворотний проксі → застосунок → сховище. На схемі позначено, на якому шарі кешується відповідь, де відбувається ревалідація і який шар відповідає за інвалідацію.
  • Політики інвалідації — регламент скидання: за тегами ресурсів, за префіксами URL, за подією зміни даних. Із зазначенням, що чиститься примусово, а що живе до спливу max-age, і як це співвідноситься з бізнес-логікою.
  • Документація API — опис ендпоінтів із зазначенням кешованості: які відповіді публічні, які приватні, де обов'язкова авторизація і чому така відповідь не повинна потрапляти до спільного кешу.
  • Регламенти перевірки — чек-ліст приймання: контроль заголовків відповіді, поведінка при 304 Not Modified, коректність Vary за різних Accept-Encoding, відсутність витоку приватних даних через спільний кеш.
  • Моніторинг і алерти — метрики частки влучань у кеш, часу відповіді на промаху та ревалідації. Пороги, за яких інженер отримує повідомлення, а не дізнається про проблему від користувачів.
  • Інструкція з відкату — порядок дій, якщо нова політика кешування ламає видачу: як швидко скинути кеш на всіх шарах і повернути попередню конфігурацію.

Пакет самодостатній: за ним можна провести аудит поточного кешування, відтворити налаштування в новому середовищі та передати супровід іншій команді. Опишіть задачу — повернемося з оцінкою та планом робіт.

Кейс: як кероване кешування прибрало сплески відмов

Проєкт — маркетплейс із каталогом на кілька сотень тисяч позицій і мобільним застосунком, який ходив в API за кожним екраном. Кеш-заголовків бекенд не віддавав: Cache-Control не виставлявся, ETag не рахувався, відповіді йшли з no-store за замовчуванням. Кожен запуск застосунку і кожен перехід по каталогу били в базу напряму.

Що було до впровадження

На піках — ранковий трафік і розпродажі — час відповіді каталогу сягав понад секунду, частка відповідей із помилкою сервера трималася в районі кількох відсотків, а база впиралася в стелю з'єднань.

Відмови йшли хвилями: перевантаження викликало таймаути, клієнти повторювали запити, і навантаження подвоювалося на рівному місці. Чергова зміна гасила це ручним розширенням пулу і перезапусками.

Що змінили

Налаштували кероване кешування на рівні API-шлюзу і застосунку. Для довідників і карток товарів увімкнули ETag і Last-Modified — повторний запит без змін повертає 304 Not Modified і не доходить до бекенду.

Для списків, що залежать від фільтрів, ролей і мови, прописали Vary за потрібними заголовками, щоб не віддавати чужу версію відповіді.

Публічні дані отримали Cache-Control з роздільними директивами max-age і stale-while-revalidate: клієнт віддає застарілу копію, поки фоном підтягується свіжа. Інвалідацію прив'язали до подій зміни товару, а не до таймера.

Що стало

Частка відповідей 304 на повторних запитах каталогу перевищила половину — ці звернення перестали доходити до бази. Час відповіді на піках скоротився в рази, частка помилок сервера впала до часток відсотка, а навантаження на бекенд у години пік знизилося приблизно вдвічі. Хвилеподібні відмови припинилися: система тримає трафік розпродажу без ручного втручання чергового.

Практика впровадження показала головне: виграш дає не сам заголовок, а узгоджена політика — що кешується, на який термін, за якими ознаками розрізняється і коли скидається.

Такий підхід ми застосовуємо і в інших проєктах на FastAPI і подібних стеках, де важлива передбачуваність під навантаженням.

Чим відрізняється ETag від Last-Modified і коли потрібен Vary?

ETag і Last-Modified вирішують одне завдання — дати клієнту дешевий спосіб перевірити, чи змінився ресурс, не передаючи його тіло повністю.

Last-Modified спирається на час останньої правки і працює з точністю до секунди: якщо дві зміни вклалися в одну секунду або файл перезаписано тим самим вмістом, мітка бреше.

ETag — це відбиток конкретної версії представлення, тому він ловить зміни, яких час не бачить, і коректно працює при віддачі з CDN та при збиранні відповіді з кількох джерел.

На практиці їх не протиставляють, а ставлять разом: ETag дає точну перевірку, Last-Modified залишається запасним валідатором для посередників, які не вміють працювати з відбитком.

Клієнт надсилає умовний запит з If-None-Match і If-Modified-Since, сервер порівнює і повертає або тіло, або коротку відповідь «не змінилося» — економія трафіку й часу відповіді на порядок, а не на відсотки.

Слабкий ETag відрізняється від сильного: перший підтверджує смислову еквівалентність, другий — побайтову. Для JSON API майже завжди достатньо слабкого, для статики й файлів віддачі — сильного.

Помилка новачка — генерувати ETag від часу старту процесу: після перезапуску або переїзду на інший вузол мітка змінюється, і весь кеш клієнтів інвалідується разом.

Vary відповідає на інше питання — не «та сама це версія», а «той самий це клієнт».

Якщо відповідь залежить від заголовка Accept, Accept-Encoding, Accept-Language або авторизації, без Vary проміжний кеш віддасть чужу версію: стиснуту відповідь — клієнту без підтримки стиснення, англійську — тому, хто просив російську.

Vary: Accept-Encoding і Vary: Accept-Language закривають це, але кожен доданий заголовок дробить кеш на більшу кількість варіантів, тому перелічувати потрібно лише те, що реально впливає на тіло відповіді.

Окремо варто Vary: Authorization і приватні відповіді: їх або позначають Cache-Control: private, або забороняють кешування взагалі, інакше персональні дані осідають у спільному кеші.

Перевіряти зв'язку зручно за журналом: частка відповідей «не змінилося» на умовні запити показує, чи працює валідація, а частка влучань у кеш за кожним варіантом Vary — чи не розростається сховище.

Часті технічні сумніви при налаштуванні кешування

Кеш найчастіше вже розгорнуто — на CDN, reverse-proxy або в самому застосунку, і питання не «вмикати чи ні», а «як не зламати те, що працює». Починаємо з інвентаризації: які маршрути кешуються, за якими ключами, хто виставляє заголовки — проксі чи бекенд.

Далі змінюємо точково: спочатку відповіді без персоналізації, потім усе інше, з перевіркою на кожному кроці.

Авторизація та кеш конфліктують там, де відповідь залежить від користувача, а ключ кешу — лише від URL. Рішення — або явний Cache-Control: private для таких маршрутів, або Vary: Authorization, або розділення на публічний і приватний контури.

Ми не покладаємося на «за замовчуванням не закешується»: перевіряємо кожен маршрут, де у відповіді є дані користувача.

Перевірка інвалідації — окремий етап, а не формальність. Дивимося, що відбувається при оновленні ресурсу: чи змінюється ETag, чи приходить 304 на умовний запит, чи йде стара відповідь з проксі після PURGE. Якщо інвалідація не спрацьовує, клієнт отримує застарілі дані й не розуміє чому.

У нас уже розгорнуто кеш — доведеться все перебудовувати?

Ні. Спочатку фіксуємо поточну поведінку: які заголовки віддає бекенд, що перезаписує проксі, де розходяться ключі. Перебудова потрібна лише там, де правила конфліктують — зазвичай це 2-3 маршрути з десятків.

Як не зламати авторизацію при вмиканні кешу?

Розділяємо контури: публічні відповіді кешуються за URL, приватні — позначаються private або отримують Vary: Authorization. Після вмикання прогоняємо сценарії з різними ролями й перевіряємо, що користувач не отримує чужу відповідь.

Як переконатися, що інвалідація працює?

Перевіряємо ланцюжок: оновили ресурс — чи змінився ETag або Last-Modified, чи повернув сервер 304 на умовний запит, чи пішла стара відповідь з проксі. Якщо хоча б один крок не спрацьовує, кеш віддає застаріле.

Ці сумніви виринають майже на кожному проєкті — і майже завжди вирішуються точковим налаштуванням, а не переписуванням. Опишіть вашу конфігурацію — повернемося з оцінкою та планом перевірки.

Обговоримо ваше завдання щодо кешування API

Щоб повернутися з оцінкою та планом впровадження, нам потрібен контекст щодо вашого API: де саме кешування не працює або працює не так, як очікується. Опишіть завдання у вільній формі — цього достатньо, щоб наш інженер зрозумів картину та запропонував реалістичний план.

Що корисно додати до опису:

  • поточні заголовки відповідей API — Cache-Control, ETag, Last-Modified, Vary: видно, що вже віддається клієнтам і де логіка розсипається;
  • архітектуру: моноліт чи кілька сервісів, чи є CDN або зворотний проксі перед застосунком;
  • які методи та ендпоінти кешуються, а які мають залишатися строго свіжими (платежі, баланси, статуси замовлень);
  • як влаштована авторизація — токени в заголовку, cookie, сесії: від цього залежить коректне налаштування Vary та приватності кешу;
  • скарги від користувачів або метрики: застарілі дані, зайві запити, зростання навантаження на базу;
  • обмеження: регламенти, вимоги до безпеки, строки, які не можна зсувати.

За цими ввідними ми повернемося з оцінкою робіт і планом впровадження: які заголовки та правила виставляємо, як налаштовуємо розділення публічного та приватного кешу, як перевіряємо коректність через умовні запити та відкат.

Якщо під час розбору з'являться розвилки — обговоримо їх з вашим інженером, щоб рішення лягло в наявну інфраструктуру, а не потребувало її перебудови.

Опишіть завдання — повернемося з оцінкою та планом.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1140
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060