Skip to content

Fix getKeys() iterable to return the keys and not objects of keys#186

Merged
cb1kenobi merged 2 commits intomainfrom
fix-getkeys
Oct 21, 2025
Merged

Fix getKeys() iterable to return the keys and not objects of keys#186
cb1kenobi merged 2 commits intomainfrom
fix-getkeys

Conversation

@cb1kenobi
Copy link
Copy Markdown
Contributor

@cb1kenobi cb1kenobi commented Oct 20, 2025

getKeys() iterable is supposed to produce strings, not objects. Whoops.

@cb1kenobi cb1kenobi requested a review from a team October 20, 2025 14:49
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Oct 20, 2025

📊 Benchmark Results

encoding.bench.ts

Key encoding > ordered-binary keys - strings (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 24.43K ops/sec 40.93 36.06 664.376 1.14 12,216
🥈 rocksdb 2 4.60K ops/sec 217.218 201.995 1,595.12 0.861 2,302

Key encoding > ordered-binary keys - numbers (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 26.71K ops/sec 37.43 33.33 394.204 0.959 13,357
🥈 rocksdb 2 4.86K ops/sec 205.877 194.317 641.835 0.351 2,429

Key encoding > ordered-binary keys - mixed types (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 24.55K ops/sec 40.74 36.24 396.559 1.01 12,274
🥈 rocksdb 2 4.76K ops/sec 209.904 196.082 789.246 0.448 2,383

Value encoding > msgpack values - strings (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 16.03K ops/sec 62.40 55.92 473.935 1.18 8,013
🥈 rocksdb 2 4.40K ops/sec 227.443 214.176 831.845 0.491 2,199

Value encoding > msgpack values - numbers (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 25.70K ops/sec 38.92 34.68 461.069 0.956 12,848
🥈 rocksdb 2 4.73K ops/sec 211.436 192.47 3,895.353 2.07 2,365

Value encoding > msgpack values - arrays (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 9.22K ops/sec 108.443 97.15 748.338 1.48 4,611
🥈 rocksdb 2 3.45K ops/sec 289.512 269.251 986.645 0.573 1,728

Value encoding > msgpack values - small objects (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 5.86K ops/sec 170.591 150.435 1,097.632 1.91 2,931
🥈 rocksdb 2 2.63K ops/sec 379.734 353.223 822.394 0.576 1,317

Value encoding > msgpack values - large objects (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 625.36 ops/sec 1,599.083 1,480.218 9,567.428 3.72 313
🥈 rocksdb 2 611.21 ops/sec 1,636.11 1,492.337 3,405.986 2.00 306

get-sync.bench.ts

getSync() > random keys - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 20.40K ops/sec 49.02 41.90 3,327.434 1.76 10,200
🥈 rocksdb 2 4.36K ops/sec 229.472 198.528 11,422.945 6.31 2,179

get.bench.ts

get() > rocksdb - random vs sequential keys (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 sequential 1 3.86K ops/sec 259.324 242.769 1,183.939 0.600 1,929
🥈 random 2 3.83K ops/sec 261.31 239.607 1,103.085 0.793 1,914

get() > random keys - max 1978 lmdb key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 3.07K ops/sec 326.051 291.991 2,205.555 2.19 1,534

get() > rocksdb - async vs sync

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 sync 1 4.36K ops/sec 229.375 212.445 3,356.365 1.70 2,180
🥈 async 2 3.54K ops/sec 282.124 266.275 1,051.135 0.529 1,773

put-sync.bench.ts

putSync() > random keys - insert - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.17K ops/sec 460.915 440.542 652.877 0.227 1,085
🥈 lmdb 2 4.22 ops/sec 236,878.325 227,050.197 259,182.432 2.61 10.00

putSync() > random keys - update - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.12K ops/sec 471.194 432.898 594.033 0.172 1,062
🥈 lmdb 2 4.10 ops/sec 244,014.472 233,715.94 270,149.559 3.40 10.00

putSync() > random keys - insert - max 1978 lmdb key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 970.71 ops/sec 1,030.177 893.019 1,635.268 0.686 486
🥈 lmdb 2 3.89 ops/sec 257,281.698 247,519.156 272,674.533 3.06 10.00

putSync() > random keys - update - max 1978 lmdb key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 964.95 ops/sec 1,036.323 909.139 1,754.909 0.560 483
🥈 lmdb 2 3.89 ops/sec 257,150.063 246,836.795 276,285.19 3.51 10.00

putSync() > sequential keys - insert (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.12K ops/sec 471.331 430.191 2,752.661 0.911 1,061
🥈 lmdb 2 4.15 ops/sec 240,796.666 209,939.569 265,252.477 4.36 10.00

putSync() > put 100KB value (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 51.01 ops/sec 19,605.197 17,666.966 21,040.225 1.88 26.00
🥈 lmdb 2 2.66 ops/sec 375,783.231 367,987.794 384,364.284 1.13 10.00

putSync() > put 1MB value (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 5.25 ops/sec 190,387.671 183,202.005 205,563.842 2.41 10.00
🥈 lmdb 2 1.72 ops/sec 581,909.951 534,481.984 619,105.53 3.45 10.00

putSync() > get 10MB value (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 0.28 ops/sec 3,560,157.845 3,031,280.381 3,836,937.545 5.91 10.00
🥈 rocksdb 2 0.17 ops/sec 5,893,862.762 2,159,493.581 10,039,414.047 25.97 10.00

put.bench.ts

put > small dataset (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 1.93K ops/sec 519.4 492.467 832.561 0.331 963
🥈 lmdb 2 3.80 ops/sec 263,111.56 234,279.75 288,052.274 3.49 10.00

put > async vs sync overhead

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 sync 1 2.05K ops/sec 487.819 462.542 618.834 0.164 1,025
🥈 async 2 1.88K ops/sec 530.942 497.405 876.073 0.284 942

ranges.bench.ts

getRange() > small range (100 records, 50 range)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 23.87K ops/sec 41.89 37.42 985.444 1.13 11,936
🥈 rocksdb 2 2.91K ops/sec 343.419 298.701 2,142.615 2.58 1,456

getRange() > full scan vs range scan

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb range scan 1 21.55K ops/sec 46.40 40.42 656.542 1.14 10,776
🥈 lmdb full scan 2 11.96K ops/sec 83.63 75.76 773.62 1.40 5,979
🥉 rocksdb range scan 3 2.96K ops/sec 338.362 299.366 1,810.93 1.86 1,478
rocksdb full scan 4 1.61K ops/sec 621.685 553.621 3,665.82 2.83 805

getKeys() > keys only (100 records, 50 range)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 53.53K ops/sec 18.68 16.68 3,009.81 1.92 26,768
🥈 rocksdb 2 4.64K ops/sec 215.452 190.802 1,108.056 1.18 2,321

Reverse iteration > reverse range (100 records, 50 range)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 511.54K ops/sec 1.95 1.26 6,357.042 7.23 258,042
🥈 rocksdb 2 2.76K ops/sec 362.955 325.642 1,998.676 1.68 1,378

Reverse iteration > rocksdb - reverse vs forward

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 forward 1 3.08K ops/sec 324.383 298.698 1,220.309 1.48 1,542
🥈 reverse 2 2.83K ops/sec 353.343 320.61 2,901.313 2.17 1,416

Range query patterns > prefix scan performance

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 30.64K ops/sec 32.64 28.68 1,235.076 1.14 15,319
🥈 rocksdb 2 3.36K ops/sec 297.382 271.861 1,636.366 1.46 1,682

Sparse data patterns > sparse - range over gaps

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 58.41K ops/sec 17.12 14.82 1,620.25 1.43 29,204
🥈 rocksdb 2 6.03K ops/sec 165.772 148.085 1,160.928 1.10 3,017

Sparse data patterns > sparse - prefix with gaps

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 125.03K ops/sec 8.00 6.66 3,394.91 2.63 62,514
🥈 rocksdb 2 12.32K ops/sec 81.15 71.71 3,185.452 1.52 6,162

remove-sync.bench.ts

removeSync() > random keys - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 12.49K ops/sec 80.08 68.58 854.747 1.80 6,244
🥈 rocksdb 2 2.54K ops/sec 394.461 377.884 532.619 0.197 1,268

removeSync() > sequential keys - small key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 12.63K ops/sec 79.18 68.44 719.62 1.38 6,315
🥈 rocksdb 2 2.60K ops/sec 384.103 357.854 521.779 0.136 1,302

removeSync() > rocksdb - random vs sequential keys (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 sequential 1 2.59K ops/sec 386.8 367.242 617.825 0.176 1,293
🥈 random 2 2.56K ops/sec 390.208 364.017 598.379 0.202 1,282

removeSync() > random keys - max 1978 lmdb key size (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 9.79K ops/sec 102.16 87.23 1,654.909 2.59 4,895
🥈 rocksdb 2 1.06K ops/sec 945.405 824.532 1,232.71 0.462 529

removeSync() > random access pattern (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 12.16K ops/sec 82.27 72.46 600.847 1.29 6,078
🥈 rocksdb 2 2.60K ops/sec 383.986 358.728 812.061 0.247 1,303

removeSync() > non-existent keys (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 12.80K ops/sec 78.14 73.65 306.45 0.338 6,399
🥈 rocksdb 2 2.58K ops/sec 388.206 366.708 475.179 0.162 1,288

transaction-sync.bench.ts

transaction sync > optimistic > simple put operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 584.17 ops/sec 1,711.832 1,616.831 4,283.697 1.49 293
🥈 lmdb 2 4.24 ops/sec 235,654.691 231,042.373 255,399.249 2.20 10.00

transaction sync > optimistic > batch operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.89K ops/sec 346.55 307.212 1,983.239 0.916 1,443
🥈 lmdb 2 333.07 ops/sec 3,002.352 2,285.656 6,109.536 3.37 167

transaction sync > optimistic > read-write operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 353.45 ops/sec 2,829.244 2,541.746 4,727.25 1.72 177
🥈 lmdb 2 4.12 ops/sec 242,443.235 230,595.202 262,801.895 3.56 10.00

transaction sync > optimistic > concurrent non-conflicting operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 549.56 ops/sec 1,819.651 1,709.761 3,302.888 1.21 275
🥈 lmdb 2 4.22 ops/sec 236,807.251 228,745.365 256,374.733 3.15 10.00

transaction sync > optimistic > rollback operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 16.12K ops/sec 62.04 59.61 339.749 0.375 8,060
🥈 rocksdb 2 5.66K ops/sec 176.826 168.112 453.611 0.231 2,828

transaction sync > optimistic > rocksdb - large transaction vs many small

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.95K ops/sec 338.861 301.733 488.715 0.228 1,476
🥈 rocksdb 2 596.58 ops/sec 1,676.214 1,620.895 3,902.996 0.899 299

transaction sync > optimistic > lmdb - large transaction vs many small

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 365.25 ops/sec 2,737.859 2,147.885 5,882.354 1.83 183
🥈 lmdb 2 4.26 ops/sec 234,682.603 222,327.901 281,642.314 5.17 10.00

transaction sync > optimistic > empty transaction overhead

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 758.56K ops/sec 1.32 1.17 1,566.777 0.660 379,282
🥈 rocksdb 2 92.79K ops/sec 10.78 9.67 1,975.266 1.11 46,397

transaction sync > optimistic > transaction with only reads (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 1.54K ops/sec 649.468 589.972 4,270.948 3.35 770
🥈 rocksdb 2 263.98 ops/sec 3,788.155 3,538.19 10,887.1 3.77 132

transaction sync > pessimistic > simple put operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 539.44 ops/sec 1,853.771 1,809.849 2,177.908 0.278 270
🥈 lmdb 2 4.28 ops/sec 233,694.152 228,482.707 256,467.722 2.52 10.00

transaction.bench.ts

transaction > optimistic > simple put operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 328.19 ops/sec 3,047 2,718.643 5,993.655 2.97 165
🥈 lmdb 2 3.50 ops/sec 285,662.045 276,254.473 303,704.988 2.79 10.00

transaction > optimistic > batch operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.19K ops/sec 456.007 414.427 607.19 0.283 1,097
🥈 lmdb 2 286.30 ops/sec 3,492.833 2,267.988 9,199.35 4.30 144

transaction > optimistic > read-write operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 213.83 ops/sec 4,676.63 4,094.617 8,094.003 2.98 107
🥈 lmdb 2 3.46 ops/sec 288,829.983 259,986.698 332,705.895 4.81 10.00

transaction > optimistic > concurrent non-conflicting operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 936.43 ops/sec 1,067.886 951.893 3,858.036 3.24 469
🥈 lmdb 2 283.47 ops/sec 3,527.666 2,326.66 8,424.451 3.22 142

transaction > optimistic > rollback operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 4.51K ops/sec 221.687 208.462 810.424 0.491 2,256
🥈 lmdb 2 296.27 ops/sec 3,375.329 3,112.256 6,343.265 1.36 149

transaction > optimistic > rocksdb - large transaction vs many small

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 2.17K ops/sec 461.746 387.5 729.795 0.296 1,083
🥈 rocksdb 2 307.61 ops/sec 3,250.869 2,772.416 8,610.178 4.90 154

transaction > optimistic > lmdb - large transaction vs many small

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 288.14 ops/sec 3,470.556 3,148.011 9,153.963 4.46 145
🥈 lmdb 2 3.67 ops/sec 272,435.547 261,566.805 280,857.805 1.69 10.00

transaction > optimistic > empty transaction overhead

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 42.04K ops/sec 23.79 18.69 368.13 0.360 21,021
🥈 rocksdb 2 35.51K ops/sec 28.16 20.75 4,274.271 2.59 17,756

transaction > optimistic > transaction with only reads (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 330.56 ops/sec 3,025.13 2,682.738 20,536.988 8.12 166
🥈 rocksdb 2 148.92 ops/sec 6,715.066 5,093.514 15,025.579 5.73 75.00

transaction > pessimistic > simple put operations (100 records)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 54.51 ops/sec 18,344.186 16,514.953 18,948.716 1.46 28.00
🥈 lmdb 2 3.61 ops/sec 276,687.698 247,727.371 300,428.972 3.83 10.00

worker-get-sync.bench.ts

Worker > random keys - small key size (100 records, 1 worker)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 14.39K ops/sec 69.49 58.25 6,776.86 3.18 7,196
🥈 rocksdb 2 3.59K ops/sec 278.253 227.813 1,921.117 1.12 1,797

Worker > random keys - small key size (100 records, 2 workers)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 14.34K ops/sec 69.75 60.24 7,606.443 3.53 7,169
🥈 rocksdb 2 3.64K ops/sec 274.45 245.494 1,863.644 1.32 1,822

Worker > random keys - small key size (100 records, 10 workers)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 lmdb 1 7.53K ops/sec 132.754 118.718 6,631.06 2.59 3,767
🥈 rocksdb 2 1.68K ops/sec 596.097 513.707 3,304.61 1.58 839

worker-put-sync.bench.ts

putSync() > random keys - small key size (100 records, 1 worker)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 1.76K ops/sec 569.24 499.368 3,899.028 1.52 879
🥈 lmdb 2 4.09 ops/sec 244,657.445 232,643.793 267,504.503 3.34 10.00

putSync() > random keys - small key size (100 records, 2 workers)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 1.37K ops/sec 729.309 666.426 3,268.223 1.07 686
🥈 lmdb 2 2.17 ops/sec 461,696.72 427,475.869 498,792.987 2.94 10.00

putSync() > random keys - small key size (100 records, 10 workers)

Implementation Rank Operations/sec Mean (ms) Min (ms) Max (ms) RME (%) Samples
🥇 rocksdb 1 790.76 ops/sec 1,264.605 1,165.938 5,063.618 1.77 396
🥈 lmdb 2 1.14 ops/sec 880,461.027 799,927.23 1,003,428.547 5.94 10.00

Results from commit 565b00a

Copy link
Copy Markdown
Member

@kriszyp kriszyp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@cb1kenobi cb1kenobi merged commit b2db7e5 into main Oct 21, 2025
21 checks passed
@cb1kenobi cb1kenobi deleted the fix-getkeys branch October 21, 2025 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants