How to Write to SSDs (VLDB 2026), out-of-place write LeanStore
C++
26
19 commits
updated Aug 16, 2026
LeanStore is a high-performance OLTP storage engine optimized for many-core CPUs and NVMe SSDs. ZLeanStore is an out-of-place write version of LeanStore that co-designs the DBMS and SSD layers to minimize total write amplification (WAF). It is the artifact for the paper:
How to Write to SSDs Bohyun Lee, Tobias Ziegler, and Viktor Leis. Proceedings of the VLDB Endowment (PVLDB), Vol. 19, 2026, p. 1469. VLDB PDF · extended arxiv PDF · Code · Slides
ZLeanStore extends original LeanStore with four out-of-place optimizations that collectively reduce write amplification across both the DB and SSD layers, improving throughput by 1.65--2.24x and reducing flash writes per transaction by 6.2--9.8x on YCSB-A:
The design also natively supports ZNS SSDs (zone-append interface, SSD WAF = 1 by construction) and FDP-enabled SSDs (placement hints replace NoWA to avoid multiplexing).
Total WAF = DB WAF x SSD WAF. The key insight is that optimizing only one layer can counterintuitively worsen the other; both must be addressed jointly.
Install dependencies:
sudo apt-get install build-essential make git pkg-config
sudo apt-get install cmake libtbb-dev libfmt-dev libgflags-dev libgtest-dev \
libgmock-dev libgcrypt-dev liburing-dev libzstd-dev libbenchmark-dev \
libssl-dev zlib1g-dev
exmap (optional): stored in share_libs/exmap if you want to enable exmap
sudo apt-get install linux-headers-$(uname -r)sudo ./load.sh inside share_libs/exmap/Databases (for comparison benchmarks):
sudo apt-get install libwiredtiger-dev libsqlite3-dev libmysqlcppconn-dev libpq-dev libfuse-dev
sudo apt-get install nvme-cli smartmontools fio jq sysstat
mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. && make -j
Configuration flags are defined in src/config.cc. Key flags:
| Flag | Description |
|---|---|
--use_out_of_place_write | Enable out-of-place writes (default: false for in-place baseline) |
--garbage_collector_cnt | Number of GC threads |
--use_compression | Enable page-wise LZ4 compression |
--use_binpacking | Enable 4 KiB-aligned page packing |
--batch_writes | Batch evictions into sequential I/Os |
--use_edt | Enable Estimated Deathtime (GDT) placement |
--block_size_mb | DB zone (GC unit) size in MB -- align to SSD GC unit |
--use_SSDWA1_pattern | Enable the NoWA write pattern (SSD WAF = 1) |
--use_FDP | Use FDP placement hints instead of NoWA |
--simulator_mode | Run with a simulated smaller SSD capacity |
--ycsb_dataset_size_gb | Logical dataset size in GB |
--ycsb_record_count | Number of YCSB records to load |
--bm_physical_gb | Buffer pool size in GB (set to 5--20% of dataset for I/O-bound runs) |
--max_wal_capacity_gb | Maximum WAL size in GB |
--SSD_OP | SSD over-provisioning ratio |
--db_path accepts either a raw block device (e.g. /dev/nvme1n1) or a file path on a mounted filesystem (e.g. /mnt/ssd/leanstore.db). Raw device access bypasses the filesystem for maximum throughput, but requires root or appropriate device permissions and will destroy all data on the device. Using a filesystem path is safer and does not require root, though it adds a small layer of indirection.
cd build/benchmark
./LeanStore_YCSB \
--max_ssd_capacity_gb=16 \
--bm_virtual_gb=18 \
--db_path=/dev/nvme1n1 \
--wal_path="" \
--use_out_of_place_write=true \
--garbage_collector_cnt=16 \
--use_compression=true \
--use_binpacking=true \
--batch_writes=true \
--use_edt=true \
--block_size_mb=512 \
--use_SSDWA1_pattern=false \
--worker_count=64 \
--ycsb_exec_seconds=1200 \
--ycsb_read_ratio=50 \
--ycsb_zipf_theta=0.8 \
--measure_waf=true \
--user_pwd=YOUR_PASSWORD \
| tee trx.csv
./build/benchmark/LeanStore_TPCC \
--tpcc_warehouse_count=100 \
--tpcc_exec_seconds=1800 \
--tpcc_batch_delete_window=0
--tpcc_batch_delete_window=2100--tpcc_batch_delete_window=0benchmark/src/include/benchmark/tpcc/, benchmark/main/leanstore_tpcc.ccSimulator mode emulates a smaller SSD capacity in software, allowing WAF evaluation without dedicating an entire device. I/O is still issued to the underlying device, but the space manager behaves as if the SSD is smaller.
./LeanStore_YCSB \
--simulator_mode=true \
--ycsb_dataset_size_gb=40 \
--bm_physical_gb=8 \
--max_wal_capacity_gb=8 \
--block_size_mb=32 \
--simulator_SSD_gc_unit_mb=32 \
--SSD_OP=0.125 \
--measure_waf=true \
--ycsb_exec_seconds=1800 \
--ycsb_read_ratio=50 \
--ycsb_zipf_theta=0.6 \
--worker_count=8 \
--user_pwd=YOUR_PASSWORD \
| tee trx.csv
The scripts/ directory contains automation for running YCSB workloads on multiple database systems to compare WAF and throughput. See scripts/README.md for full documentation.
| Script | DBMS |
|---|---|
run_leanstore_ycsb_example.sh | ZLeanStore (raw device) |
run_leanstore_ycsb_fdp.sh | ZLeanStore with FDP namespace setup |
run_mysql_ycsb.sh | MySQL / InnoDB |
run_pg_ycsb.sh | PostgreSQL |
run_rocksdb_ycsb.sh | RocksDB |
run_wiredtiger_ycsb.sh | WiredTiger |
Scripts for measuring SSD read performance, inferring GC unit size, and validating the NoWA pattern. These use the iob (I/O benchmark) and sim (SSD simulator) tools from ssdiq_zleanstore. See scripts/README.md for details.
| Script | Purpose |
|---|---|
readlat.sh | Measure random-read latency at multiple block sizes (fio, QD=1) |
readbw.sh | Measure random-read bandwidth (fio, QD=64) |
findssdgcunitsize.sh | Infer the SSD's GC erase-unit size via ZNS-like probing |
testnowa.sh | Validate NoWA achieves SSD WAF = 1 on real hardware |
testnowasim.sh | Validate NoWA and ZNS patterns in the SSD simulator |
calcssdwaf.sh | Continuously sample NVMe SMART counters and compute SSD WAF |
getsmartinfo.sh | Collect raw NVMe media/host write counters |
@article{lee2026howtowrite,
title = {How to Write to SSDs},
author = {Lee, Bohyun and Ziegler, Tobias and Leis, Viktor},
journal = {Proceedings of the VLDB Endowment},
volume = {19},
year = {2026},
pages = {1469},
url = {https://www.vldb.org/pvldb/vol19/p1469-lee.pdf}
}
@misc{lee2026howtowrite_arxiv,
title = {How to Write to SSDs},
author = {Lee, Bohyun and Ziegler, Tobias and Leis, Viktor},
year = {2026},
eprint = {2603.09927},
archivePrefix = {arXiv},
primaryClass = {cs.DB}
}
19 commits
C++
55.1%
C
17.0%
Makefile
14.6%
Shell
7.1%
CMake
3.7%
Python
1.3%
How to Write to SSDs (VLDB 2026), out-of-place write LeanStore
C++
26
19 commits
updated Aug 16, 2026
LeanStore is a high-performance OLTP storage engine optimized for many-core CPUs and NVMe SSDs. ZLeanStore is an out-of-place write version of LeanStore that co-designs the DBMS and SSD layers to minimize total write amplification (WAF). It is the artifact for the paper:
How to Write to SSDs Bohyun Lee, Tobias Ziegler, and Viktor Leis. Proceedings of the VLDB Endowment (PVLDB), Vol. 19, 2026, p. 1469. VLDB PDF · extended arxiv PDF · Code · Slides
ZLeanStore extends original LeanStore with four out-of-place optimizations that collectively reduce write amplification across both the DB and SSD layers, improving throughput by 1.65--2.24x and reducing flash writes per transaction by 6.2--9.8x on YCSB-A:
The design also natively supports ZNS SSDs (zone-append interface, SSD WAF = 1 by construction) and FDP-enabled SSDs (placement hints replace NoWA to avoid multiplexing).
Total WAF = DB WAF x SSD WAF. The key insight is that optimizing only one layer can counterintuitively worsen the other; both must be addressed jointly.
Install dependencies:
sudo apt-get install build-essential make git pkg-config
sudo apt-get install cmake libtbb-dev libfmt-dev libgflags-dev libgtest-dev \
libgmock-dev libgcrypt-dev liburing-dev libzstd-dev libbenchmark-dev \
libssl-dev zlib1g-dev
exmap (optional): stored in share_libs/exmap if you want to enable exmap
sudo apt-get install linux-headers-$(uname -r)sudo ./load.sh inside share_libs/exmap/Databases (for comparison benchmarks):
sudo apt-get install libwiredtiger-dev libsqlite3-dev libmysqlcppconn-dev libpq-dev libfuse-dev
sudo apt-get install nvme-cli smartmontools fio jq sysstat
mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. && make -j
Configuration flags are defined in src/config.cc. Key flags:
| Flag | Description |
|---|---|
--use_out_of_place_write | Enable out-of-place writes (default: false for in-place baseline) |
--garbage_collector_cnt | Number of GC threads |
--use_compression | Enable page-wise LZ4 compression |
--use_binpacking | Enable 4 KiB-aligned page packing |
--batch_writes | Batch evictions into sequential I/Os |
--use_edt | Enable Estimated Deathtime (GDT) placement |
--block_size_mb | DB zone (GC unit) size in MB -- align to SSD GC unit |
--use_SSDWA1_pattern | Enable the NoWA write pattern (SSD WAF = 1) |
--use_FDP | Use FDP placement hints instead of NoWA |
--simulator_mode | Run with a simulated smaller SSD capacity |
--ycsb_dataset_size_gb | Logical dataset size in GB |
--ycsb_record_count | Number of YCSB records to load |
--bm_physical_gb | Buffer pool size in GB (set to 5--20% of dataset for I/O-bound runs) |
--max_wal_capacity_gb | Maximum WAL size in GB |
--SSD_OP | SSD over-provisioning ratio |
--db_path accepts either a raw block device (e.g. /dev/nvme1n1) or a file path on a mounted filesystem (e.g. /mnt/ssd/leanstore.db). Raw device access bypasses the filesystem for maximum throughput, but requires root or appropriate device permissions and will destroy all data on the device. Using a filesystem path is safer and does not require root, though it adds a small layer of indirection.
cd build/benchmark
./LeanStore_YCSB \
--max_ssd_capacity_gb=16 \
--bm_virtual_gb=18 \
--db_path=/dev/nvme1n1 \
--wal_path="" \
--use_out_of_place_write=true \
--garbage_collector_cnt=16 \
--use_compression=true \
--use_binpacking=true \
--batch_writes=true \
--use_edt=true \
--block_size_mb=512 \
--use_SSDWA1_pattern=false \
--worker_count=64 \
--ycsb_exec_seconds=1200 \
--ycsb_read_ratio=50 \
--ycsb_zipf_theta=0.8 \
--measure_waf=true \
--user_pwd=YOUR_PASSWORD \
| tee trx.csv
./build/benchmark/LeanStore_TPCC \
--tpcc_warehouse_count=100 \
--tpcc_exec_seconds=1800 \
--tpcc_batch_delete_window=0
--tpcc_batch_delete_window=2100--tpcc_batch_delete_window=0benchmark/src/include/benchmark/tpcc/, benchmark/main/leanstore_tpcc.ccSimulator mode emulates a smaller SSD capacity in software, allowing WAF evaluation without dedicating an entire device. I/O is still issued to the underlying device, but the space manager behaves as if the SSD is smaller.
./LeanStore_YCSB \
--simulator_mode=true \
--ycsb_dataset_size_gb=40 \
--bm_physical_gb=8 \
--max_wal_capacity_gb=8 \
--block_size_mb=32 \
--simulator_SSD_gc_unit_mb=32 \
--SSD_OP=0.125 \
--measure_waf=true \
--ycsb_exec_seconds=1800 \
--ycsb_read_ratio=50 \
--ycsb_zipf_theta=0.6 \
--worker_count=8 \
--user_pwd=YOUR_PASSWORD \
| tee trx.csv
The scripts/ directory contains automation for running YCSB workloads on multiple database systems to compare WAF and throughput. See scripts/README.md for full documentation.
| Script | DBMS |
|---|---|
run_leanstore_ycsb_example.sh | ZLeanStore (raw device) |
run_leanstore_ycsb_fdp.sh | ZLeanStore with FDP namespace setup |
run_mysql_ycsb.sh | MySQL / InnoDB |
run_pg_ycsb.sh | PostgreSQL |
run_rocksdb_ycsb.sh | RocksDB |
run_wiredtiger_ycsb.sh | WiredTiger |
Scripts for measuring SSD read performance, inferring GC unit size, and validating the NoWA pattern. These use the iob (I/O benchmark) and sim (SSD simulator) tools from ssdiq_zleanstore. See scripts/README.md for details.
| Script | Purpose |
|---|---|
readlat.sh | Measure random-read latency at multiple block sizes (fio, QD=1) |
readbw.sh | Measure random-read bandwidth (fio, QD=64) |
findssdgcunitsize.sh | Infer the SSD's GC erase-unit size via ZNS-like probing |
testnowa.sh | Validate NoWA achieves SSD WAF = 1 on real hardware |
testnowasim.sh | Validate NoWA and ZNS patterns in the SSD simulator |
calcssdwaf.sh | Continuously sample NVMe SMART counters and compute SSD WAF |
getsmartinfo.sh | Collect raw NVMe media/host write counters |
@article{lee2026howtowrite,
title = {How to Write to SSDs},
author = {Lee, Bohyun and Ziegler, Tobias and Leis, Viktor},
journal = {Proceedings of the VLDB Endowment},
volume = {19},
year = {2026},
pages = {1469},
url = {https://www.vldb.org/pvldb/vol19/p1469-lee.pdf}
}
@misc{lee2026howtowrite_arxiv,
title = {How to Write to SSDs},
author = {Lee, Bohyun and Ziegler, Tobias and Leis, Viktor},
year = {2026},
eprint = {2603.09927},
archivePrefix = {arXiv},
primaryClass = {cs.DB}
}
19 commits
C++
55.1%
C
17.0%
Makefile
14.6%
Shell
7.1%
CMake
3.7%
Python
1.3%