Пользователь заходит на сайт. Браузер отправляет запрос на сервер. Сервер идёт в базу данных, собирает данные, рендерит HTML, отправляет обратно. На всё это уходит 1–3 секунды. Если каждый запрос делает всё это заново — сайт будет медленным независимо от мощности сервера.

Кэширование — это сохранение результата, чтобы при следующем запросе не делать работу заново. Первый запрос: 1,5 секунды. Второй: 50 миллисекунд. Тысячный: те же 50 миллисекунд. Это и есть «ускорение в 10–30 раз».

О чём эта статья

Разбираем 5 уровней кэширования — от браузера пользователя до базы данных. Для каждого: что кэшировать, как настраивать, какие ошибки допускают. С конкретными примерами и цифрами.

1. Пять уровней кэширования

Кэш — это не одна система, а слои. Каждый следующий ловит то, что не поймал предыдущий. Настроив все пять, вы получаете максимальную скорость.

1
Кэш браузера

Статика (CSS, JS, картинки, шрифты) сохраняется в браузере пользователя. При повторных заходах загружается с диска — 0 запросов к серверу.

2
CDN-кэш

Раздаётся через сеть серверов по всему миру. Пользователь из Владивостока получает картинку с сервера во Владивостоке, а не с вашего сервера в Москве.

3
Кэш приложения

HTML-страницы, результаты сложных вычислений, ответы API сохраняются в Redis или в памяти. Не надо рендерить страницу каждый раз.

4
Кэш базы данных

Результаты частых SQL-запросов сохраняются отдельно. Или используются материализованные представления для тяжёлых агрегатов.

5
Кэш на уровне операционной системы

Файловый кэш ОС и кэш процессора — работают автоматически, ничего настраивать не нужно, но понимать полезно.

Для большинства сайтов первые три уровня дают 90% ускорения. Начните с них, потом переходите к четвёртому, если сайт сильно нагружен.

2. HTTP-кэш: самый дешёвый уровень

HTTP-кэш работает через заголовки ответа. Когда сервер отдаёт файл, он добавляет заголовки, которые говорят браузеру: «этот файл можно сохранить и не перезапрашивать вот столько времени».

Основные заголовки:

# Файл можно кэшировать на 1 год
Cache-Control: public, max-age=31536000, immutable

# Файл можно кэшировать на 1 час
Cache-Control: public, max-age=3600

# Кэш только у клиента, не в CDN
Cache-Control: private, max-age=300

# Не кэшировать (для админки, личного кабинета)
Cache-Control: no-store, must-revalidate

Правильная стратегия: «вечные» файлы получают хеш в имени: app.abc123.css. Тогда их можно кэшировать на год через immutable. Когда файл меняется — меняется и хеш, браузер скачивает новую версию.

HTML-страницы кэшируются иначе — на короткое время или с проверкой через ETag и Last-Modified. Браузер отправляет серверу «у меня есть версия с таким ETag», сервер отвечает «304 Not Modified» без тела страницы. Это экономит трафик и время.

Типичная ошибка

Кэшировать HTML-страницы без версионирования. Если страница «О компании» меняется, а браузер всё ещё показывает старую версию — пользователь думает, что вы не обновляете сайт. Для HTML используйте короткий max-age (5–15 минут) или no-cache с обязательной проверкой через ETag.

3. CDN: раздача статики по всему миру

Если ваш сервер стоит в Москве, а пользователь заходит из Новосибирска, запрос идёт через всю страну. Задержка — 100+ миллисекунд на каждый файл. Загрузить сайт с 50 файлами = 5 секунд только на задержках.

CDN решает это: файлы раздаются с ближайшего к пользователю сервера. Из Новосибирска — с сервера в Новосибирске. Из Владивостока — с сервера во Владивостоке. Задержка падает до 5–20 миллисекунд.

Что отдавать через CDN:

  • Изображения, иконки, логотипы
  • CSS и JavaScript
  • Шрифты
  • Видео и аудио
  • Статические HTML-страницы (если сайт на SSG)

Что выбрать: Cloudflare — бесплатный тариф покрывает потребности большинства сайтов. Даёт кэш, защиту от DDoS, SSL, оптимизацию картинок. Российские аналоги — Selectel CDN, Gcore. Для российского бизнеса лучше российские (152-ФЗ и скорость).

Цифры: сайт с 30 картинками весом 100 КБ каждая. Без CDN: 3 МБ трафика с одного сервера, 3–5 секунд загрузки. С CDN: те же 3 МБ, но с ближайших серверов — 0,8–1,2 секунды. Ускорение в 3–4 раза.

4. Кэш приложения: Redis и память

Здесь начинается самое интересное. HTML-страница, которую генерирует ваш код, — это результат работы десятков SQL-запросов и шаблонизатора. Если страница одна и та же для всех — зачем генерировать её заново каждый раз?

Простой пример на Python (Django):

from django.core.cache import cache

