Как OpenAI крутит PostgreSQL на 800M пользователей и миллионы QPS

Привет, %username%! Статья от OpenAI — это довольно любопытный пример того, как не городить зоопарк баз, а выжать максимум из одного PostgreSQL, понимая его сильные и слабые стороны.

Что по сути сделали OpenAI:

  • Оставили один primary PostgreSQL без шардинга, но навесили почти 50 read‑реплик по регионам, чтобы разрулить гигантский read‑трафик и держать низкие задержки.
  • Все, что можно шардинровать и что много пишет, уехало в Cosmos DB и другие шардированные системы — Postgres перестали использовать как универсальный молоток для любых нагрузок.
  • Жёстко оптимизировали запросы: убирали монструозные joins (например, на 12 таблиц), ломали ORM‑магию, разбивали тяжелую логику по слоям, настраивали таймауты и следили за long‑running / idle‑транзакциями.
  • Боролись с MVCC‑болью (bloat, dead tuples, write amplification) через снижение лишних записей, lazy writes, аккуратный backfill с rate‑limit'ами и перенос write‑heavy кейсов из PostgreSQL.
  • Защитились от "шумных соседей": развели high‑priority и low‑priority трафик по разным инстансам, чтобы новая фича с кривыми запросами не ложила критичные пути.
  • Везде, где можно, поставили PgBouncer (statement/transaction pooling), чтобы не умереть от connection storm при лимите в 5000 коннектов на инстанс.
  • Снизили риск SEV‑0 от падения primary: HA с hot‑standby, быстрый failover, максимум критичных чтений — с реплик, чтобы при проблемах с записью сервис хотя бы читал.
  • Поверх этого — rate limiting и load shedding на всех уровнях: приложение, пулер, прокси, конкретные query digests в ORM, плюс защита от retry storm'ов.
  • Сильно ограничили эволюцию схемы: только лёгкие изменения, 5‑секундный timeout на DDL, без full table rewrite; новые таблицы — уже не в этом Postgres, а в шардированных системах.

В результате — миллионы QPS, p99 в низких десятках миллисекунд и около пяти девяток доступности, при этом за год только один SEV‑0 инцидент на Postgres, и тот во время дикого роста (ImageGen, +100M новых юзеров за неделю).

Что можно утащить к себе

  • Не пытаться "передумать" базу: принять ограничения PostgreSQL (один writer, MVCC, bloat) и строить архитектуру вокруг этого, а не против этого.
  • Относиться к read‑репликам как к основному инструменту масштабирования, а к primary — как к самому дорогому и охраняемому ресурсу.
  • Ввести жёсткие правила для схемы и DDL: никакого "ALTER в прайм‑тайм прямо в прод", только безопасные паттерны миграций, троттлинг backfill’ов и чёткие SLO на операции с данными.
  • Отдельно думать про защиту от кэш‑штормов: cache locking/lease, чтобы не просадить базу, когда Redis/мемкэш внезапно "забывает" ключи.

Вопросы к размышлению

1. Узнаешь ли ты свои продовые боли в описанных кейсах? Где у тебя узкое место — write‑нагрузка, длинные запросы, connection storm, кэш‑шторма? 2. Что ты сейчас используешь для изоляции "шумных соседей": отдельные БД, dedicated инстансы, resource groups, QoS на уровне запросов? 3. Есть ли у вас формальные правила для миграций схемы и кто их реально стопорит, когда хочется "просто добавить колонку"? 4. Насколько ты доверяешь read‑репликам — используешь ли их агрессивно, как OpenAI, или всё ещё боишься lag'а и читаешь почти всё с primary?

Делись в комментах кейсами и анти‑паттернами — особенно интересно, где вы сознательно не стали шардинговать Postgres, а выжали максимум из одной инстанции.

#PostgreSQL #SRE #DevOps #HighLoad #ChatGPT #Scalability #DatabaseReliability #DistributedSystems #Caching #Replication