Всем привет! Пополняю интернеты «еще одной» статейкой с бенчмарками популярных СУБД. Захотелось выяснить, каков оверхед на протокол, работу с сетью и клиентскими соединениями в самом простом кейсе — когда таблица либо совсем пуста, либо данных так мало, что все они в памяти.
Бенчмарк на Rust. Я попросил написать его Chat‑GPT, и он отлично справился.
Исходник здесь
Сравнивал с официальными scylla‑bench и redis‑bench — результаты схожи.
Для теста я специально использовал слабую железку — Orange Pi 3b. Это китайский аналог малинки. Захотелось узнать, на что она способна.

Quad-core 64-bit Cortex-A55 processor 1.8GHz
8GB(LPDDR4/4x)
1000Mbps Ethernet (On-board PHY chip: YT8531C-CA )
SD Flash U1: 10 MB/Sec min write speed.
Она в 15–30 раз слабее моего игрового laptop на core i7. Cреда для тестирования получилась идеальной. Генератор нагрузки гораздо мощнее сервера, а гигабитный ethernet всё равно что 400Gbit на реальном кластере. К сожалению, m2 ssd на ней так и не завелся, пришлось тестить на SD карте классом скорости 10MB/Sec. Из за этого цифры записи можно не воспринимать как адекватные. В конце статьи дополнительно приведу результаты, полученные на своем игровом лэптопе.
Для теста я взял Redis, Cassandra, Scylla, MongoDB и Postgres по возрастанию предоставляемых возможностей и сложности архитектуры СУБД. Да, в каком то смысле это сравнение слона, карася и утки. Но правда в том, что какая бы БД не была в вашей системе, вы всё равно прикрутите её дополнительно как key-value к части бизнес логики. Так что, сравнение допустимо. Redis архитектурно работает в режиме одного потока, поэтому я запускал 4 отдельных процесса‑шарда — один на ядро. Распределение запросов по шардам происходило на стороне клиента. Остальные же базы активно используют все 4 ядра по умолчанию. Mongo по определенным причинам запускал в докере (и даже не с host network), остальные базы просто устанавливал в систему. Настройки дефолтные, т.к. нас не интересуют размеры кэшей и индексов в данном тесте, они не повлияют ни на что.
Подробнее подсветим несколько основным моментов:
диск вообще нигде не используется для тестов на чтение, всё всегда лежит в памяти. запись в конкретном тесте нас в целом не интересует. это данные приведены просто для полноты картины.
в этом бенчмарке я попытался нивелировать ту часть внутренней логики, которая занимается непосредственно самим поиском данных — бегает по индексам, страницам памяти, ходит на диск и тп. меня интересовали все остальные шаги, которые она (база данных) проходит начиная от получения пакета по сети и до момента отправки ответа обратно.
Из всего набора выделяется только Redis (это вообще не база данных), все же остальные СУБД во многом схожи. Им ровно так же надо получить сообщение, десериализовать его, обогатить prepared statement, провести все необходимые проверки, пройтись по плану запроса, получить данные, дополнить их в ответе метаданными колонок, проделаеть еще какую то тучу работы, отправить ответ. Но каждая делает это по разному. И, казалось бы, супер навороченная Postgres должна была увязнуть в нагромождении логики, а более простая с этой точки зрения Scylla обогнать её в такого рода простых сценариях. Но на деле это оказалось не так. Redis же здесь не с целью показать, что надо выбросить SQL решения и признать их мертвыми, потому что они слишком медленные. Он здесь для контраста и сравнения порядка величин, какова может быть скорость отдачи проиндексированных данных находящихся в памяти в принципе. Так сказать, референсное значение чистого HashMap приклееного к сокету.
Версии ОС и баз данных.
Redis 7.0.15
Cassanda 5.0.5
Scylla 2025.3.0-0.20250827
Mongo 8.0.13
Postgres 15.04
Сервер — armbian x64 — Linux 6.1.115-vendor‑rk35xx
Генератор нагрузки — Ubuntu 25.04 i7-13620H DDR5-4800 32 GB
Соединены через гигабитный ethernet по кабелю.
Везде использовал prepared statements (далее PS), где это возможно. Для каждого клиентского потока свой connection.
Табличка c payload 108 байт, что вполне сравнимо с реальными сущностями в продакшн системах.
CREATE TABLE vectors (
LONG primary key,
INT[16] vector,
TEXT // 36 bytes utf-8
);
Погнали!
Сперва посмотрим перфоманс в режиме пустой таблицы. Интересно же, какой оверхед на протокол. Не понимаю, почему никто это не делает.
Внизу каждой диаграмм указано количество клиентских потоков/сессий/соединений.