def get_article(slug):
    # Пробуем взять из кэша
    cached = cache.get(f'article:{slug}')
    if cached:
        return cached
    
    # Если нет — идём в БД
    article = Article.objects.get(slug=slug, status='published')
    
    # Сохраняем в кэш на 10 минут
    cache.set(f'article:{slug}', article, timeout=600)
    return article

Первый запрос: 250 миллисекунд (SQL + рендер). Второй и последующие: 2–5 миллисекунд (запрос к Redis).

Redis или Memcached?

  • Redis — умеет больше: списки, множества, публикация/подписка. Может работать и как кэш, и как очередь задач, и как хранилище сессий. Выбор по умолчанию в 2026.
  • Memcached — проще, легче, чуть быстрее на чистом кэше. Но больше ни для чего не подходит.

Для сайта с 100–1000 посетителей в день хватает Redis на самом слабом VPS (128 МБ памяти). Для высоконагруженного проекта — Redis-кластер или managed-решение.

Что кэшировать: результаты тяжёлых SQL-запросов, HTML-фрагменты (меню, футер, блоки «популярное»), ответы внешних API, результаты сложных вычислений. Что НЕ кэшировать: корзину, личный кабинет, всё, что зависит от конкретного пользователя.

5. Кэш базы данных

Даже с кэшем приложения часть запросов всё равно идёт в базу. Это нормально — но некоторые запросы настолько часты, что их тоже стоит кэшировать.

Три подхода:

  • Индексы. Не совсем кэш, но эффект похож. Правильный индекс превращает запрос по таблице из 100 000 строк из 500 мс в 5 мс. Это самое дешёвое ускорение — просто добавьте индекс.
  • Материализованные представления. Если у вас есть запрос «топ-10 товаров за месяц» — он выполняется каждый раз. Материализованное представление сохраняет результат, обновляется по расписанию.
  • Query cache. Некоторые СУБД (MySQL) кэшируют результаты одинаковых запросов. Устаревший механизм, в новых версиях его убрали — лучше использовать Redis.

Пример материализованного представления (PostgreSQL):

CREATE MATERIALIZED VIEW popular_products AS
SELECT 
    p.id,
    p.name,
    COUNT(o.id) AS order_count
FROM products p
JOIN orders o ON o.product_id = p.id
WHERE o.created_at > now() - interval '30 days'
GROUP BY p.id, p.name
ORDER BY order_count DESC
LIMIT 10;

-- Обновляем раз в час
REFRESH MATERIALIZED VIEW CONCURRENTLY popular_products;

Цифры: запрос «топ-10 за месяц» по таблице orders с 1 миллионом строк занимает 1,8 секунды. Из материализованного представления — 3 миллисекунды. Ускорение в 600 раз.

6. Инвалидация кэша: самая сложная часть

«В информатике есть только две сложные вещи: инвалидация кэша и придумывание имён». Фил Карлтон, 1996 год. С тех пор ничего не изменилось.

Проблема: как понять, что кэш устарел? Если вы закэшировали страницу товара, а потом поменяли цену — старый кэш продолжит показывать старую цену. Это хуже, чем медленный сайт.

Три стратегии:

  • По времени (TTL). Кэш живёт фиксированное время: 5 минут, час, сутки. Просто и понятно, но не всегда точно. Для товаров с редко меняющейся ценой — подходит. Для акции «скидка до конца дня» — плохо.
  • По событию. При изменении данных явно удаляем кэш. Например, обновили цену товара — сбросили кэш страницы этого товара. Точно, но нужно не забыть сбросить везде, где нужно.
  • По версии. Добавляем к ключу версию данных. Изменилась — ключ тоже изменился. Это самый гибкий способ, особенно для CDN-кэша.
Неправильный кэш хуже, чем его отсутствие

Если вы показываете устаревшие цены, недоступные товары или неправильные данные — пользователи перестают доверять сайту. Лучше чуть медленнее, но всегда актуально, чем быстро с устаревшими данными. Начинайте с коротких TTL и постепенно увеличивайте.

7. Что категорически нельзя кэшировать

  • Личный кабинет. Каждый пользователь должен видеть только свои данные. Если случайно закэшировать чужую страницу — утечка данных и огромные проблемы.
  • Корзину. Корзина привязана к сессии. Если два пользователя увидят одну корзину — потеряете обоих.
  • Админку. Кэширование админки — верный способ запутаться самому. Обязательно Cache-Control: no-store.
  • Формы и токены. CSRF-токены, каптчи, одноразовые ссылки должны быть уникальными для каждого запроса.
  • Страницы акций с таймером. Если у вас «до конца акции 2 часа», кэш на час покажет неправильное время.

Кэширование — самое дешёвое ускорение сайта. Не нужно покупать мощный сервер или переписывать код. Достаточно правильно расставить заголовки и настроить Redis. Сайт, который грузился 3 секунды, будет грузиться 300 миллисекунд — и конверсия вырастет на 20–30%.

Ускорим ваш сайт

Настроим кэширование на всех уровнях: HTTP, CDN, Redis, БД. Проведём замеры до и после. От 15 000 ₽.