Problem
Two internal components use a single global mutex to protect all keys, creating contention under concurrent access:
1. Memory storage
File: internal/storage/memory/memory.go:20
A single sync.RWMutex protects the entire db map[string]Entry. Every Get, Set, Delete, Reset, and Keys call contends on this one lock. When used as the storage backend for sessions, rate limiting, or CSRF, this becomes a bottleneck.
2. Idempotency locker
File: middleware/idempotency/locker.go:21-35
MemoryLock.mu is a single sync.Mutex protecting the keys map. Every Lock() and Unlock() call acquires this global lock, even for different idempotency keys.
Impact
- Memory storage: Write operations (
Set/Delete) block all reads. Noticeable at >10K concurrent requests.
- Idempotency locker: All concurrent idempotent requests with different keys serialize.
Proposed fix
Sharded map pattern (apply to both):
const numShards = 32
type shardedMap struct {
shards [numShards]struct {
mu sync.RWMutex
m map[string]entry
}
}
func (s *shardedMap) getShard(key string) *shard {
hash := fnv32(key)
return &s.shards[hash%numShards]
}
This reduces contention by ~32x with minimal memory overhead.
Priority
P1 — Matters at >10K QPS or when memory storage is the default backend.
Identified during a full performance architecture review of the Fiber codebase.
Problem
Two internal components use a single global mutex to protect all keys, creating contention under concurrent access:
1. Memory storage
File:
internal/storage/memory/memory.go:20A single
sync.RWMutexprotects the entiredb map[string]Entry. EveryGet,Set,Delete,Reset, andKeyscall contends on this one lock. When used as the storage backend for sessions, rate limiting, or CSRF, this becomes a bottleneck.2. Idempotency locker
File:
middleware/idempotency/locker.go:21-35MemoryLock.muis a singlesync.Mutexprotecting thekeysmap. EveryLock()andUnlock()call acquires this global lock, even for different idempotency keys.Impact
Set/Delete) block all reads. Noticeable at >10K concurrent requests.Proposed fix
Sharded map pattern (apply to both):
This reduces contention by ~32x with minimal memory overhead.
Priority
P1 — Matters at >10K QPS or when memory storage is the default backend.
Identified during a full performance architecture review of the Fiber codebase.