Skip to content

Cache

Igo.js uses Redis as a distributed cache.

Configuration

js
config.redis = {
  socket: {
    host: process.env.REDIS_HOST || '127.0.0.1',
    port: process.env.REDIS_PORT || 6379,
  },
  database: process.env.REDIS_DATABASE || 0,
};

Usage

js
const { cache } = require('@igojs/server');

// Store a value (with optional TTL in seconds)
await cache.put('users', 'user:123', { name: 'John' }, 3600);

// Retrieve a value
const user = await cache.get('users', 'user:123');
// => { name: 'John' } or null

// Retrieve several values of the same namespace, in one round trip
const users = await cache.mget('users', ['user:123', 'user:456']);
// => [{ name: 'John' }, 0]   missing keys come back as 0

// Fetch: get from cache, or compute and store
const data = await cache.fetch('expensive', 'result', async () => {
  return await expensiveComputation();
}, 1800);

// Delete
await cache.del('users', 'user:123');

// Increment a counter
await cache.incr('stats', 'page_views');

// Flush by pattern
await cache.flush('users/*');

// Flush everything
await cache.flushall();

API

MethodDescription
get(namespace, id)Get a cached value (returns null if not found)
mget(namespace, ids)Get several values in order (missing keys return 0)
put(namespace, id, value, timeout?)Store a value with optional TTL (seconds)
fetch(namespace, id, fn, timeout?)Get or compute and cache
del(namespace, id)Delete a cached value
incr(namespace, id)Increment a counter
flush(pattern)Delete keys matching pattern (e.g. users/*)
scan(pattern, fn)Iterate over keys matching pattern
flushdb()Flush current database
flushall()Flush all databases
info()Redis server info
isAvailable()false while Redis is disabled, unreachable or reconnecting

Availability

Redis is optional at runtime. While it is unavailable, no command throws: each one returns what it would have returned had it found or done nothing.

MethodDegraded result
getnull
mget0 for every id — its usual value for a missing key
put, flushdb, flushall, scan, flushnothing happens
del0 (no key removed)
info''
incr, incrbynull, not 0

incr is the exception: 0 is a real counter value, so a counter the caller cannot read is nullunknown. Code that gates on one (a rate limiter, a quota) has to decide what that means.

The client reconnects on its own and isAvailable() flips back without a restart — see Running without Redis.

Key Format

Keys are stored as namespace/id. For example, cache.get('users', 'user:123') reads the key users/user:123.

Serialization

Values are serialized with Node's structured clone (v8.serialize), so types survive the round trip: Date, Buffer, Map, Set and RegExp come back as themselves, falsy values are valid cache hits, functions are dropped and class instances come back as plain objects.

Two consequences:

  • stored values are binary: unreadable with redis-cli or from another language;
  • an entry that cannot be read back — written by an Igo release still using JSON, or by a Node version using another format — is a cache miss and gets rewritten, rather than served with degraded types. Counters written by incr / incrby are plain integers, so a codec change never invalidates them.

Released under the ISC license.