Skip to content

TPC-C Analysis with glibc, jemalloc, mimalloc, tcmalloc on TideSQL & InnoDB in MariaDB v11.8.6

TPC-C Analysis with glibc, jemalloc, mimalloc, tcmalloc on TideSQL & InnoDB in MariaDB v11.8.6

by Alex Gaetano Padula

published on April 22nd, 2026

It’s been on my mind for a while to run analysis with different allocators running in TidesDB in which is the lower level component for the MariaDB plugin TideSQL. In TidesDB you can configure jemalloc, mimalloc, or tcmalloc as the allocator when building. I’ve run this analysis using HammerDB TPROC-C and a custom script to automate the processes.

When installing TideSQL you can specify the allocator to build with TidesDB, the installer does all the mapping for you

Because TidesDB and TideSQL don’t come packaged in MariaDB and are external in this analysis I had to rebuild TidesDB with each allocator and restart my MariaDB server also to load the new allocator on MariaDB so both library and engine use the same allocator.

-- First i installed MariaDB with TidesDB and TideSQL
./install.sh --mariadb-prefix /data/mariadb --tidesdb-prefix /data/tidesdb --build-dir /data/tidesql-build --mariadb-version
mariadb-11.8.6
-- Now I went ahead with glibc allocator
-- Then before each other besides glibc allocator analysis I rebuilt TidesDB, rebuilt plugin and restarted MariaDB server.
cd /data/tidesql-build/tidesdb-lib
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/data/tidesdb \
-DTIDESDB_BUILD_TESTS=OFF \
-DBUILD_SHARED_LIBS=ON \
-DTIDESDB_WITH_JEMALLOC=ON
-- Now I went ahead with mimalloc allocator
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/data/tidesdb \
-DTIDESDB_BUILD_TESTS=OFF \
-DBUILD_SHARED_LIBS=ON \
-DTIDESDB_WITH_MIMALLOC=ON
-- Now I went ahead with tcmalloc allocator
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/data/tidesdb \
-DTIDESDB_BUILD_TESTS=OFF \
-DBUILD_SHARED_LIBS=ON \
-DTIDESDB_WITH_JEMALLOC=OFF \
-DTIDESDB_WITH_MIMALLOC=OFF \
-DTIDESDB_WITH_TCMALLOC=ON
-- For rebuilding its simple as
./install.sh \
--mariadb-prefix /data/mariadb \
--tidesdb-prefix /data/tidesdb \
--build-dir /data/tidesql-build \
--rebuild-plugin
-- Then when restarting server
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 /data/mariadb/bin/mariadbd-safe --defaults-file=/data/mariadb/my.cnf &
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libmimalloc.so.2 /data/mariadb/bin/mariadbd-safe --defaults-file=/data/mariadb/my.cnf &
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4 /data/mariadb/bin/mariadbd-safe --defaults-file=/data/mariadb/my.cnf &

installed TidesDB v9.0.9, TideSQL v4.2.5

The specs for the environment are

  • AMD Ryzen Threadripper 2950X (16 cores 32 threads) @ 3.5GHz
  • 128GB DDR4
  • Ubuntu 22.04 x86_64
  • XFS raw NVMe(SAMSUNG MZVLB512HAJQ-00000) w/discard, inode64, nodiratime, noatime, logbsize=256k, logbufs=8
my.cnf
[mysqld]
basedir = /data/mariadb
datadir = /data/mariadb/data
port = 3306
socket = /tmp/mariadb.sock
user = root
pid-file = /data/mariadb/data/mariadb.pid
log-error = /data/mariadb/data/mariadb.err
# Networking
bind-address = 127.0.0.1
max_connections = 1024
table_open_cache=2000
table_open_cache_instances=16
back_log=1500
max_prepared_stmt_count=102400
innodb_open_files=1024
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 2M
read_rnd_buffer_size = 2M
tmp_table_size = 64M
max_heap_table_size = 64M
skip-log-bin
sync_binlog = 0
table_open_cache = 4096
table_definition_cache = 2048
# InnoDB (inspired by https://hammerdb.com/ci-config/maria.cnf)
default_storage_engine = InnoDB
innodb_buffer_pool_size = 64M
#innodb_buffer_pool_instances = 4
innodb_log_file_size = 64M
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 0
innodb_file_per_table = ON
innodb_doublewrite = 0
innodb_flush_method = O_DIRECT
innodb_io_capacity = 10000
innodb_io_capacity_max = 20000
innodb_purge_threads = 4
innodb_max_purge_lag_wait=0
innodb_max_purge_lag=0
innodb_max_purge_lag_delay=1
innodb_lru_scan_depth=128
innodb_read_only=0
innodb_adaptive_hash_index=0
innodb_undo_log_truncate=on
innodb_undo_tablespaces=1
innodb_fast_shutdown=0
innodb_max_dirty_pages_pct=1
innodb_max_dirty_pages_pct_lwm=0.1
innodb_adaptive_flushing=1
innodb_adaptive_flushing_lwm=0.1
innodb_flush_neighbors=0
innodb_read_io_threads=4
innodb_write_io_threads=4
innodb_read_ahead_threshold=0
innodb_buffer_pool_dump_at_shutdown=0
innodb_buffer_pool_load_at_startup=0
join_buffer_size=32K
sort_buffer_size=32K
innodb_use_native_aio=1
innodb_stats_persistent=1
innodb_log_write_ahead_size=4096
performance_schema=OFF
# Logging
slow_query_log = ON
slow_query_log_file = /data/mariadb/data/slow.log
long_query_time = 2
# Character set
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
# TidesDB
plugin_load_add = ha_tidesdb.so
plugin_maturity = gamma
tidesdb_pessimistic_locking = OFF
tidesdb_block_cache_size = 64M
tidesdb_max_open_sstables = 512
tidesdb_unified_memtable_sync_mode = NONE
tidesdb_unified_memtable_write_buffer_size = 64M
tidesdb_default_write_buffer_size = 64M
tidesdb_default_sync_mode = NONE
tidesdb_default_compression = NONE
tidesdb_flush_threads = 4
tidesdb_compaction_threads = 4
tidesdb_log_level = NONE
[client]
port = 3306
socket = /tmp/mariadb.sock
default-character-set = utf8mb4
[mysqldump]
quick
max_allowed_packet = 64M
[mariadb-backup]