Казалось бы, что сложного отправить ответ с пустым rows, да еще и когда таблица без записей. Но разница получилась значительная. Redis ожидаемо в топе. Scylla чуть быстрее Cassandra. От монги я многого не ждал, там нет аналога PS. Postgres меня удивил, если честно.
Теперь читаем в табличку с заполненными данными. Датасет небольшой — 1млн записей. Здесь главное, что на каждое чтение возвращается ответ в 1 row с payload размером 108 байт. Селектим рандомными id из массива всех вставленных в таблицу ключей. Всё, что здесь происходит — lightweight парсинг препарашки, поиск и сериализация. Помимо данных в ответе всегда присутствуют имена колонок. Везде, кроме Redis. Там просто blob.

C Redis всё понятно, Cassandra просела еще сильнее. Почему она стала медленнее Mongo, для меня загадка. При селекте из пустой таблицы она её обгоняла. Забавно, что Postgres всё равно быстрее Scylla.

Я попутно смотрел disk io — Postgres очень много пишет. Как я упоминал выше, на железке SD карта, поэтому результаты не стоит воспринимать слишком всерьез. Но разброс цифр заметный, и это заставляет задуматься. 5к RPS это почти 500 млн записей в сутки. На этом то калькуляторе!
Теперь посмотрим на latency. Привел цифры только select single row. Для столбцов с одним клиентом я указал min latency, для остальных (2-64) — average latency. Кассандру я долго прогревал перед каждый тестом, наблюдая как RPS постепенно возрастает примерно в 7-8 раз от значений после холодного старта.

С Cassandra и Mongo ничего неожиданного. Как и с Redis. Scylla снова оказалась медленнее Postgres. Здесь действительно видно, насколько слаба эта железка. 500 микросекунд на запрос это ж целая вечность.
Теперь самое интересное. Напомню, для Scylla, Cassandra и Postgres я использовал prepared statements. В Redis это не нужно. В Mongo прямого аналога нет. Посмотрим, сколько байт ходит по сети на 1 запрос. Оверхэд сетевого стека в моём случае 66 байт — это фрейм Ethernet, заголовок TCP + доп параметры протокола. Соответственно, от каждого столбца можно отнять эту цифру, чтобы понять чистый payload. Проверял через tcpdump. Empty — это select из пустой таблицы, read full — select с ответом в 1 row. Ну и insert.

Что тут интересного? Redis не отправляет ничего лишнего. У Cassandra и Scylla одинаковый протокол, использовал один и тот же драйвер и даже код бенчмарка, но размер сообщений местами разный. Я так и не выяснил, почему. Монга из за того, что там нет полноценных PS, посылает в запросе очень много данных. Redis не отправляет имена колонок в ответе. А у Cassandra какой то жирный протокол, что даже Postgres местами лучше!
В конце обещанный бенч на ноуте. Север и генератор нагрузки разделены через cpuset по разным cpu core. Redis запускал как 4 отдельных инстанса.
Select из пустой таблицы

Вот вам и 500k RPS. А Postgres — 248k.
Select single row.

Собственно, те же +-500k RPS. Загрузка сети (на loopback) доходила до гигабита на чтение. И чем вас не устраивает Postgres как mem cache? )

Для 1 клиента указано минимальное latency, для остальных столбцов среднее.
Что мы видим? Цифры в районе 10-30 микросекунд. И это просто лэптопный процессор, а не серверный Xeon. На хорошем железе они могут быть и меньше 10, уверен. Да, это через loopback, и тем не менее.
Выводы.
Postgres великолепна. Scylla действительно быстрее Cassandra. И дело не в Java. Видимо, кассандру пришло время рефакторить. Я ожидал, что Scylla должна была быть никак не медленнее Postgres в такого рода тестах, но реальность другая. До сих пор не покидает сомнение, что я протестировал её как то не так, уж очень низкие цифры.
И, честно говоря, не понимаю такую большую разницу в latency.
Я готов теперь поверить в то, что RPS на современном железе для in-memory mode — 50-100k на ядро. А кластер запросто может держать больше миллиона. Например, на той же Scylla. Latency для внешнего кэша на подобных Redis решениях (или на своем велосипеде — ведь у всех же руки чешутся запилить своей кэшик) хотелось бы видеть в пределах 10-20 мкс.
По итогу вопросов для меня больше чем ответов, может в комментах подскажут, почему такие разные цифры.
Почему Scylla настолько медленнее Postgres?
Почему Cassandra так сливает Scylla?
Спасибо, что дочитали до конца!