Skip to content

Search a feature or API · Enter opens first result · Esc closes

Go queries, made simple.

One client. Many data types.
Shared cache, background refresh, and focused invalidation.

Get started
go get github.com/Waterkyuu/cacheq
Go 1.22+ · Zero core dependencies· MIT

Queries & conditions

Share requests, read state, and load when ready.

Query · SetEnabled · Updates

Query options

Reuse typed query definitions and share loading options.

QueryOptions · QueryDefinition

Cache & lifecycle

Reuse data, refresh in the background, and clean up.

StaleTime · GCTime · Prefetch

Automatic batch loading

Group concurrent requests or load known keys with LoadMany.

NewBatcher · LoadMany · Fetcher

Invalidation & refresh

Invalidate related data, await refreshes, and coalesce follow-ups.

Invalidate · InvalidateAndWait · RefetchAfterLoad

Query filters

Reuse query selections for refresh, cancellation, and removal.

QueryFilter · Keys · Predicate

Query tags

Declare related queries and refresh, cancel, or remove them by tag.

QueryDefinition.Tags · QueryFilter.Tags

Observability

Measure cache hits, shared requests, loads, and cleanup.

Stats

Diagnostic events

Trace load causes, shared requests, and removals by key.

SubscribeEvents · LoadID · Dropped

MCP resource caching

Share resource reads, preserve TTL, and notify on changes.

FetchWithExpiry · Invalidate · Stats

Bubble Tea example

Run a task board with shared views, refreshes, and error recovery.

Query · Updates · Invalidate

Atomic cache updates

Transform cached data without overwriting concurrent changes.

Update · ErrUpdateConflict

Mutations & synchronization

Observe writes and synchronize related queries after success.

Mutation · SyncErr · Invalidate

Execution budgets

Bound backend concurrency and queued work across consumers.

NewExecutor · MaxConcurrent · MaxQueued

One client. Different result types.

A User profile and a []User list share the same client, while keeping their types.

type User struct {
Name string
}
loadUser := func(context.Context) (User, error) {
return User{Name: "Alice"}, nil
}
loadUsers := func(context.Context) ([]User, error) {
return []User{{Name: "Alice"}}, nil
}
client := cacheq.NewClient(cacheq.Options{
StaleTime: time.Minute,
})
defer client.Close()
profile := cacheq.Query(client, "user:42", loadUser)
users := cacheq.Query(client, "users", loadUsers)
defer profile.Close()
defer users.Close()
Read the complete guide