https://github.com/jeffotoni/benchmark-gocache
Benchmark Caches - gocache v1, v2..v9, freecache, go-cache
https://github.com/jeffotoni/benchmark-gocache
benchamark benchmarking benchmarks go go-cache golang
Last synced: 28 days ago
JSON representation
Benchmark Caches - gocache v1, v2..v9, freecache, go-cache
- Host: GitHub
- URL: https://github.com/jeffotoni/benchmark-gocache
- Owner: jeffotoni
- License: mit
- Created: 2025-02-28T04:19:53.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-07T20:53:41.000Z (about 1 year ago)
- Last Synced: 2025-06-08T16:03:16.655Z (about 1 year ago)
- Topics: benchamark, benchmarking, benchmarks, go, go-cache, golang
- Language: Go
- Homepage: https://goquick.run
- Size: 27.3 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://github.com/jeffotoni/benchmark-gocache/blob/main/LICENSE)



# 🚀💕 Benchmarks for Go In-Memory Caches
This repository provides a comprehensive benchmark suite comparing **nine custom cache implementations** from [`jeffotoni/gocache`](https://github.com/jeffotoni/gocache) (versions `v1` through `v9`), plus two well-known open-source libraries:
- [`patrickmn/go-cache`](https://github.com/patrickmn/go-cache)
- [`coocood/freecache`](https://github.com/coocood/freecache)
All tests are run on an **Apple M3 Max** machine (Darwin/arm64) to measure both **1-second** and **3-second** benchmark performance (`-benchtime=1s` and `-benchtime=3s`).
## Why Use an In-Memory Cache?
- **Faster Access**: In-memory caches reduce latency by storing frequently accessed data directly in memory, avoiding repeated database or external service calls.
- **Reduced Load**: Caching lowers the workload on databases and APIs, improving overall system throughput.
- **Quick Expiration**: In-memory caches are best for *ephemeral* data where occasional staleness is tolerable, and items can expire quickly.
## Cache Implementations Tested
We benchmarked nine versions from [`jeffotoni/gocache`](https://github.com/jeffotoni/gocache), each using different concurrency strategies, expiration approaches, and internal data structures. Additionally, we tested:
- **`go-cache`**: [patrickmn/go-cache](https://github.com/patrickmn/go-cache)
- **`freecache`**: [coocood/freecache](https://github.com/coocood/freecache)
Below is a snippet showing how the caches are instantiated in our benchmarking suite:
```go
var cacheV1 = v1.New(10 * time.Minute)
var cacheV2 = v2.New[string, int](10*time.Minute, 0)
var cacheV3 = v3.New(10*time.Minute, 1*time.Minute)
var cacheV4 = v4.New(10 * time.Minute)
var cacheV5 = v5.New(10 * time.Minute)
var cacheV6 = v6.New(10 * time.Minute)
var cacheV7 = v7.New(10 * time.Minute)
var cacheV8 = v8.New(10*time.Minute, 8)
var cacheV9 = v9.New(10 * time.Minute)
// Third-party libraries
var cacheGoCache = gocache.New(10*time.Second, 1*time.Minute)
var fcacheSize = 100 * 1024 * 1024 // 100MB cache
var cacheFreeCache = freecache.NewCache(fcacheSize)
```
Each version of gocache implements different optimizations (locking, sharding, ring buffers, etc.) to analyze performance trade-offs.
Example Benchmark Function
Below is an example benchmark test used for Version 1 (v1), focusing on both Set() and Get():
```go
//The result wiil BenchmarkGcacheSet1(b *testing.B)
func BenchmarkGcacheSet1(b *testing.B) {
for i := 0; i < b.N; i++ {
key := strconv.Itoa(i)
cacheV1.Set(key, i, time.Duration(time.Minute))
}
}
//The result wiil BenchmarkGcacheSetGet1(b *testing.B)
func BenchmarkGcacheSetGet1(b *testing.B) {
for i := 0; i < b.N; i++ {
key := strconv.Itoa(i)
cacheV1.Set(key, i, 10*time.Minute)
i, ok := cacheV1.Get(key)
if !ok {
log.Printf("Not Found %v", i)
}
}
}
...
```
Note: Similar benchmark functions are repeated for v2 through v9, plus go-cache and freecache.
## Benchmark de Cache em Go
**Architecture:** Apple M3 Max (arm64)
**Package:** `benchmark-gocache`
```sh
$ go test -bench=. -benchtime=5s -benchmem
```
# 📊 Go Cache Benchmark Comparison Freecache, Ristretto, Bigcache and Go-cache
This benchmark compares several Go in-memory caching libraries using `go test -bench` on an Apple M3 Max (arm64) CPU.
Each implementation is tested for raw **Set** performance and **Set/Get** combined performance.
The values reflect **nanoseconds per operation**, **allocations**, and **bytes per op** under high concurrency (`GOMAXPROCS=16`).
---
| **Implementation** | **Set Ops** | **Set ns/op** | **Set/Get Ops** | **Set/Get ns/op** | **Observations** |
|------------------------|------------------|----------------|------------------|--------------------|--------------------------------------------------|
| **gocache V1** | 28,414,197 | 338.6 ns/op | 22,687,808 | 294.9 ns/op | Baseline version — decent speed, moderate allocs |
| **gocache V8** | 26,022,742 | 364.5 ns/op | 15,105,789 | 393.6 ns/op | High memory cost, TTL enabled |
| **gocache V9** | 44,026,141 | 265.4 ns/op | 23,528,972 | 270.0 ns/op | 🏆 **Fastest write throughput** |
| **gocache V10** | 19,749,439 | 393.2 ns/op | 16,217,510 | 495.9 ns/op | ❌ Higher allocation and latency |
| **gocache V11 (Short)**| 39,719,458 | 264.2 ns/op | 23,308,189 | 265.4 ns/op | ⚡ Short TTL — very fast overall |
| **gocache V11 (Long)** | 22,334,095 | 348.8 ns/op | 18,338,124 | 319.7 ns/op | Balanced long TTL setup |
| **go-cache** | 25,669,981 | 392.5 ns/op | 20,485,022 | 306.0 ns/op | Stable, but slower than newer gocache versions |
| **freecache** | 41,543,706 | 380.3 ns/op | 14,433,577 | 425.2 ns/op | 🚀 Fast writes, significantly slower reads |
| **ristretto** | 30,257,541 | 352.3 ns/op | 10,055,701 | 547.8 ns/op | 🧠 TinyLFU eviction, high allocation per op |
| **bigcache** | 30,260,250 | 320.6 ns/op | 14,382,721 | 354.6 ns/op | 🔥 Very consistent, low GC overhead |
---
### 🧠 Notes:
- `gocache` is a custom in-memory cache optimized for concurrency, modularity, and optional TTL.
- `freecache`, `go-cache`, `bigcache`, and `ristretto` are popular open-source libraries with different focuses (size control, expiration, LFU, etc).
- **Set/Get** benchmarks include an immediate `Get()` call after each `Set()`.
- Allocation and GC behavior differ drastically across libraries, especially with TTL and internal eviction mechanisms.
---
## 🚀 1-Second Benchmarks
```sh
$ go test -bench=. -benchtime=1s
```
| **Implementation** | **Set Ops** | **Set ns/op** | **Set/Get Ops** | **Set/Get ns/op** | **Observations** |
|--------------------|----------------|---------------|-----------------|-------------------|---------------------------------------|
| **gocache V1** | 6,459,714 | 259.4 ns/op | 5,062,861 | 245.0 ns/op | Fast reads, decent writes |
| **gocache V2** | 6,597,314 | 239.5 ns/op | 4,175,704 | 280.4 ns/op | Good write speed, average read |
| **gocache V3** | 7,094,665 | 259.7 ns/op | 4,746,934 | 281.6 ns/op | Balanced performance |
| **gocache V4** | 4,644,594 | 324.4 ns/op | 3,571,759 | 330.9 ns/op | ❌ Slower (sync.Map) |
| **gocache V5** | 6,311,216 | 252.6 ns/op | 4,714,106 | 278.7 ns/op | Solid all-around |
| **gocache V6** | 7,532,767 | 262.6 ns/op | 4,865,896 | 256.2 ns/op | 🔥 Great concurrency |
| **gocache V7** | 8,026,825 | 222.4 ns/op | 4,978,083 | 244.3 ns/op | 🏆 **Best write** (1s), fast reads |
| **gocache V8** | 4,708,249 | 309.3 ns/op | 2,513,566 | 399.7 ns/op | ❌ Slower overall |
| **gocache V9** | 9,295,434 | 215.9 ns/op | 5,096,511 | 272.7 ns/op | 🏆 **Fastest write** (lowest ns/op) |
| **go-cache** | 6,463,236 | 291.6 ns/op | 4,698,109 | 290.7 ns/op | Solid library, slower than V7/V9 |
| **freecache** | 5,803,242 | 351.1 ns/op | 2,183,834 | 469.7 ns/op | 🚀 Decent writes, poor reads |
## 🚀 3-Second Benchmarks
```sh
$ go test -bench=. -benchtime=3s
```
| **Implementation** | **Set Ops** | **Set ns/op** | **Get Ops** | **Get ns/op** | **Observations** |
|--------------------|-----------------|---------------|-----------------|---------------|--------------------------------------|
| **gocache V1** | 17,176,026 | 338.5 ns/op | 13,891,083 | 268.6 ns/op | Fast read, solid write |
| **gocache V2** | 16,457,449 | 318.5 ns/op | 12,379,336 | 304.4 ns/op | Good write speed, average read |
| **gocache V3** | 20,858,042 | 310.8 ns/op | 14,042,400 | 287.1 ns/op | Balanced, efficient |
| **gocache V4** | 15,255,268 | 422.4 ns/op | 8,882,214 | 406.3 ns/op | ❌ Slow (sync.Map) |
| **gocache V5** | 20,500,326 | 348.9 ns/op | 12,597,715 | 271.7 ns/op | Good balance |
| **gocache V6** | 21,767,736 | 341.4 ns/op | 13,085,462 | 297.3 ns/op | 🔥 Strong concurrency |
| **gocache V7** | 27,229,544 | 252.4 ns/op | 14,574,768 | 268.6 ns/op | 🏆 **Best write** (3s) |
| **gocache V8** | 15,796,894 | 383.5 ns/op | 8,927,028 | 408.8 ns/op | ❌ Slower overall |
| **gocache V9** | 24,809,947 | 252.1 ns/op | 13,225,228 | 275.7 ns/op | 🏆 **Very fast write**, good read |
| **go-cache** | 15,594,752 | 375.4 ns/op | 14,289,182 | 269.7 ns/op | 🚀 Excellent reads, slower writes |
| **freecache** | 13,303,050 | 402.3 ns/op | 8,903,779 | 421.4 ns/op | ❌ Decent write, slow read |
## 🏅 Benchmark Icons Guide
These icons indicate key **performance insights** from our benchmarks:
- 🏆 **Top Performance** → Best result in a specific category (fastest read/write).
- ❌ **Underperformance** → Notably slower compared to other implementations.
- 🔥 **Balanced & Scalable** → Strong concurrency, optimized trade-offs.
- 🚀 **High Speed** → Impressive performance, but not always the absolute fastest.
💡 Use these indicators to **quickly identify the strengths and weaknesses** of each cache version!
## 🚀 Key Highlights
✅ **Best Write Performance**:
- 🏆 **V7 and V9** consistently deliver the **fastest writes** (`lowest ns/op` in Set benchmarks).
- **V9** achieves top speeds while maintaining strong read performance.
✅ **Best Read Performance**:
- **V1 and go-cache** often provide **the lowest `ns/op` in Get benchmarks**, making them excellent choices for read-heavy workloads.
- **go-cache** remains a strong competitor in retrieval speed.
⚠️ **Slower Performance Observed**:
- ❌ **V4 (`sync.Map`) and V8** struggle in both read and write speeds, making them less suitable for high-performance applications.
- **freecache** performs well in **writes** but has significantly **slower read speeds**.
🔥 **Overall, V7 and V9 stand out as the best-balanced options for both write speed and retrieval performance!**
## ⚖️ Overall Trade-Offs
Every cache implementation has **its own strengths and weaknesses**:
✅ **Optimized for Reads** → Some caches prioritize fast retrieval speeds.
🚀 **High Write Throughput** → Others are designed to handle massive insertions efficiently.
🔥 **Balanced Performance** → **V7 and V9** strike a great balance between **read and write speeds**.
💡 **Choosing the right cache depends on your workload needs!**
---
## 🤝 Contributing
Want to **enhance this benchmark suite**? Follow these simple steps:
1️⃣ **Fork this repo** and add your own cache tests or custom versions.
2️⃣ **Submit a Pull Request (PR)** with your improvements or questions.
3️⃣ **Join the discussion** by opening an issue to suggest new features or optimizations.
Your contributions are always welcome! 🚀✨
---
## 🔗 Related Projects
This benchmark compares the following caching solutions:
✅ [**jeffotoni/gocache**](https://github.com/jeffotoni/gocache) – Custom high-performance cache versions (V1–V9).
✅ [**patrickmn/go-cache**](https://github.com/patrickmn/go-cache) – Lightweight in-memory cache with expiration.
✅ [**coocood/freecache**](https://github.com/coocood/freecache) – High-speed cache optimized for low GC overhead.
📌 If you know another cache worth benchmarking, feel free to suggest it!
---
## 📜 License
This project is **open-source** under the **MIT License**.
💡 Feel free to **fork, modify, and experiment** with these benchmarks in your own applications or libraries.
🔬 The goal is to **help developers choose the best in-memory cache** for their needs.
🚀 **Happy benchmarking!**