В конце января OpenAI порадовала статьёй про то, как у них устроен backend, вот её перевод на русский от @CoolJuice. Хороший материал для размышлений на тему system design, и, в частности, для поиска ответов на вопросы:

Стоит ли идти таким путём начинающему стартапу?

Спойлер

Почему бы и нет. На PostgreSQL можно решить подавляющее большинство задач по хранению данных в рамках типичного стартапа.

Стоило ли OpenAI так делать?

Спойлер

Всё сложно. Скорее нет, чем да.


О подходе

При анализе архитектуры системы следующие факторы являются ключевыми:

  • Нефункциональные требования (NFR)

  • Имеющиеся ресурсы (бюджет, команда, сроки)

Почему так? Одну и ту же функциональность можно реализовать по-разному, и выбор реализации будет зависеть как раз от этих факторов. Например, если нужна очень высокая производительность для записи событий, то можно смотреть в сторону Kafka, Redpanda, Pulsar. Если же требования к производительности умеренные, то можно события в том же PostgreSQL хранить. Возможен вариант, когда команда не имеет опыта с нужными технологиями, а сроки поджимают -- в этом случае недостаток производительности компенсируется "железом".

Посмотрим же на нефункциональные требования.


CAP. Но не теорема

Полный список non-functional requirement весьма внушителен, с чего начинать? С тройки Consistency, Availability, Partition tolerance Performance. Откуда это следует, почему consistency впереди? Потому что это требование оказывает сильное влияние на выполнение требований как по availability, так и по performance.

Рассмотрим на примере. Допустим, у нас в качестве СУБД работает Scylla/Cassandra и используется значение 3 для replication factor. Если для какой-то порции данных доступна только одна реплика, то система всё ещё может обрабатывать запросы с consistency level 1, а вот с consistency level 2 -- уже нет (наблюдаем влияние на availability). Что же касается performance, то запросы с consistency level 1 будут обрабатываться быстрее, чем запросы с consistency level 2.

Итак, consistency. Consistency определяет, насколько актуально состояние системы, наблюдаемое операцией чтения. В OpenAI типичная операция чтения актуального состояния системы не наблюдает, так как для операции чтения предназначены около 50 асинхронных реплик. Налицо eventual consistency (когда-то, в светлом будущем, читатель увидит то, что записал писатель), по крайней мере, для существенной части операций чтения.

Для некоторых операций записи допустимо не видеть изменений вообще, на это указывает "we... introduced lazy writes, where appropriate, to smooth traffic spikes". Lazy write при потере primary server означает потерю данных. Иными словами, потеря данных заложена в архитектуру, по крайней мере, для части операций.

Availability. С доступностью по типичному чтению всё хорошо -- с такими-то требованиями по consistency и количеством реплик чтения. С доступностью по записи и по чтению с высокой согласованностью ситуация сложнее.

OpenAI описывает ситуацию так:

To mitigate primary failures, we run the primary in High-Availability (HA) mode with a hot standby, a continuously synchronized replica that is always ready to take over serving traffic. If the primary goes down or needs to be taken offline for maintenance, we can quickly promote the standby to minimize downtime. The Azure PostgreSQL team has done significant work to ensure these failovers remain safe and reliable even under very high load.

Итак, если "in the fifth my server goes down", то в дело вступает запасной игрок. Как быстро это происходит? Recovery Time Objective для Azure PostgreSQL составляет 120 секунд -- речь про конфигурации Zone redundant high availability и Same zone high availability. Какое-то дополнительное влияние будет оказывать процесс cache warm-up, но степень этого влияния проанализировать не возьмусь, ибо OpenAI использует некий дополнительный caching layer.

Performance. Оригинальная статья даёт такой ориентир: "we’ve scaled PostgreSQL at OpenAI to support millions of queries per second". Этого недостаточно для оценки производительности, так как запросы могут быть разными по сложности, поэтому придётся довериться интуиции и пользовательскому опыту (я почти с самого начала "платный" пользователь ChatGPT). Видимо, речь про короткие транзакции с простыми операциями (INSERT, UPDATE, DELETE, SELECT по ключу/части), иными словами, перед нами типичная OLTP нагрузка.

Итак, что нам известно или угадано:

- Consistency target
  - Eventual consistency для большинства операций чтения
  - Возможна потеря данных для части операций записи
