Caching

Limits, identity-preserving snapshots, sweeps, and how guild/channel caches stay aligned.

The client keeps structures in memory so you do not REST-fetch everything on every event. Managers are the day-to-day API; client.cache exposes limits, stats, and sweeps.

Mental model

CacheAccessNotes
Guildsclient.guildsREADY / GUILD_CREATE upserts
Channelsclient.channels and guild.channelsSame object, two indexes
Usersclient.usersShared across guilds
Membersguild.membersPer guild; partial snapshots merge only
Roles / emojis / stickersguild.roles / .emojis / .stickersPer guild
Messagesper-channel maps via gateway handlersBounded; FIFO when full

Deleting or FIFO-evicting a guild removes its channels from the global index and clears those channels’ message caches. Users are not mass-deleted (they are shared).

Configuring limits

Defaults (DEFAULT_CACHE_LIMITS):

BucketDefault
guilds200
users10_000
channels5_000
messages50 (per channel)
members5_000 (per guild)
roles / emojis / stickersunbounded (0)

Semantics:

ValueMeaning
positive numberMax entries (FIFO on insert of a new key)
0 or InfinityUnbounded
false (messages only)Message cache disabled
javascript
import { Client } from '@fluxerjs/core';

const client = new Client({
  cache: {
    guilds: 100,
    channels: 2_000,
    messages: 20,       // per channel
    // messages: false, // disable message caching
    roles: 500,         // optional per-guild caps
  },
});

client.cache.limits; // resolved numbers (`Infinity` when unbounded)

Breaking clarification: cache.messages: 0 is now unbounded (same as other buckets). Pass messages: false to turn message caching off. Passing 0 emits a one-time warning.

Get / fetch / resolve / force

  • get — cache only; undefined if missing
  • fetch — REST, then update cache
  • resolve — get, else fetch (when the manager supports it)
  • forceguilds.fetch(id, { force: true }) re-fetches and _patches metadata in place (nested caches kept)
javascript
const cached = client.guilds.get(guildId);
const guild = cached ?? (await client.guilds.fetch(guildId));
await client.guilds.fetch(guildId, { force: true });

const member =
  guild.members.get(userId) ?? (await guild.members.resolve(userId));

Identity and patching

READY and available GUILD_CREATE reuse cached Guild / Channel / Role / emoji / sticker instances when the id (and channel type) match. Nested collections are synced with prune for roles/channels/emojis/stickers; members are merge-only (partial lists are common).

References stay valid across reconnects and outage recovery unless:

  • the channel type changes (instance is replaced)
  • the guild/channel is FIFO-evicted or permanently deleted
  • you call client.destroy()

*Update events still provide an old snapshot when something was cached.

Sweeps and stats

javascript
client.cache.stats();
// { guilds, channels, users, members, messages, messageChannels, roles, emojis, stickers }

client.cache.sweepMessages((msg) => Date.now() - Date.parse(msg.timestamp) > 3_600_000);
client.cache.sweepMembers((member, guildId) => member.id !== client.user.id);
client.cache.sweepUsers();
client.cache.sweepChannels((ch) => !('guildId' in ch));
client.cache.sweepGuilds((g) => !g.available);

Aliases kept for compatibility: client.sweepMessages, client.sweepMembers, client.users.sweep, guild.members.sweep.

See examples/cache-bot.js for a runnable long-running pattern.

Reconnect / unavailable

  • RESUMED — cache is kept as-is
  • Identify READY — guilds upsert in place (same object identity when still cached)
  • Unavailable (GUILD_DELETE with unavailable: true) — guild stays cached with available === false; the next available GUILD_CREATE recovers the same guild instance and syncs nested caches
  • Permanent GUILD_DELETE — guild removed; channels + message caches cascade away

When to fetch anyway

Fetch when correctness beats a round trip: bans, messages older than the per-channel cap, or roles/channels after an outage if the recovery snapshot omitted them. For “is this user in the server right now,” fetchMember beats a stale cache.

Troubleshooting

SymptomCheck
Memory keeps growingLower limits; periodic sweepMessages / sweepMembers; confirm messages is not 0 if you meant “off” (false)
“Orphan” channels after leaving a guildPermanent delete and FIFO eviction cascade; if you only marked unavailable, channels stay on purpose
Channel missing from guild.channels but present on client.channelsShould not happen after sync — report if you see it; both indexes are written together
Held Guild reference looks stale after reconnectConfirm you did not hit FIFO eviction; identity is preserved only while the guild remains cached