PostgreSQL

PostgreSQL на 1M+ QPS: опыт компаний

Instagram, Stripe, Notion обрабатывают сотни миллионов операций в день на PostgreSQL. Как они это делают - и почему не перешли на NoSQL?

  • Stripe обработал $817 млрд платежей в 2022 году на PostgreSQL с pgbouncer и partitioning
  • Instagram шардировал PostgreSQL на 1200+ инстансов без замены на NoSQL, встроив shard_id в 64-bit ID
  • Notion шардировал монолитный PostgreSQL за 6 месяцев без единого downtime-инцидента

Instagram: PostgreSQL на 1 млрд пользователей

Instagram запустился на PostgreSQL в 2010 году и к 2012 году обслуживал 30 млн пользователей с одним сервером. Ключевое архитектурное решение: горизонтальное шардирование по user_id до того, как вертикальное масштабирование исчерпало ресурс.

Instagram выбрал PostgreSQL из-за богатой системы типов (arrays, hstore до появления jsonb), надёжных транзакций и активного сообщества. К 2013 году: 1200+ шардов, каждый - полноценный PostgreSQL-инстанс с репликой. Автоматическое шардирование реализовано на уровне Python-ORM.

Проблема UUID vs bigint: Instagram перешёл с UUID на 64-bit ID (Instagram ID), встраивая в ID временную метку и номер шарда. Это позволило декодировать шард без обращения к routing-таблице и сортировать записи по времени создания без отдельного поля created_at.

К 2022 году Meta (Instagram) мигрировала часть нагрузки на MySQL для унификации инфраструктуры, но PostgreSQL остался на критических системах. Опыт Instagram стал основой для open-source шардинг-библиотек в экосистеме Python.

Почему Instagram встроил shard_id в 64-bit ID записей?

Notion: от монолита к шардированию за 6 месяцев

В 2021 году Notion столкнулся с деградацией производительности: один PostgreSQL-кластер с 100+ млн страниц, p99 latency рос, autovacuum не справлялся с объёмом bloat. Команда приняла решение о шардировании за 6 месяцев.

Notion выбрал шардирование по block_id (основная сущность в Notion - block). Ключевой принцип: все операции над workspace выполняются в пределах одного шарда - это обеспечивает атомарность без distributed transactions.

Технические детали миграции: Notion использовал postgres_fdw для временного доступа к данным старого монолита в период backfill. Double-write обеспечивал консистентность. Весь процесс занял 6 месяцев, без единого downtime-инцидента по причине шардирования.

Notion опубликовал post-mortem о шардировании в своём блоге. Ключевой вывод: шардировать надо ДО того, как начались проблемы с производительностью - оставлять запас минимум 2x по текущей нагрузке.

После шардирования: autovacuum работает эффективно на меньших таблицах, query plans стабильны, p99 latency снизилась на 40%. Дополнительный эффект: hot шарды видны в мониторинге, проще изолировать проблемных клиентов.

Почему Notion шардировал по block_id, а не по user_id?

Supabase: PostgreSQL как платформа

Supabase предоставляет PostgreSQL как managed service с расширенными возможностями: Row Level Security для multi-tenancy, реалтайм через logical replication, REST API через PostgREST, GraphQL через pg_graphql. Каждый проект - отдельный PostgreSQL-инстанс.

Реалтайм в Supabase построен на logical replication: отдельный сервис (написан на Elixir) подключается к PostgreSQL как logical replication slot, парсит WAL и отправляет изменения клиентам через WebSocket. Это позволяет подписываться на изменения таблиц в реальном времени без polling.

Supabase запустил pgvector как первоклассную функцию: у каждого проекта расширение pgvector активировано по умолчанию. Это привело к взрывному росту adoption - в 2023 году Supabase стал крупнейшей managed-платформой для PostgreSQL с pgvector, опередив AWS RDS по количеству векторных индексов.

К 2024 году Supabase обслуживает 1M+ PostgreSQL инстансов. Инфраструктура: Fly.io для compute, каждый инстанс - изолированный контейнер. Хранилище данных: S3-совместимое через Supabase Storage с FDW.

