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

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 serverLD_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/mariadbdatadir = /data/mariadb/dataport = 3306socket = /tmp/mariadb.sockuser = rootpid-file = /data/mariadb/data/mariadb.pidlog-error = /data/mariadb/data/mariadb.err
# Networkingbind-address = 127.0.0.1max_connections = 1024table_open_cache=2000table_open_cache_instances=16back_log=1500max_prepared_stmt_count=102400innodb_open_files=1024
sort_buffer_size = 4Mjoin_buffer_size = 4Mread_buffer_size = 2Mread_rnd_buffer_size = 2Mtmp_table_size = 64Mmax_heap_table_size = 64M
skip-log-binsync_binlog = 0
table_open_cache = 4096table_definition_cache = 2048
# InnoDB (inspired by https://hammerdb.com/ci-config/maria.cnf)default_storage_engine = InnoDBinnodb_buffer_pool_size = 64M#innodb_buffer_pool_instances = 4innodb_log_file_size = 64Minnodb_log_buffer_size = 64Minnodb_flush_log_at_trx_commit = 0innodb_file_per_table = ONinnodb_doublewrite = 0innodb_flush_method = O_DIRECTinnodb_io_capacity = 10000innodb_io_capacity_max = 20000innodb_purge_threads = 4innodb_max_purge_lag_wait=0innodb_max_purge_lag=0innodb_max_purge_lag_delay=1innodb_lru_scan_depth=128innodb_read_only=0innodb_adaptive_hash_index=0innodb_undo_log_truncate=oninnodb_undo_tablespaces=1innodb_fast_shutdown=0innodb_max_dirty_pages_pct=1innodb_max_dirty_pages_pct_lwm=0.1innodb_adaptive_flushing=1innodb_adaptive_flushing_lwm=0.1innodb_flush_neighbors=0innodb_read_io_threads=4innodb_write_io_threads=4innodb_read_ahead_threshold=0innodb_buffer_pool_dump_at_shutdown=0innodb_buffer_pool_load_at_startup=0join_buffer_size=32Ksort_buffer_size=32Kinnodb_use_native_aio=1innodb_stats_persistent=1innodb_log_write_ahead_size=4096performance_schema=OFF
# Loggingslow_query_log = ONslow_query_log_file = /data/mariadb/data/slow.loglong_query_time = 2
# Character setcharacter-set-server = utf8mb4collation-server = utf8mb4_general_ci
# TidesDBplugin_load_add = ha_tidesdb.soplugin_maturity = gamma
tidesdb_pessimistic_locking = OFF
tidesdb_block_cache_size = 64Mtidesdb_max_open_sstables = 512tidesdb_unified_memtable_sync_mode = NONEtidesdb_unified_memtable_write_buffer_size = 64Mtidesdb_default_write_buffer_size = 64Mtidesdb_default_sync_mode = NONEtidesdb_default_compression = NONEtidesdb_flush_threads = 4tidesdb_compaction_threads = 4tidesdb_log_level = NONE
[client]port = 3306socket = /tmp/mariadb.sockdefault-character-set = utf8mb4
[mysqldump]quickmax_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

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:
| Engine | Allocator | Run | File | SHA-256 |
|---|---|---|---|---|
| InnoDB | glibc | 1 | hammerdb_results_20260422_204822.csv | 80b06c93ffe973c030f77429625167476fcfd49b463f1d1ff5e2e30e15791265 |
| InnoDB | glibc | 2 | hammerdb_results_20260422_205525.csv | cb99223245f4487d067f51968d4a190af637530732a9a5d7821ff0182a46d6e9 |
| InnoDB | jemalloc | 1 | hammerdb_results_20260422_212522.csv | ff79aaaa8c44f319f103b87e36bb79626aa9fa49eb1003f98e2574356ddd44bb |
| InnoDB | jemalloc | 2 | hammerdb_results_20260422_213140.csv | 88ae6fb5f9c1bd35d88a492f505cab16ee26bf4b797baa7f82479893add8d359 |
| InnoDB | mimalloc | 1 | hammerdb_results_20260422_215543.csv | f3282fd9d72cca0068f8973c2f3db138e2831920fee83cb9c3faee40501c37d4 |
| InnoDB | mimalloc | 2 | hammerdb_results_20260422_220446.csv | 285cde838f2421d8e1db43dfbd68701cfbf492433301e42e44904abab8f4617b |
| InnoDB | tcmalloc | 1 | hammerdb_results_20260422_223711.csv | 48c8ad610e4c9bb32b9ab0c33af3349d4a794c9d4cbf9b0553d7c478da563994 |
| InnoDB | tcmalloc | 2 | hammerdb_results_20260422_224756.csv | e9caa67036bdeacc64fe709834aa17d1758b85ac36d7c0dfbc8a5e7edc4ccee7 |
| TidesDB | glibc | 1 | hammerdb_results_20260422_210138.csv | cbfbc3cb6665fbafd075f5a159a790998c1c8d709e3b30dc7b297a7e6c78a1cf |
| TidesDB | glibc | 2 | hammerdb_results_20260422_210755.csv | 8a0abffb770f37451fcce693f502c6dd3e2c0702def8b6eff883c6dd293bd450 |
| TidesDB | jemalloc | 1 | hammerdb_results_20260422_213748.csv | 39d496b0128c1523e857ae1fe613cdd6ac62b5e1749b2bd15641f9c83a1a8327 |
| TidesDB | jemalloc | 2 | hammerdb_results_20260422_214352.csv | 7e308e4c272507d4760b8a05cb667313bd67dff74d4932370087d866a264c9b0 |
| TidesDB | mimalloc | 1 | hammerdb_results_20260422_221243.csv | 8e18f4c4d25f1be5d48f1d61753585cc5d997894afd2e77512b95f377229660b |
| TidesDB | mimalloc | 2 | hammerdb_results_20260422_222049.csv | ead9b35bc0f09e70cb502654f2d821d9a282533c7bdeb2b17b22c3d22cb6ba44 |
| TidesDB | tcmalloc | 1 | hammerdb_results_20260422_225637.csv | 82ecdd2c3ed1aa252879284d0e3f5c1a7d4fd625741ba38008758223e7358dbc |
| TidesDB | tcmalloc | 2 | hammerdb_results_20260422_230301.csv | 49c71d8042e88265367b154db6e9fcb744de18eb2eb3766e1e30202521f5f0f6 |
Bundle of all data: hammerdb_mariadb_allocator_analysis.zip (bfd2d99e7a9c873e37bab370d5f1c26671d349fd0e8fa3feb8758d2668641016)