Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
T

ttlcache

> 编程语言
Open source

An in-memory cache with item expiration and generics

1.3K stars0 likes0 views
WebsiteGitHub

About

An in-memory cache with item expiration and generics

TTLCache - an in-memory cache with item expiration and generics

Features

  • Simple API built with type parameters (generics)
  • Per-item or cache-wide TTL with automatic deletion of expired items
  • Automatic expiration time extension on each Get call (can be disabled)
  • Loader interface that may be used to load/lazily initialize missing cache items, with optional duplicate call suppression
  • Capacity limits based on the number of items or their custom-calculated cost
  • Event handlers (insertion, update, and eviction)
  • Metrics
  • Thread safety

Installation

go get github.com/jellydator/ttlcache/v3

Usage

All cache operations are provided by the Cache type, which represents a single in-memory data store. To create a new instance of it, the ttlcache.New() function needs to be called:

go
func main() {
	cache := ttlcache.New[string, string]()
}

By default, items never expire and are never removed automatically. Expiration is enabled by setting a default TTL with the ttlcache.WithTTL() option and starting the automatic cleanup process with the cache.Start() method. Since cache.Start() blocks until cache.Stop() is called, it is usually launched on a separate goroutine:

go
func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
	)

	go cache.Start() // starts automatic expired item deletion
	defer cache.Stop()
}

Automatic cleanup suits most applications, but some may need to control the exact timing of expired item deletion. For example, a system may want to delete such items only when its resource load is at its lowest (e.g., after midnight, when the number of users/HTTP requests drops). In cases like these, the cache.DeleteExpired() method can be called periodically instead of starting the cleanup process:

go
func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
	)

	for {
		time.Sleep(4 * time.Hour)
		cache.DeleteExpired()
	}
}

The data stored in the cache can be inserted, retrieved, checked, and deleted with Set, Get, Has, Delete, and other related methods. Each new item receives a TTL: a specific duration, ttlcache.DefaultTTL to use the cache's default one, or ttlcache.NoTTL to never expire:

…

The cache.OnInsertion(), cache.OnUpdate(), and cache.OnEviction() methods subscribe to the cache's events. The subscribed functions are executed on separate goroutines, so they never block the cache's operations, and each subscription method returns a function that can be called to unsubscribe:

…

A custom or existing implementation of the ttlcache.Loader interface can be used to load or lazily initialize data on cache misses. The Get method calls the loader whenever the requested item is not found and returns whatever the loader returns:

go
func main() {
	loader := ttlcache.LoaderFunc[string, string](
		func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
			// load from file/make an HTTP request
			item := c.Set(key, "value from file", ttlcache.DefaultTTL)
			return item
		},
	)
	cache := ttlcache.New[string, string](
		ttlcache.WithLoader[string, string](loader),
	)

	item := cache.Get("key from file")
}

When multiple goroutines request the same missing item at once, the loader normally runs once for each of them. Wrapping it with ttlcache.NewSuppressedLoader() ensures that only one load operation is in-flight for a given key at a time, with all callers receiving its result:

go
func main() {
	loader := ttlcache.LoaderFunc[string, string](
		func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
			// load from file/make an HTTP request
			item := c.Set(key, "value from file", ttlcache.DefaultTTL)
			return item
		},
	)
	cache := ttlcache.New[string, string](
		ttlcache.WithLoader[string, string](ttlcache.NewSuppressedLoader(loader, nil)),
	)

	item := cache.Get("key from file")
}

The cache's capacity can also be restricted by criteria other than the number of items. The ttlcache.WithMaxCost() option assigns each item a cost, calculated by a custom function, and evicts the least recently used items whenever the total cost exceeds the given limit. The following example limits the memory used by cached entries to ~5KiB:

go
func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 {
			// Note: the calculation below does not include the memory
			// used by the internal structures or the string metadata of
			// the key and the value.
			return uint64(len(item.Key) + len(item.Value))
		}),
	)

	cache.Set("first", "value1", ttlcache.DefaultTTL)
}

Examples

See the examples directory for complete applications demonstrating how to use ttlcache.

Projects using TTLCache

Below is a list of some well-known projects that use ttlcache:

  • TiDB: An open-source, cloud-native, distributed SQL database designed for high availability, scalability, and strong consistency.
  • HashiCorp Vault: A tool for secrets management, encryption as a service, and privileged access management.
  • File Browser: A file managing interface that can be used to upload, delete, preview and edit files within a specified directory.
  • Tailscale: The easiest, most secure way to use WireGuard and 2FA.
  • authentik: An open-source Identity Provider (IdP) for modern SSO.
  • Navidrome: Your personal streaming service.
  • LiveKit: An end-to-end realtime stack for connecting humans and AI.
  • Owncast: A self-hosted live video streaming and chat server.
  • OpenTelemetry Collector Contrib: The contrib repository for the OpenTelemetry Collector.
  • Datadog Agent: The main repository for the Datadog Agent.
  • Erigon: An Ethereum implementation on the efficiency frontier.
  • Microsoft Retina: An eBPF distributed networking observability tool for Kubernetes.
  • ByteDance Elkeid: An open-source security solution for hosts, containers, K8s, and serverless workloads.
  • Polygon Bor: The official Go implementation of the Polygon blockchain.
  • Azure Service Operator: A Kubernetes operator that allows Azure resources to be created using kubectl.

...and thousands more.

License

MIT

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Gocachegenericsgolangttl-cache

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言