I ran the script twice per engine per allocator (glibc, jemalloc, mimalloc, and tcmalloc).

./hammerdb_runner.sh -b tpcc --warehouses 40 --tpcc-vu 8 --tpcc-build-vu 8 --rampup 1 --duration 2 --settle 5 -H ~/HammerDB-5.0 -e <innodb|tidesdb> -u hammerdb --pass hammerdb123 -S /tmp/mariadb.sock

TPCC NOPM by Allocator

TPCC Average Latency by Allocator

From the analysis what we see is in MariaDB 11.8.6 the two engines respond very differently to allocator choice. InnoDB is effectively flat across all four allocators, the spread between the best (glibc, ~16.9k NOPM) and the worst (mimalloc, ~16.6k NOPM) is under 2.1%, and average new-order latency stays inside an 8.10–8.18 ms band regardless of which allocator the server is preloaded with. TidesDB on the other hand is strongly allocator-sensitive in that jemalloc (~75.1k NOPM) and tcmalloc (~74.5k NOPM) are the clear winners, glibc (~68.8k) is roughly 8–9% behind them, and mimalloc is the outlier going the other way at ~42.7k NOPM, a ~43% drop versus jemalloc, with average new-order latency rising from ~3.46 ms to ~4.91 ms and p95 from ~5.0 ms to ~7.4 ms.

The article’s takeaway is rather split, for InnoDB the allocator basically does not matter at this scale, while for TidesDB jemalloc and tcmalloc are interchangeable best picks, glibc is acceptable, and mimalloc should be avoided in this configuration. Even at its worst case TidesDB still does ~2.5x the throughput of InnoDB, and at its best ~4.5x, so the engine difference dominates the allocator difference in every cell of the matrix.

That’s all for this article.

Thank you for reading

Learn more about jemalloc, mimalloc, and tcmalloc:

Learn more about TidesDB:

Learn more about TideSQL:

You can find all the data from the analysis below:

EngineAllocatorRunFileSHA-256
InnoDBglibc1hammerdb_results_20260422_204822.csv80b06c93ffe973c030f77429625167476fcfd49b463f1d1ff5e2e30e15791265
InnoDBglibc2hammerdb_results_20260422_205525.csvcb99223245f4487d067f51968d4a190af637530732a9a5d7821ff0182a46d6e9
InnoDBjemalloc1hammerdb_results_20260422_212522.csvff79aaaa8c44f319f103b87e36bb79626aa9fa49eb1003f98e2574356ddd44bb
InnoDBjemalloc2hammerdb_results_20260422_213140.csv88ae6fb5f9c1bd35d88a492f505cab16ee26bf4b797baa7f82479893add8d359
InnoDBmimalloc1hammerdb_results_20260422_215543.csvf3282fd9d72cca0068f8973c2f3db138e2831920fee83cb9c3faee40501c37d4
InnoDBmimalloc2hammerdb_results_20260422_220446.csv285cde838f2421d8e1db43dfbd68701cfbf492433301e42e44904abab8f4617b
InnoDBtcmalloc1hammerdb_results_20260422_223711.csv48c8ad610e4c9bb32b9ab0c33af3349d4a794c9d4cbf9b0553d7c478da563994
InnoDBtcmalloc2hammerdb_results_20260422_224756.csve9caa67036bdeacc64fe709834aa17d1758b85ac36d7c0dfbc8a5e7edc4ccee7
TidesDBglibc1hammerdb_results_20260422_210138.csvcbfbc3cb6665fbafd075f5a159a790998c1c8d709e3b30dc7b297a7e6c78a1cf
TidesDBglibc2hammerdb_results_20260422_210755.csv8a0abffb770f37451fcce693f502c6dd3e2c0702def8b6eff883c6dd293bd450
TidesDBjemalloc1hammerdb_results_20260422_213748.csv39d496b0128c1523e857ae1fe613cdd6ac62b5e1749b2bd15641f9c83a1a8327
TidesDBjemalloc2hammerdb_results_20260422_214352.csv7e308e4c272507d4760b8a05cb667313bd67dff74d4932370087d866a264c9b0
TidesDBmimalloc1hammerdb_results_20260422_221243.csv8e18f4c4d25f1be5d48f1d61753585cc5d997894afd2e77512b95f377229660b
TidesDBmimalloc2hammerdb_results_20260422_222049.csvead9b35bc0f09e70cb502654f2d821d9a282533c7bdeb2b17b22c3d22cb6ba44
TidesDBtcmalloc1hammerdb_results_20260422_225637.csv82ecdd2c3ed1aa252879284d0e3f5c1a7d4fd625741ba38008758223e7358dbc
TidesDBtcmalloc2hammerdb_results_20260422_230301.csv49c71d8042e88265367b154db6e9fcb744de18eb2eb3766e1e30202521f5f0f6

Bundle of all data: hammerdb_mariadb_allocator_analysis.zip (bfd2d99e7a9c873e37bab370d5f1c26671d349fd0e8fa3feb8758d2668641016)