Caching Discord without lying to ourselves
Why Orbit caches channels and guilds aggressively, but treats permission-sensitive member roles very differently.
Discord data creates an awkward engineering choice. Fetch everything live and the dashboard becomes slow, fragile, and unnecessarily expensive. Cache everything and eventually somebody keeps a permission they should have lost. The answer is not one cache duration. The answer is deciding what kind of truth each feature needs.
Three layers of truth
- The database stores durable Discord snapshots for cold starts and cross-process reuse.
- Redis serves hot data with short, purpose-specific lifetimes.
- Gateway events update or invalidate member, role, channel, and guild state as Discord changes.
Lists can be fast and still user-controlled
Channels, roles, guild summaries, and member-search results are safe to reuse for normal editing flows. Every guild workspace therefore exposes a manual Discord refresh. Triggering it invalidates the shared Discord cache and refreshes active selectors together. Member search also has a local reload action for the moment you need to find somebody who joined ten seconds ago.
The rules we use
- Cache data according to its risk, not according to one global timer.
- Use gateway events to keep snapshots warm between reads.
- Provide a visible reload action wherever a cached Discord list affects editing.
- Prefer current data for authorization.
- Use stale data only as an explicit resilience path, never as unquestioned truth.
Caching is not the opposite of correctness. Invisible caching with no invalidation strategy is. The useful version makes routine pages fast, protects Discord from needless calls, and gets out of the way when a decision has security consequences.