alepha@docs:~/docs/guides/persistence$
cat 5-caching.md
3 min read
Last commit:

#Caching

$cache provides a caching system with two modes: automatic function result caching and manual key-value store operations. In-memory by default, with Redis support for distributed environments.

typescript
1import { $cache } from "alepha/cache";

#Function Result Caching

Define a cache with a handler function. The return value is automatically cached based on the input arguments.

typescript
 1import { $cache } from "alepha/cache"; 2  3class UserService { 4  getUserData = $cache({ 5    name: "user-data", 6    ttl: [10, "minutes"], 7    handler: async (userId: string) => { 8      return await this.repo.findById(userId); 9    },10  });11}

Call it like a regular function. The first call executes the handler and caches the result. Subsequent calls with the same arguments return the cached value until the TTL expires.

typescript
1const user = await this.getUserData("some-uuid");

The cache key is derived from the function arguments by default (via JSON.stringify). If the handler throws an error, the result is not cached.

#Manual Store Operations

Omit the handler to use the cache as a manual key-value store.

typescript
 1class SessionService { 2  sessions = $cache({ name: "sessions", ttl: [1, "hour"] }); 3  4  async store(id: string, data: any) { 5    await this.sessions.set(id, data); 6  } 7  8  async get(id: string) { 9    return await this.sessions.get(id);10  }11 12  async clear(id: string) {13    await this.sessions.invalidate(id);14  }15}

#Options

Option Type Default Description
name string ClassName:propertyKey Cache namespace. Keys are stored as cache:<name>:<key>
handler Function - Function whose results are cached automatically
ttl DurationLike [300, "seconds"] (5 min) Time-to-live. Set 0 to disable expiration
key Function JSON.stringify(args) Custom key generator from handler arguments
provider Class or "memory" Injected CacheProvider Override the cache backend
compress boolean false Enable gzip compression (60-80% size reduction)
disabled boolean false Disable caching entirely

#TTL Format

TTL accepts a DurationLike tuple: [amount, unit].

typescript
1ttl: [30, "seconds"]2ttl: [10, "minutes"]3ttl: [1, "hour"]4ttl: [7, "days"]

The default TTL is 5 minutes (300 seconds). This can be overridden globally via the CACHE_DEFAULT_TTL environment variable (in seconds).

#Methods

#run

Execute the handler function with caching. This is what gets called when you invoke the cache as a function. Only available when a handler is defined.

typescript
1const result = await this.getUserData("some-uuid");2// equivalent to:3const result = await this.getUserData.run("some-uuid");

#get

Retrieve a cached value by key. Returns undefined if the key does not exist or has expired.

typescript
1const value = await this.sessions.get("session-123");

#set

Store a value in the cache with an optional TTL override.

typescript
1await this.sessions.set("session-123", sessionData);2await this.sessions.set("session-123", sessionData, [30, "minutes"]);

#invalidate

Remove one or more keys from the cache. Supports pattern-based invalidation with a trailing wildcard *.

typescript
1// Invalidate a specific key2await this.sessions.invalidate("session-123");3 4// Invalidate multiple keys5await this.sessions.invalidate("session-123", "session-456");6 7// Pattern-based invalidation: delete all keys starting with "user:"8await this.cache.invalidate("user:*");

Calling invalidate() with no arguments deletes all entries in the cache's namespace.

#incr

Atomically increment a numeric value. If the key does not exist, it is set to 0 before incrementing.

typescript
1const newCount = await this.counter.incr("page-views", 1);

#key

Get the cache key that would be generated for the given arguments (useful for debugging).

typescript
1const cacheKey = this.getUserData.key("some-uuid");

#Custom Key Generation

Override the default key derivation:

typescript
1getUserData = $cache({2  name: "user-data",3  ttl: [10, "minutes"],4  key: (userId: string) => `user:${userId}`,5  handler: async (userId: string) => {6    return await this.repo.findById(userId);7  },8});

#Compression

Enable gzip compression for cached values to reduce storage size. Useful for large JSON payloads.

typescript
1largeData = $cache({2  name: "large-data",3  ttl: [1, "hour"],4  compress: true,5  handler: async () => {6    return await this.repo.findMany({});7  },8});

Compression adds CPU overhead but reduces storage by 60-80% for typical JSON data.

#Redis Backend

By default, caching uses in-memory storage (MemoryCacheProvider). For distributed caching across multiple instances, switch to Redis.

#Module Registration

typescript
1import { AlephaCacheRedis } from "alepha/cache/redis";2 3const alepha = Alepha.create().with(AlephaCacheRedis);

AlephaCacheRedis automatically registers RedisCacheProvider as the CacheProvider implementation and includes the base AlephaCache module.

#Direct Provider Override

typescript
1import { AlephaCache, CacheProvider } from "alepha/cache";2import { RedisCacheProvider } from "alepha/cache/redis";3 4const alepha = Alepha.create()5  .with(AlephaCache)6  .with({ provide: CacheProvider, use: RedisCacheProvider });

#Redis Key Prefix

Set REDIS_CACHE_PREFIX in your environment to add a prefix to all Redis cache keys. Useful for multi-tenant applications or isolating test environments.

#Environment Variables

Variable Type Default Description
CACHE_ENABLED boolean true Enable or disable all caching globally
CACHE_DEFAULT_TTL number 300 Default TTL in seconds
REDIS_CACHE_PREFIX string - Prefix for all Redis cache keys

#Serialization

The cache automatically handles serialization:

  • JSON values: Serialized with JSON.stringify / JSON.parse
  • Strings: Stored as raw UTF-8
  • Uint8Array: Stored as raw binary

The serialization format is detected automatically during deserialization based on a type byte prefix.