304 Not Modified: чому це успіх, а не помилка
304 Not Modified - це успіх: він означає, що ваша кешована копія ресурсу досі актуальна, тож сервер не надсилає тіло і каже повторно використати те, що у вас уже є. Він з'являється лише у відповідь на умовний запит, тому перевірка моніторингу, яка не надсилає заголовків кешування, ніколи його не побачить.
Як виникає 304
304 - це друга половина розмови у два кроки. На перший запит сервер повертає ресурс із валідатором: ETag, який є непрозорим ідентифікатором саме цієї версії, і часто датою Last-Modified. Клієнт зберігає відповідь разом із цими валідаторами.
Пізніше, коли кешовану копію потрібно перевалідувати, клієнт повторює запит і додає те, що вже має:
If-None-Match: "abc123"передає збережений ETag. Це переважний валідатор, бо він точний.If-Modified-Since: Wed, 03 Sep 2026 10:00:00 GMTпередає збережену дату, застосовується, коли ETag немає.
Якщо ресурс не змінився, сервер відповідає 304 Not Modified лише із заголовками, без тіла, і клієнт відображає свою кешовану копію. Якщо змінився, сервер відповідає 200 з новим вмістом і новими валідаторами. Обидва результати - правильна поведінка.
Чому 304 - це добра новина, а не помилка
Люди бачать 304 у панелі мережі браузера чи в аналізаторі логів, помічають, що це не 200, і думають, що щось не спрацювало. Насправді все гаразд. 304 - найдешевша корисна відповідь у вебі: тіло відповіді не передається мережею, тож трансфер займає кілька сотень байтів замість повного файлу, а сервер зазвичай не витрачається на повторну генерацію ресурсу, тому 304 обходиться дешевше за процесор, ніж 200. Сторінка рендериться швидше, бо браузер повторно використовує байти, які вже має. Виграють і краулери, адже стабільний ETag, що дає 304, дозволяє пошуковику витрачати краул-бюджет на сторінки, які справді змінилися.
Висока частка 304 на статичних файлах - ознака того, що кешування налаштовано добре. Варто лише подумати, чи потрібен вам взагалі раунд-тріп перевалідації: для версійних чи фінгерпринтованих файлів довгий Cache-Control: max-age з immutable дозволяє уникнути навіть 304, бо браузер узагалі не питає сервер.
Коли 304 - проблема
- Застаріла сторінка, яка не оновлюється. Якщо ваш HTML віддається з валідатором, який ніколи не змінюється, поки змінюється вміст, браузери продовжують отримувати 304, а користувачі - бачити стару сторінку. Це класичний баг "я задеплоїв, але ніхто цього не бачить".
- 304 без відповідної кешованої копії. Якщо клієнт надсилає умовний запит, на який не мав підстав, або проксі вирізає тіло з відповіді 200, клієнту нема що рендерити, і сторінка виглядає порожньою.
- Слабкі або нестабільні ETag за балансувальником навантаження. Коли кілька бекендів генерують різні ETag для однакового вмісту, кожна перевалідація дає промах, і замість очікуваних 304 ви отримуєте повні 200. Трафік зростає без причини.
- Стиснення, що змінює валідатор. Якщо ETag відрізняється для стиснутого і нестиснутого варіанта без коректного
Vary: Accept-Encoding, кеші можуть віддати не те, що треба.
Як тестувати умовні запити
- Отримайте ресурс і прочитайте його валідатори:
curl -sI https://example.com/style.css | grep -Ei "^(HTTP|etag|last-modified|cache-control)" - Повторіть запит із отриманим ETag і переконайтеся, що сервер відповідає 304:
Підставте точне значення ETag, включно з лапками. 200 тут означає, що перевалідація не працює.curl -sI -H 'If-None-Match: "abc123"' https://example.com/style.css | head -n 1 - Якщо ви отримуєте 200 там, де очікували 304, перевірте, чи не вирізає проксі або CDN заголовок
If-None-Match, і чи узгоджені ваші бекенди щодо ETag для одного й того самого файлу. - Якщо ви отримуєте застарілу сторінку, зробіть так, щоб валідатор змінювався разом зі вмістом. Фінгерпринтовані назви файлів - найнадійніше рішення; інакше виводьте ETag із самого вмісту.
- Тримайте для HTML короткий термін свіжості, а файлам залишайте довгий. HTML, закешований на добу, - це те, через що деплой стає непомітним.
Чому перевірки аптайму ніколи не бачать 304
Перевірка аптайму запитує сторінку так, ніби це перший візит, без If-None-Match і без If-Modified-Since, тож серверу немає з чим порівнювати, і він завжди відповідає 200. Це правильна поведінка за замовчуванням для перевірки доступності. Але це також означає, що регресії кешування взагалі не видно в даних аптайму: сайт може віддавати всім застарілу сторінку, поки кожна перевірка залишається зеленою. Додайте перевірку вмісту сторінки поряд зі статусом, і сторінка, що перестала оновлюватися, стане видимою як розбіжність вмісту. HostTracker пропонує 13 типів моніторів і моніторить сайти з 2004 року. Перевірте заголовки й статус за допомогою інструмента HTTP-перевірки, а також прочитайте, що насправді доводить 200 OK, і повний посібник про родину 3xx.