- Availability target: 99.999%
- Performance target:
  - QPS: millions
  - Load profile, educated guess:
    - В основном INSERT, UPDATE, DELETE, SELECT по ключу/части
    - 95%+ reads, <5% writes
  - p99 latency: low double-digit ms (~10-30ms)

Переходим к ресурсам.


Ресурсы

If you're not embarrassed by the first version of your product, you've launched too late

Reid Hoffman

Эта известная, среди участников стартапов, ма́ксима, содержит в себе весомое рациональное зерно. Если вы "умеете" в PostgreSQL и нужно срочно "пилить", при ограниченных ресурсах -- конечно "пилите"! Победителей не судят, некоторые косяки пользователи простят. Например, какое-то время я многократно наблюдал в ответах на свои вопросы некие хвосты ответов другим пользователям, и даже писал куда-то в поддержку OpenAI по этому поводу.

Тут, конечно, надо заметить, что "правило Хоффмана" по сути развивает более раннюю классическую мысль: "Premature optimization is the root of all evil" (Donald Knuth). То, что преждевременно для OpenAI, вовсе не преждевременно для продукта типа VictoriaMetrics.

А какие, собственно, ресурсы были у OpenAI? Согласно википедии:

In December 2015, OpenAI was founded as a not for profit organization by Sam Altman, Elon Musk, Ilya Sutskever, Greg Brockman, Trevor Blackwell, Vicki Cheung, Andrej Karpathy, Durk Kingma, John Schulman, Pamela Vagata, and Wojciech Zaremba, with Sam Altman and Elon Musk as the co-chairs. A total of $1 billion in capital was pledged by Sam Altman, Greg Brockman, Elon Musk, Reid Hoffman, Jessica Livingston, Peter Thiel, Amazon Web Services (AWS), and Infosys. However, the actual capital collected significantly lagged pledges. According to company disclosures, only $130 million had been received by 2019

Т.е. это не совсем типичный pre-seed раунд, когда инвестируют фаундеры, друзья, тёти или ангелы с бизнес-крылышками.

Давайте посмотрим, что получилось.


Текущая архитектура

Тут интересно не столько то, что получилось, сколько то, чем пожертвовали, по сравнению с "обычным" PostgreSQL-based решением. Цитаты из статьи:

  • Schema changes are restricted to existing tables

  • If a new feature requires additional tables, they must be in alternative sharded systems such as Azure CosmosDB rather than PostgreSQL

  • If joins are necessary, we learned to consider breaking down the query and move complex join logic to the application layer instead

  • Many of problematic queries are generated by Object-Relational Mapping frameworks (ORMs), so it's important to carefully review the SQL they produce and ensure it behaves as expected

  • Lazy writes (потенциальная потеря данных)

  • Cascading read replicas (требуется специальное сотрудничество с Azure PostgreSQL team)

  • Caching layer перед PostgreSQL

Разработка в таких рамках -- это особый вид удовольствия, которое усиливается от ощущения большого риска допустить случайную ошибку.


Оценка архитектуры

В моей новостной ленте в LinkedIn я довольно часто видел посты примерно такого содержания: "обычный PostgreSQL справляется с экстремальными нагрузками, а значит, не стоит спешить со сложными решениями". Автор перевода, @CoolJuice, формулирует эту мысль достаточно явно:

В качестве послесловия хочу отметить что опыт OpenAI наглядно демонстрирует, что даже в эпоху специализированных NoSQL решений, традиционные реляционные СУБД, такие как PostgreSQL могут ещё дать фору новомодным решениям и обеспечить приемлемый уровень доступности и что не всегда нужно спешить, и заниматься построением "космолетов".

С этим согласиться, конечно, нельзя. Ну то есть вот так -- взять и согласиться, без рассуждений. А рассуждения здесь следующие.

При заявленных нефункциональных требованиях и доступных ресурсах естественным выбором сегодня была бы распределённая NoSQL-СУБД вроде CosmosDB -- к чему OpenAI в итоге всё равно пришла. Такой выбор позволяет сосредоточиться на решении задач бизнеса, а не на постоянной оптимизации реляционной СУБД, большая часть возможностей которой в данном случае практически не используется.

