https://github.com/golift/cache
In-memory cache Go module. High performance, integrated statistics.
https://github.com/golift/cache
cache go golang memcached memcached-server
Last synced: about 2 months ago
JSON representation
In-memory cache Go module. High performance, integrated statistics.
- Host: GitHub
- URL: https://github.com/golift/cache
- Owner: golift
- License: mit
- Created: 2022-08-04T06:17:36.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2026-04-12T23:37:34.000Z (about 2 months ago)
- Last Synced: 2026-04-13T01:21:19.066Z (about 2 months ago)
- Topics: cache, go, golang, memcached, memcached-server
- Language: Go
- Homepage:
- Size: 90.8 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cache
[](https://pkg.go.dev/golift.io/cache)
[](https://goreportcard.com/report/golift.io/cache)
[](https://github.com/golift/cache/blob/master/LICENSE)
[](https://golift.io/discord)
This module provides a small in-memory key/value cache for Go.
- **Concurrency:** Each **shard** has its own `sync.RWMutex` over a `map[string]*Item`. `Get` takes a **read** lock on that
shard; `Save`, `Update`, `Delete`, and the pruner take the **write** lock. Hit/miss and per-item access metadata use atomics
so reads do not serialize on the mutex. Shards are looked up via `sync.Map` (`uint32` index → shard), populated at startup
when `Config.Shards` is greater than 1. `List` takes read locks per shard; `Stats` aggregates atomic counters and per-shard
item counts (under contention, counter snapshots can be briefly inconsistent across fields).
- **Background work:** By default each operation uses `time.Now()` directly. If `RequestAccuracy` is set above
100ms, one goroutine also refreshes a shared clock on that interval (fewer `time.Now()` calls on hot paths).
The optional pruner runs on `PruneInterval`.
- **Metrics:** Hit/miss and other counters are exposed for `expvar` or your own metrics pipeline.
- **Sharding:** Optional `Config.Shards` (default 1) partitions keys across multiple maps using FNV-1a 64-bit `hash(key) % Shards`
(capped at 65536). Use this to reduce mutex contention under high concurrency.
Items can be marked prunable or not. Prunable entries are removed after they have not been retrieved within `PruneAfter`.
Non-prunable entries use a separate maximum idle duration (`MaxUnused`).
I wrote this to cache data from MySQL queries for an [nginx auth proxy](https://github.com/Notifiarr/mysql-auth-proxy).
It is also useful as a simple global in-process store.
## Example: basic use
```go
package main
import (
"fmt"
"golift.io/cache"
)
func main() {
c := cache.New(cache.Config{})
defer c.Stop(true)
c.Save("user:42", "Ada", cache.Options{})
item := c.Get("user:42")
if item != nil {
fmt.Println("value:", item.Data)
}
}
```
## Example: pruning and stats
```go
import (
"fmt"
"time"
"golift.io/cache"
)
func exampleStats() {
c := cache.New(cache.Config{
PruneInterval: 5 * time.Minute,
PruneAfter: 10 * time.Minute,
MaxUnused: 24 * time.Hour,
})
defer c.Stop(false)
c.Save("session:1", "opaque-token", cache.Options{Prune: true})
stats := c.Stats()
fmt.Println("hits:", stats.Hits, "size:", stats.Size)
}
```
See also the package example in [cache_test.go](cache_test.go).