Как Supabase реализует реалтайм-подписки на изменения таблиц?

Стратегии шардирования PostgreSQL

Шардирование PostgreSQL реализуется на нескольких уровнях: application-level (самый распространённый), middleware (Citus, pg_partman для partitioning), или через FDW. Каждый подход имеет свои trade-offs по сложности, производительности и поддерживаемости.

Declarative partitioning (PG 10+) - нативный инструмент PostgreSQL для вертикального масштабирования без application-level шардирования. Range partitioning по дате для time-series, hash partitioning для равномерного распределения. Partition pruning позволяет планировщику игнорировать нерелевантные партиции.

Шардирование усложняет JOIN, транзакции, UNIQUE constraints и sequence. Перед шардированием нужно исчерпать: индексы, partitioning, connection pooling, read replicas, caching. Шардирование - последний рубеж, не первый.

Что такое partition pruning в PostgreSQL?

Практические уроки масштабирования

Компании, масштабировавшие PostgreSQL до 1M+ QPS, выработали общие принципы. Они расходятся с интуицией начинающих и подкреплены production-данными из реальных post-mortem и engineering blog-постов.

Stripe обработал $817 млрд платежей в 2022 году на PostgreSQL-кластерах. Ключевые решения: aggressive connection pooling через Pgbouncer, separate read clusters для аналитики, partitioning charges/payment_intents по customer_id. Stripe никогда не переходил на NoSQL для core payments - PostgreSQL с правильной настройкой справляется с любой нагрузкой финтеха.

GitLab мигрировал с MySQL на PostgreSQL в 2018 году и сразу получил 40% снижение нагрузки на базу за счёт лучшего планировщика запросов. Использует Patroni + Consul для HA, 3 read replica, pgbouncer. Весь GitLab.com работает на одном нешардированном PostgreSQL-кластере с правильной настройкой autovacuum и партиционированием по namespace_id.

PostgreSQL не масштабируется для высоких нагрузок - нужен NoSQL

PostgreSQL масштабируется до 1M+ QPS при правильной настройке. Instagram, Stripe, GitLab, Notion - все работают на PostgreSQL при огромных нагрузках.

Узкие места PostgreSQL - connection overhead (решается pgbouncer), bloat (решается autovacuum tuning), и отсутствие horizontal scaling (решается read replicas + partitioning + Citus). NoSQL жертвует ACID и богатой системой запросов, не давая чудес при правильно настроенном PostgreSQL.

Какой подход Stripe использует для масштабирования core payments?

PostgreSQL на масштабе

  • Instagram: шардирование по user_id, 64-bit ID с embedded shard_id, 1200+ PostgreSQL инстансов
  • Notion: шардирование по block_id за 6 месяцев без downtime, dual-write + backfill + switchover
  • Supabase: logical replication WAL → Elixir → WebSocket как основа реалтайма, pgvector по умолчанию
  • Partitioning + connection pooling + read replicas покрывают 95% нагрузок без шардирования
  • Шардировать нужно поздно - Stripe и GitLab работают на нешардированном PostgreSQL при огромных нагрузках

Связанные темы

Масштабирование PostgreSQL требует понимания всего стека

  • Citus — Citus - managed решение для горизонтального шардирования без application-level routing
  • Connection Pooling — PgBouncer - первый шаг масштабирования, обязателен до шардирования
  • Логическая репликация — Logical replication - основа Supabase Realtime и zero-downtime миграций

Вопросы для размышления

  • При каком объёме данных или нагрузке стоит задуматься о шардировании вместо дальнейшей оптимизации одного кластера?
  • Почему Stripe и GitLab могут работать на нешардированном PostgreSQL, а Instagram и Notion перешли к шардированию?
  • Какие компромиссы принимает Supabase, используя logical replication для реалтайма вместо triggers?

Связанные уроки

  • dist-11-replication
PostgreSQL на 1M+ QPS: опыт компаний

0

1

Войти