Есть, впрочем, важный нюанс. То, что выглядит очевидным сейчас, было далеко не столь очевидно в 2015 году, когда OpenAI только была основана. Azure DocumentDB появилась лишь в 2014 году. Из того, с чем я работал, теоретически можно было бы выбрать Cassandra (2010), но, как обычно, задним умом все крепки.


Заключение

Решения, принятые в 2015 (?) году, были (возможно) рациональны в условиях того времени, доступных технологий и неопределённости будущего. Но это не делает их универсальной рекомендацией для систем, проектируемых сегодня. Использование PostgreSQL в данном случае приводит к длинному списку сознательных жертв.

Архитектура OpenAI -- это не пример "простого решения на PostgreSQL". Это пример того, во что превращается архитектура, когда PostgreSQL вынуждают работать в режимах, для которых он не предназначался.

Комментарии (14)


  1. CoolJuice
    10.02.2026 12:06

    В целом я с вами согласен, когда ты точно знаешь что строишь геораспределённую систему на несколько континентов, думать о том какие будешь использовать инструменты и подходы конечно же нужно. Посыл был в том, что многие не достигают даже части этой нагрузки, но уже спешат все переоптимизировать, не думая о том, что у всего есть цена. Та же Casandra которую вы упомянули, имеет ряд ограничений по работе с запросами, а в условиях какого-то стартапа просто может не быть возможностей заранее точно понять какие запросы будут нужны (с Сassаndra сам наткнулся в практике на такие проблемы, хотя как к инструменту у меня к ней нет никаких претензий).


    1. maxim_ge Автор
      10.02.2026 12:06

      Я полностью поддерживаю идею использовать Postgress в большинстве "начальных" случаев -- при условии наличия в команде соответствующих компетенций, конечно.

      В основном полемика идёт вокруг тезиса "PostgreSQL могут ещё дать фору новомодным решениям".

      Вот смотрите, Вы пишете: "когда ты точно знаешь что строишь геораспределённую систему на несколько континентов". Почему же сразу гео и на несколько континентов? А уметь переживать падение датацентра внутри континента - разве не является задачей, достойной рассмотрения?

      Cassandra/Scylla решают это задачу так... Ну как решают - это у них в DNA прописано. RF=3, NetworkTopologyStrategy и т.д. Т.е. всё работает прямо "из коробки", не требуя особых усилий по конфигурации и доработке ПО.

      Вот такой аспект, конечно, посложнее будет - "точно понять какие запросы будут нужны". С Cassandra надо работать в парадигме ключ-значение, CQL лишь способ придать некоторую структуру ключам и значениям, не более. Запрос на чтение - всегда по ключу или по подключу. Все сложные соединения и агрегации - через заранее подготовленные материализованные VIEW. У нас вот этот продукт сделан по такой технологии.

      В основном всё круто работает. Основная проблема - получить развёрнутую статистику по всем клиентам. Тут пока думаем использовать ClickHouse. Ну т.е. Scylla/Cassandra - это OLTP профиль нагрузки, ClickHouse - OLAP. Это, к тому же, разные типы хранения - строковые и колоночные.


      1. CoolJuice
        10.02.2026 12:06

        Пережить падение ДЦ, это очень важная задача, но это целый план DR. Так как не ограничивается только работой с БД. Именно для этих целей любое облако, например, просит работать минимум с двумя зонами доступности. И PostgreSQL вполне спокойно работает в таких условиях. Что удобнее и проще, вопрос философский, мой ответ - там где есть достаточные в команде компетенции. У каждого инструмента свои сильные и слабые стороны.

        Денормализация данных и поддержка работоспособности в условиях активной разработки и последующего версионирования схем БД для Cassandra, отнюдь не самая тривиальная задача. Фактически нужно подстроить разработку под БД, тоже не все готовы на это пойти.

        Плюс большие требования для железа, это будет 1,5-2 раза (субъективно) будет занимать больше места на то же количество информации в сравнении с реляционками. Главный же момент, который отталкивает именно бизнес, это сама парадигма: жертвуя консистентностью в пользу доступности (до этого понимания нужно дорасти).


        1. maxim_ge Автор
          10.02.2026 12:06

          И PostgreSQL вполне спокойно работает в таких условиях

          Можно подробнее, как он работает? Вот есть три bare metal сервера в трёх ДЦ, что нужно сделать, чтобы обеспечить strict consistency и fault tolerance к выпадению одного ДЦ? Для cassandra/scylla это решается штатно незамысловатым конфигом.

          Достаточно просто также добавить дискового пространства и вычислительных мощностей в систему путем добавления узлов - это тоже штатные процедуры. Как с этим у PostgreSQL?

          Плюс большие требования для железа, это будет 1,5-2 раза (субъективно) будет занимать больше места на то же количество информации в сравнении с реляционками.

          Ну тут таки да, три копии данных вместо двух (у Postgres) в стандартной HA-конфигурации.

          Главный же момент, который отталкивает именно бизнес, это сама парадигма: жертвуя консистентностью в пользу доступности (до этого понимания нужно дорасти).

          По опыту, бизнесу вообще это не очень важно или легко объясняется. Тут скорее вопрос в технарях, и как раз та самая "переоптимизация".


          1. CoolJuice
            10.02.2026 12:06

            1) Если мы говорим про ванильный PostgreSQL, то действительно шатные средства отсутствуют. Но это не означает что задача не решаема в принципе, популярный стек: Patroni + Consul (ZooKeeper или etcd), для получения автоматического failover. Или использовать Citus который превратит БД в распределённую систему. Но смысл и сила PostgreSQL, как раз в реляционной модели и ACID. Вокруг PG сложилась обширная экосистема, которая решает сопутствующие проблемы.

            2.1) Про размер: дело не только (и не столько) в количестве копий БД, а в самой структуре хранения данных и индексов.

            Например:

            Для быстрого запроса "получить все заказы пользователя" создаём таблицу orders_by_user_id, где ключ партиции будет поле user_id, а в строке будут хранится все данные заказов.

            Для запроса же к тем же данным, например "получить заказ по номеру" необходимо будет создать другую таблицу orders_by_order_id, где снова мы будем хранить все те же данные заказа, но уже в другой партиции. То есть данные заказа физически будут продублированы 2 раза.

            2.2) Кроме того PostgreSQL имеет продвинутые механизмы сжатия на уровне страниц для больших полей или NULL-значений. Cassandra же традиционно менее эффективна в сжатии отдельных строк и сжимает данные на уровне дисковой системы. Что не настолько эффективно, как комбинация сжатия страниц и отсутствие дублирования данных.

            2.3) В силу специфики самого механизма работы, Cassandra хранит не только само значение, но и дополнительные метаданные: маркеры времени для разрешения конфликтов, TTL или например информацию о кластере внутри партиции.

            2.4) Ну и механизм сборки мусора тоже не очень сильно эффективен по сравнению с PG.

            То есть по этим пунктам Cassandra очень сильно проигрывает PostgreSQL. Но оно и не удивительно, как я выше написал, это плата за инструмент.


            3) Про то что бизнесу всё равно: ему всё равно, пока не приходят счета))


            1. maxim_ge Автор
              10.02.2026 12:06

              Но это не означает что задача не решаема в принципе, популярный стек: Patroni + Consul (ZooKeeper или etcd), для получения автоматического failover.

              Дык в принципе оно конечно решается, кто ж спорит. Но по рассматриваемому факту у OpenAI не решилось - они это дело аутсорсят вместо того, чтобы взять bare metal и сэкономить денег.

              Но смысл и сила PostgreSQL, как раз в реляционной модели и ACID.

              Это в каком-то смысле верно.

              Но если целиться в распределённую систему, то сила реляционной модели превращается в её слабость. Для high-load OLTP нагрузки лучше подходят key-value базы, ибо для скорости требуется точечное чтение - запись. Для OLAP нужна колоночная база, там и скорость, и сжатие огромное.

              Про то что бизнесу всё равно: ему всё равно, пока не приходят счета))

              Так как раз счета придут больше, если обеспечивать strict consistency там, где этого не требуется. Именно через этот аргумент бизнес и убеждается легко в том, что давайте лучше eventual consistency, где можно - дешевле выйдет.

              По остальному предметно без данных конкретных экспериментов говорить не готов. Но, впрочем, качественно склонен согласится.


  1. OlegIct
    10.02.2026 12:06

    При заявленных нефункциональных требованиях и доступных ресурсах естественным выбором сегодня была бы распределённая NoSQL-СУБД вроде CosmosDB

    был пример стартапа, который выбрал DynamoDB. При всей квалификации специалистов этого стартапа использование нереляционной базы привело к 15-часовому простою https://habr.com/ru/amp/publications/960394/


    1. maxim_ge Автор
      10.02.2026 12:06

      Как пример - интересно, как контраргумент - не очень убеждает.

      Тут недавно Cloudflare лихорадило, при всей квалификации разрабов и надёжности языка Rust...

      PS. А ничего, что система с бэком, который работает на PostgreSQL, мне показывала куски чатов от других пользователей?


      1. CoolJuice
        10.02.2026 12:06

        Тут тоже прокомментирую про куски чатов: Контекст вашей проблемы не знаю. Но скорее всего это была проблема не БД, а генеративного ИИ и promt injection. Последнее время я такого не встречал (после 3.5 версии), но на тот момент у меня было исследование на эту тему, когда я добивался того, что бы мне куски других чатов становились доступны. Допускаю что такая ситуация могла воспроизвестись и у вас. Но обыкновенный баг с бекенда тоже никто не отменял. Нарушение же принципов ACID, только потому что это реляционная БД, это нууу... что-то феноменально маловероятное.


        1. maxim_ge Автор
          10.02.2026 12:06

          Но скорее всего это была проблема не БД, а генеративного ИИ и promt injection.

          Интересно. Поясните, как это могло произойти? Я, причём, спрашиваю на русском или английском, а вижу фрагменты ответов на испанском (я в тот период был в Испании, если что).


          1. CoolJuice
            10.02.2026 12:06

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

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

            На практике, баг мог быть и потому что, многие запросы пользователей объединялись в один так называемый "пакет", что бы разом его обработать на GPU. Если в логике обработки ответов вдруг возникла бы какая-то ошибка, то ответы от одного пользователя могли перепутаться с другим.


      1. OlegIct
        10.02.2026 12:06

        Тут недавно Cloudflare лихорадило, при всей квалификации разрабов и надёжности языка Rust...

        Там тоже нереляционная база. По ссылке пишут «Объяснение заключалось в том, что файл генерировался каждые пять минут запросом, выполняемым в кластере баз данных ClickHouse, который постепенно обновлялся для улучшения управления разрешениями.» В более раннем варианте было «Настоящим виновником было обновление прав доступа к базе данных ClickHouse. Это небольшое изменение привело к неожиданному удвоению размера файла функции управления ботами.», что процитировали в https://habr.com/ru/news/967836/

        А ничего, что система с бэком, который работает на PostgreSQL, мне показывала куски чатов от других пользователей?

        PostgreSQL в таком не был замечен. Не думаю, что чат сохранялся в базу PostgreSQL из статьи, так как обьем чатов огромный, а у них еще и 50 реплик - в 50 раз больший объем бы был.

        Вероятно, кусок чужого чата брался из структуры в памяти на сервере приложений. На чем у них сервер приложений не знаю, возможно питон. По аналогии из java что-нибудь типа артефактов при использовании несинхронизированных non-thread-safe коллекций.


        1. maxim_ge Автор
          10.02.2026 12:06

          Настоящим виновником было обновление прав доступа к базе данных ClickHouse

          Намекаете, что если изменить права доступа к БД PostgreSQL то это никак не повлияет на результат запроса?

          В статье же пишут: a single Rust .unwrap() in Cloudflare's edge network.

          PostgreSQL в таком не был замечен.

          Безусловно. В этом замечена монструозность архитектур - чем архитектура монструознее, тем больше вероятность прокола.


          1. OlegIct
            10.02.2026 12:06

            не намекаю. Какие-то технологии сподвигают ошибаться, какие-то наоборот затрудняют использование возможностей, которые приводят к ошибкам. В Cickhouse поменяли права и создались таблицы в схеме default, вместо r0. Запрос к системной таблице с order by, но без distinct.

            OpenAI в PostgreSQL: «Изменения схемы ограничены существующими таблицами». В реляционных базах в эксплуатации не принято просто так выполнять DDL. Страсть к изменениям реализуют переписыванием selectов. С clickhouse selectам, наверное, уделяют меньше внимания и теряют навыки (distinct или where).

            Согласен, что чем монструознее, тем больше вероятность ошибки. Основное - сложность в использовании плюс сподвигание к ошибкам или затруднения в использовании опасных возможностей. Переход на распределенные системы - резкий скачок сложности.