1. Запросы. Медленные запросы ищут по pg_stat_statements и логу медленных запросов, разбирают EXPLAIN ANALYZE: недостающие индексы, лишние колонки, N+1 из ORM, OFFSET-пагинация. Это дешевле всего и часто даёт кратный эффект.
2. Кэш. Горячие и редко меняющиеся данные — в Redis или локальный кэш. Снимает основную долю чтения, если данные распределены неравномерно.
3. Реплики для чтения. Асинхронные реплики получают поток изменений и обслуживают SELECT. Ограничения: отставание (пользователь не видит только что сделанное — читать свои данные с лидера), запись по-прежнему в один узел, тяжёлые запросы на реплике могут тормозить применение журнала.
4. Модели под чтение. Денормализованные таблицы, материализованные представления, отдельные хранилища: полнотекстовый поиск — в Elasticsearch, аналитика — в ClickHouse через CDC, счётчики — предагрегированные.
5. Шардирование — когда не хватает одной машины по объёму или записи. Самое дорогое: межшардовые запросы, транзакции, решардинг.
Сопутствующее: пул соединений и PgBouncer, вертикальный рост машины (часто самый дешёвый способ выиграть время), архивирование холодных данных и партиционирование больших таблиц.