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,
};

igo pings the connection every minute, whatever config.redis holds — a project replacing it whole to set its URL keeps the ping. A managed Valkey closes a connection left idle for 10 minutes, and igo flushes the cache whenever it reconnects: an instance without traffic would otherwise wipe the cache every 10 minutes, for every instance sharing the database, and log an error each time. config.redis.pingInterval changes the interval, 0 disables it.

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 null — unknown. 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.