Skip to content

Add shared Discord member cache for dashboard/server endpoints #27

Description

@Destinea

Problem

Some server endpoints need fresh Discord member identity data (username, display_name, avatar_url) to render dashboard views such as tickets.

The current tickets/open fallback resolves missing identities with live Discord member lookups (GET /guilds/{guild.id}/members/{user.id}) during the request. On a server with 95 tickets / 64 unique users missing identity, that makes the endpoint take ~17s locally.

Recent profiling on GET /v2/server/923764211845312533/tickets/open shows:

  • total_ms=17377
  • discord_ms=15819
  • open_tickets_ms=845
  • links_ms=215
  • players_ms=396
  • auth_users_ms=98
  • missing_identity_users=64
  • discord_lookup_attempted=64
  • discord_lookup_succeeded=42

This confirms the bottleneck is not Mongo; it is the repeated live Discord member lookups. Even when done concurrently in Go, the Discord client buckets this route, so requests are effectively serialized.

Why not store identity on ticket creation?

We explicitly do not want to persist discord_username, discord_display_name, or discord_avatar_url as the source of truth on ticket creation because those fields can change over time.

We still want:

  • fresh member info when available,
  • Not on server when the user is no longer in the guild,
  • and no per-request burst of dozens of Discord member REST calls.

Proposed solution

Add a shared external Discord member cache backed by Valkey so both the bot and the API/dashboard can use the same member identity source.

High-level idea:

  1. The bot hydrates and maintains guild member identity in Valkey (startup + ongoing updates from member events).
  2. The API reads from that shared cache for ticket/link/other server endpoints.
  3. API falls back gracefully when a member is absent from cache (e.g. short-lived stale/miss strategy), without turning every dashboard request into dozens of live Discord REST calls.
  4. Cache negative lookups for short periods as well so repeated Unknown Member users do not hammer Discord.

Potential implementation direction:

  • key shape like discord:guild_member:{guild_id}:{user_id}
  • fields: user_id, guild_id, username, display_name, avatar_url, nick, fetched_at
  • optional short-lived negative cache for not-on-server users
  • API should prefer cache over live Discord lookup for read endpoints
  • bot becomes the main producer/updater of member cache

Useful reference

disgo supports custom/external cache approaches; see example:

Expected outcome

Endpoints like tickets/open should stop spending ~15s+ in Discord member lookup fallback and instead return quickly while still showing current user info (or Not on server when appropriate).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions