Caching libraries Benchmarks

September 5, 2026 ยท View on GitHub

According to my new library cachebox, I decided to benchmark caching libraries which are I know, to show the power of cachebox ...

If you know other library, tell me to add it to this page.

Note


The cacheing.VTTLCache class was excluded from the benchmark because assigning a key raises TypeError.

Methodology

Times are from Python: each sample is a calibrated inner loop around a single API call (set / get / delete / popitem). Setup and teardown are not timed. GC is collected before each sample and disabled during the timed region.

Reported values are the median ns/op (tables ranked by median), plus mean, stdev, MAD, ops/sec, sample count, and coefficient of variation. Outliers are not dropped. A result is flagged when CV > 10% or max > 1.5ร— mean.

All implementations use the same working set (maxsize = 4096, integer keys/values). TTL caches are constructed with a 3600s TTL so nothing expires during a sample. dict, cachebox.Cache, and cachetools.Cache have no eviction policy and are skipped on eviction cases.

CaseWhat is measured
Set new (no eviction)Insert keys that are not present and do not evict (cache ~25% full).
Set at capacity (eviction)Insert new keys into a cache already at maxsize.
Lookup existingget of a present key (LRU/LFU recency/frequency updates included).
Lookup missingget of a missing key.
DeletionDelete present keys (one delete per populated key, then a new cache).
Popitempopitem() on a cache filled to maxsize.
Hash collisionget of keys whose hash() is always 42.

moka-py is a concurrent Rust cache measured single-threaded like the others.

๐Ÿ–ฅ๏ธ System Information

  • Platform: Linux-7.2.3-arch1-2-x86_64-with-glibc2.44
  • Python: 3.14.7
  • Processor: 11th Gen Intel(R) Core(TM) i3-1115G4 @ 3.00GHz
  • Timer: resolution 652.0 ns, overhead 42.0 ns
  • Run: min-time 100 ms/sample, warmup 1, samples 25, isolated=no, fast=no, pin-cpu=off, nice=False
  • Hash seed: unset (isolated workers use 0 except the collision case)
  • GC: disabled during the timed loop; collected before each sample
  • Threading: single-threaded (including moka-py)
  • Libraries:
    • cachebox: 6.2.7
    • cachetools: 7.1.8
    • cacheing: 0.1.1
    • lru-dict: 1.4.1
    • moka-py: 0.5.0

๐Ÿ“Š Set new (no eviction)

Insert keys that do not exist and do not trigger eviction. Cache is pre-filled to 25% of maxsize.

set_new

  • Range: 42.9ร— between fastest and slowest (median)
  • Best: dict (70 ns, 14.1M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
dict69.671.14.20.514.1M255.8%
cachebox.Cache86.787.44.00.911.4M2004.5%
cachebox.RRCache93.294.38.40.910.6M2008.9%
cachebox.FIFOCache94.095.17.80.910.5M2008.2%
cachebox.LRUCache126.6127.22.61.47.9M2002.0%
cachebox.LFUCache128.4129.23.71.27.7M2002.9%
cachebox.TTLCache139.8140.22.11.17.1M2001.5%
lru.LRU157.7158.88.81.36.3M2005.5%
cacheing.RandomCache285.1290.433.91.73.4M20011.7%
cachetools.Cache293.4297.514.81.83.4M2005.0%
cacheing.LRUCache322.0323.04.61.53.1M2001.4%
cacheing.LFUCache324.7328.815.81.93.0M2004.8%
moka_py.Moka396.5397.912.02.22.5M2003.0%
cachetools.LFUCache400.4402.56.61.72.5M2001.6%
moka_py.Moka (lru)403.4405.110.02.22.5M2002.5%
cachetools.FIFOCache407.6409.111.42.32.4M2002.8%
cachetools.RRCache412.6420.729.62.62.4M2007.0%
cachetools.LRUCache606.0617.224.45.61.6M2004.0%
cacheing.TTLCache988.8994.621.67.41.0M2002.2%
cachetools.TTLCache1,118.81,129.983.75.10.9M2007.4%
cachebox.VTTLCache2,987.53,020.8298.72.70.3M2009.9%

๐Ÿ“Š Set at capacity (eviction)

Insert new keys into a cache already at maxsize so each set evicts an entry.

set_evict

  • Range: 49.7ร— between fastest and slowest (median)
  • Best: cachebox.LRUCache (105 ns, 9.5M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
cachebox.LRUCache104.5105.03.11.39.5M2002.9%
cachebox.FIFOCache108.4110.212.01.09.1M20010.9%
cachebox.TTLCache152.1152.95.71.06.5M2003.7%
lru.LRU185.1185.32.21.15.4M2001.2%
cacheing.LRUCache572.2579.722.33.71.7M2003.8%
moka_py.Moka676.0685.427.66.11.5M2004.0%
cacheing.LFUCache732.7739.622.77.61.4M2003.1%
moka_py.Moka (lru)748.2752.521.43.41.3M2002.8%
cachetools.FIFOCache899.1902.214.53.01.1M1861.6%
cacheing.RandomCache993.21,010.269.76.71.0M1676.9%
cachetools.RRCache1,209.71,224.046.127.20.8M1363.8%
cachebox.RRCache1,243.31,321.6299.48.40.8M20022.7%
cachetools.LRUCache1,258.71,285.274.59.00.8M1405.8%
cacheing.TTLCache1,392.01,402.827.911.70.7M1242.0%
cachetools.LFUCache2,544.22,563.949.717.80.4M1351.9%
cachetools.TTLCache3,116.03,140.357.626.70.3M831.8%
cachebox.LFUCache4,024.03,977.898.497.10.3M1002.5%
cachebox.VTTLCache5,193.45,140.3149.893.60.2M862.9%

Skipped: dict (no eviction policy), cachebox.Cache (no eviction policy), cachetools.Cache (no eviction policy)

๐Ÿ“Š Lookup existing

Look up keys that are in the cache. LRU/LFU recency or frequency updates are part of the API cost.

get_hit

  • Range: 12.4ร— between fastest and slowest (median)
  • Best: dict (80 ns, 12.5M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
dict79.880.10.70.212.5M250.9%
cachebox.RRCache86.186.20.40.211.6M250.4%
cachebox.Cache87.287.20.30.211.5M250.4%
cachebox.LFUCache90.691.01.60.211.0M251.8%
cachebox.FIFOCache91.591.91.20.310.9M251.3%
cachebox.LRUCache93.794.01.30.610.6M251.4%
cacheing.RandomCache106.0106.41.10.49.4M251.0%
cachebox.VTTLCache118.2118.40.80.28.4M250.6%
cachebox.TTLCache123.3123.81.90.48.1M251.5%
lru.LRU128.9129.00.60.27.8M250.4%
cachetools.Cache168.9169.31.40.45.9M250.8%
cachetools.RRCache169.0169.31.00.45.9M250.6%
cachetools.FIFOCache169.4170.12.20.35.9M251.3%
cacheing.LRUCache197.7198.43.00.55.0M251.5%
moka_py.Moka (lru)231.8233.55.20.24.3M252.2%
moka_py.Moka240.5241.52.60.24.1M251.1%
cachetools.LRUCache337.6341.58.30.32.9M252.4%
cacheing.LFUCache365.1364.76.63.22.7M251.8%
cachetools.LFUCache444.0446.34.31.32.2M251.0%
cacheing.TTLCache700.5702.94.31.31.4M250.6%
cachetools.TTLCache991.6992.97.82.21.0M250.8%

๐Ÿ“Š Lookup missing

Look up keys that are not in a populated cache (mapping.get with default None).

get_miss

  • Range: 20.7ร— between fastest and slowest (median)
  • Best: dict (82 ns, 12.2M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
dict81.781.91.10.312.2M251.3%
cachetools.LFUCache131.6131.60.90.57.6M250.7%
cachetools.RRCache131.6133.12.80.57.5M252.1%
cachetools.LRUCache133.3134.52.30.97.4M251.7%
cachetools.Cache133.6134.82.21.17.4M251.6%
cachetools.FIFOCache135.1135.22.10.47.4M251.6%
moka_py.Moka (lru)174.7175.03.23.05.7M251.8%
moka_py.Moka186.5185.64.23.25.4M252.3%
lru.LRU199.8201.75.70.65.0M252.8%
cacheing.RandomCache493.3495.39.73.62.0M252.0%
cacheing.LFUCache577.7581.011.02.41.7M251.9%
cachetools.TTLCache676.0676.010.75.11.5M251.6%
cacheing.LRUCache697.7700.88.80.61.4M251.2%
cachebox.RRCache1,082.51,088.816.56.40.9M251.5%
cachebox.Cache1,087.81,092.613.42.80.9M251.2%
cachebox.VTTLCache1,166.01,171.412.12.20.9M251.0%
cachebox.LRUCache1,175.51,180.610.84.80.8M250.9%
cachebox.LFUCache1,180.31,183.08.04.00.8M250.7%
cachebox.TTLCache1,332.61,339.215.83.80.7M251.2%
cachebox.FIFOCache1,349.41,354.09.63.50.7M250.7%
cacheing.TTLCache1,687.71,689.529.914.30.6M251.8%

๐Ÿ“Š Deletion

Delete keys that exist. Each sample populates maxsize entries and deletes them once.

delete

  • Range: 9.7ร— between fastest and slowest (median)
  • Best: dict (69 ns, 14.5M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
dict68.969.21.70.614.5M2002.5%
cachebox.Cache73.774.46.40.813.4M2008.6%
cachebox.RRCache74.776.08.00.913.2M20010.6%
cachebox.FIFOCache83.283.41.50.712.0M2001.8%
cachebox.LRUCache87.687.82.21.011.4M2002.5%
cachebox.LFUCache97.298.59.90.810.2M20010.1%
lru.LRU105.6106.14.40.89.4M2004.1%
cachebox.TTLCache107.4107.71.90.89.3M2001.8%
cachebox.VTTLCache117.8118.63.81.08.4M1563.2%
cachetools.Cache168.2168.42.00.85.9M2001.2%
cacheing.LRUCache217.8220.620.20.94.5M2009.2%
cachetools.FIFOCache260.3262.312.00.93.8M2004.6%
cachetools.LRUCache260.5261.25.70.83.8M2002.2%
cachetools.LFUCache290.4292.312.00.93.4M2004.1%
cacheing.LFUCache300.5303.824.11.33.3M2007.9%
cacheing.RandomCache331.8338.516.71.73.0M2004.9%
cachetools.RRCache344.7346.311.81.32.9M2003.4%
cachetools.TTLCache559.6561.37.51.41.8M2001.3%
cacheing.TTLCache573.8582.940.74.61.7M2007.0%
moka_py.Moka (lru)662.7664.710.02.01.5M1211.5%
moka_py.Moka667.2685.163.06.41.5M2009.2%

๐Ÿ“Š Popitem

Call popitem() on a cache filled to maxsize (the eviction primitive).

popitem

  • Range: 23.5ร— between fastest and slowest (median)
  • Best: cachebox.FIFOCache (85 ns, 11.7M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
cachebox.FIFOCache84.985.55.91.211.7M2006.9%
cachebox.TTLCache94.995.98.21.210.4M2008.5%
cachebox.LRUCache95.996.12.10.910.4M2002.1%
cachebox.LFUCache97.499.312.01.210.1M20012.1%
cachebox.VTTLCache108.9110.99.41.49.0M1768.5%
lru.LRU129.8130.35.40.97.7M2004.1%
cacheing.LRUCache230.0230.97.41.24.3M2003.2%
cacheing.TTLCache343.5347.256.42.82.9M20016.2%
cacheing.LFUCache348.6351.014.01.92.8M2004.0%
cachetools.FIFOCache493.7497.115.01.92.0M2003.0%
cacheing.RandomCache637.3660.249.613.11.5M1417.5%
cachetools.LRUCache650.1658.240.52.31.5M2006.2%
cachebox.RRCache703.8712.239.47.51.4M2005.5%
cachetools.RRCache727.7740.463.26.71.4M1728.5%
cachetools.TTLCache1,786.91,812.969.324.80.6M1223.8%
cachetools.LFUCache1,995.12,010.265.833.90.5M1963.3%

Skipped: dict (no eviction policy), cachebox.Cache (no eviction policy), cachetools.Cache (no eviction policy), moka_py.Moka (no popitem), moka_py.Moka (lru) (no popitem)

๐Ÿ“Š Hash collision

Look up keys that all hash to the same value (hash() == 42).

collision

  • Range: 6.9ร— between fastest and slowest (median)
  • Best: cachebox.RRCache (1010 ns, 1.0M ops/sec)
ImplementationMedian (ns)Mean (ns)StdevMADOps/secSamplesCV
cachebox.RRCache1,009.81,018.317.38.11.0M251.7%
cachebox.Cache1,021.11,020.820.512.21.0M252.0%
cachebox.LFUCache1,048.91,056.216.710.70.9M251.6%
cachebox.VTTLCache1,068.91,063.318.210.00.9M251.7%
cachebox.LRUCache1,076.51,068.321.57.80.9M252.0%
cacheing.RandomCache1,179.21,184.915.00.70.8M251.3%
dict1,179.31,173.320.018.50.9M251.7%
cachebox.FIFOCache1,203.01,195.023.517.90.8M252.0%
cachebox.TTLCache1,217.71,216.117.818.20.8M251.5%
lru.LRU1,248.01,239.218.914.80.8M251.5%
moka_py.Moka2,040.42,042.36.92.00.5M250.3%
moka_py.Moka (lru)2,047.22,048.99.61.50.5M250.5%
cachetools.FIFOCache2,320.32,338.735.73.00.4M251.5%
cachetools.RRCache2,323.92,336.423.37.50.4M251.0%
cachetools.Cache2,324.72,335.825.55.40.4M251.1%
cacheing.LRUCache2,366.32,387.033.211.60.4M251.4%
cacheing.TTLCache2,928.72,921.844.242.20.3M251.5%
cachetools.LRUCache4,698.14,730.957.314.10.2M251.2%
cacheing.LFUCache5,303.05,337.763.813.20.2M251.2%
cachetools.TTLCache5,367.85,413.993.65.10.2M251.7%
cachetools.LFUCache6,987.77,029.077.38.90.1M251.1%

๐Ÿš€ Usage

Prerequisites

uv sync

Run Benchmarks

# All cases (in-process)
python -m cachebox_benchmark

# One or more cases
python -m cachebox_benchmark get_hit delete

# Faster iteration (not for published numbers)
python -m cachebox_benchmark --fast

# One subprocess per (case, implementation)
python -m cachebox_benchmark --isolated

# JSON + regenerate README from a previous run
python -m cachebox_benchmark --json results.json
python -m cachebox_benchmark --report-only results.json

Optional host knobs (off by default): --pin-cpu 0, --nice.

Understanding Results

  • Median (ns): robust typical cost per operation; tables are sorted by this.
  • Mean / Stdev / MAD: distribution; MAD is median absolute deviation.
  • Ops/sec: throughput from the mean.
  • CV: stdev / mean. High CV means the number is noisy, not that the library is โ€œbadโ€.