Skip to content
 
 

Repository files navigation

DialCache

npm version crates.io PyPI version TypeScript coverage Go coverage Rust coverage Python coverage OpenSSF Scorecard

Read the shared behavior guides with a language selector for TypeScript, Go, Rust and Python. Native examples in those guides are imported from source files that CI executes.

TypeScript is the reference implementation. Go, Rust, and Python are experimental. The Python asyncio guide covers its native decorator API, request scopes, and checkout installation.

DialCache organizes caching into use cases, with runtime control and observability for each one. Its TypeScript, Go, Rust and Python implementations share behavioral contracts and documentation.

  • Off by default: caching runs only inside an enable() scope.
  • Multi-layer: request-local → process-local → Redis.
  • Runtime policies per use case: layers, TTLs, and rollout ramps.
  • Targeted invalidation: one call per entity for its tracked Redis results.
  • Coalescing: same-key reads share work when a cache layer is active.
  • Fail-open: cache failures fall back to the loader.
  • Stale-on-error (opt-in): retained Redis values for selected source errors.
  • Shadow validation (opt-in): cache coherence checks through sampling.
  • Observability: Prometheus and Datadog metrics, including miss reasons.

Documentation · Getting started · API reference

Language Implementation Native guide
TypeScript typescript/ — reference implementation TypeScript and npm
Go go/ — experimental Go guide
Rust rust/ — experimental Rust guide · crates.io
Python python/ — experimental Python guide · PyPI

Shared contracts and portable test histories live in formal/. Run repository validation from the root; see the maintainer guide.

Install TypeScript

npm install dialcache

Requires Node.js 22.15.0 or newer within 22.x, or 23.8.0 and newer, for node:zlib zstd support. Use a supported LTS release in production. Install a Redis or Valkey client and a metrics client when using those integrations.

Usage

import { CacheLayer, DialCache, DialCacheKeyConfig } from "dialcache";

const dialcache = new DialCache();

// The loader: the database or service read.
async function fetchUser(userId: string) {
  console.log("Loading from source:", userId);
  return { id: userId, name: "Ada" };
}

// Register once; use getUser at read sites.
const getUser = dialcache.cached(fetchUser, {
  keyType: "user_id", // Entity kind; groups tracked results by id.
  useCase: "GetUser", // Operation name; part of the key and metric labels.
  cacheKey: (userId) => userId, // Include every input that changes the result.
  defaultConfig: new DialCacheKeyConfig({
    ttlSec: { [CacheLayer.LOCAL]: 60 },
  }),
});

// In a service, wrap each request's reads in one enable() call.
await dialcache.enable(async () => {
  await getUser("123"); // Loads from source and caches the result.
  await getUser("123"); // Reuses the value for up to 60 seconds.
});

await getUser("123"); // Outside enable(): loads from source again.

Results containing Date, bigint, or other non-JSON-compatible values need an explicit typed serializer, even when caching only in memory. Cached objects are shared references; copy before modifying.

getOrLoad() provides the same cache path for an inline loader and a direct key.

How reads work

Wrap each request's reads in one enable() call. Use disable() for nested mutation work; it restores pass-through behavior without evicting anything. Within an enabled call, the first active layer with a hit returns the value:

request-local → process-local → Redis / Valkey → loader
Layer Shared across Lifetime
Request-local Calls in one outer enable() scope Until that scope settles
Process-local Requests using one DialCache instance Insertion TTL, bounded by LRU capacity
Remote Instances sharing the Redis keyspace Physical TTL and logical age checks; optional watermarks

Local hits bypass Redis, including its invalidation checks. A Redis hit can warm an active local layer. Concurrent calls share work when a cache layer is active; set coalesce: false when callers need independent execution. How DialCache works covers the read path, publication rules, and freshness boundaries.

Runtime control

An operation's defaultConfig is its baseline. A cacheConfigProvider overrides individual policy fields for each enabled call. Ramps select stable cohorts of keys: raising a ramp adds keys, while lowering it removes keys without reshuffling the rest. A 10% key cohort need not account for 10% of traffic.

Policy changes apply to new invocations. They do not evict values or cancel work already admitted. Shadow validation has an independent ramp and compares sampled Redis values with the source in the background. It can also fill misses while remote serving is ramped down; callers do not wait for shadow checks or fills.

See Configuration and rollout for precedence and runtime examples, and Shadow validation for sampling and comparison behavior.

Documentation

Topic Guide
First reader and enabled scope Getting started
Result identity and invalidation groups Keys and identity
Defaults, overrides, and policy changes Configuration and rollout
Watermarks and mutation handling Targeted invalidation
Recovery from selected source failures Stale-on-error
Shared execution and deadlines Coalescing and liveness
Methods, options, and exports API reference
Native implementations and shared behavior contracts TypeScript guide · Go guide · Rust guide · Python guide · Quint specification · Worked walkthrough

The Go, Rust, and Python ports and the TypeScript library replay the same Quint-generated histories. Whether those histories reach every required boundary is decided by one language-neutral evaluator, node formal/witnesses.mjs evaluate, that any port runs over the same corpus; no port depends on another port's test suite for its completion evidence.

The documentation index also links to client setup, observability, upgrades, and the maintainer guide. Everything is readable as Markdown on GitHub.

MIT licensed. See LICENSE.

About

Safe, observable and feature rich read through caching

Topics

Resources

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages