Skip to main content

Overview

JDA caches Discord entities (guilds, members, channels, messages, etc.) to improve performance and reduce API calls. You can configure what gets cached to balance memory usage and functionality.

Cache Flags

Cache flags control what types of data JDA caches. Each flag can be enabled or disabled:
JDABuilder.createDefault(token)
    .enableCache(CacheFlag.VOICE_STATE, CacheFlag.EMOJI)
    .disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS)
    .build();

Available Cache Flags

FlagDescriptionRequired Intent
ACTIVITYUser activities (“Playing…”)GUILD_PRESENCES
VOICE_STATEVoice channel statesGUILD_VOICE_STATES
EMOJICustom emojisGUILD_EXPRESSIONS
STICKERCustom stickersGUILD_EXPRESSIONS
CLIENT_STATUSOnline on mobile/desktop/webGUILD_PRESENCES
MEMBER_OVERRIDESPermission overwrites per memberGUILD_MEMBERS
ROLE_TAGSRole tags (bot role, boost role, etc.)None
FORUM_TAGSForum channel tagsNone
ONLINE_STATUSUser online statusGUILD_PRESENCES
SCHEDULED_EVENTSGuild scheduled eventsSCHEDULED_EVENTS
Some cache flags require specific gateway intents. If the intent is disabled, the cache flag is automatically disabled.

Member Cache Policy

The member cache policy determines which members are cached:

Built-in Policies

// Cache no members
JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.NONE)
    .build();

// Cache all members (requires GUILD_MEMBERS intent)
JDABuilder.createDefault(token)
    .enableIntents(GatewayIntent.GUILD_MEMBERS)
    .setMemberCachePolicy(MemberCachePolicy.ALL)
    .build();

// Cache only voice members (default)
JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.VOICE)
    .build();

// Cache only online members (requires GUILD_PRESENCES)
JDABuilder.createDefault(token)
    .enableIntents(GatewayIntent.GUILD_PRESENCES)
    .setMemberCachePolicy(MemberCachePolicy.ONLINE)
    .build();

// Cache guild owner
JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.OWNER)
    .build();

// Cache boosting members
JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.BOOSTER)
    .build();

Combining Policies

// Cache voice members OR boosters
MemberCachePolicy policy = MemberCachePolicy.VOICE.or(MemberCachePolicy.BOOSTER);

JDABuilder.createDefault(token)
    .setMemberCachePolicy(policy)
    .build();

// Cache voice members AND have a specific role
MemberCachePolicy policy = MemberCachePolicy.VOICE.and(
    member -> member.getRoles().stream()
        .anyMatch(role -> role.getId().equals("123456789"))
);

Custom Policy

// Cache members with specific role
MemberCachePolicy customPolicy = member -> {
    return member.getRoles().stream()
        .anyMatch(role -> role.getName().equals("VIP"));
};

JDABuilder.createDefault(token)
    .setMemberCachePolicy(customPolicy)
    .build();

Chunking Filter

Chunking loads all members of a guild into cache. This requires the GUILD_MEMBERS intent.
// Chunk all guilds
JDABuilder.createDefault(token)
    .enableIntents(GatewayIntent.GUILD_MEMBERS)
    .setChunkingFilter(ChunkingFilter.ALL)
    .setMemberCachePolicy(MemberCachePolicy.ALL)
    .build();

// Don't chunk any guilds
JDABuilder.createDefault(token)
    .setChunkingFilter(ChunkingFilter.NONE)
    .build();

// Chunk guilds with less than 1000 members
JDABuilder.createDefault(token)
    .enableIntents(GatewayIntent.GUILD_MEMBERS)
    .setChunkingFilter(ChunkingFilter.include(1000))
    .setMemberCachePolicy(MemberCachePolicy.ALL)
    .build();
ChunkingFilter.ALL or any chunking requires the GUILD_MEMBERS privileged intent.

Configuration Examples

Lightweight Bot (Minimal Cache)

JDABuilder.createLight(token, EnumSet.of(
    GatewayIntent.GUILD_MESSAGES,
    GatewayIntent.MESSAGE_CONTENT
))
.setMemberCachePolicy(MemberCachePolicy.NONE)
.setChunkingFilter(ChunkingFilter.NONE)
.disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS, CacheFlag.ONLINE_STATUS)
.build();

Music Bot (Voice Focused)

JDABuilder.createLight(token, EnumSet.of(
    GatewayIntent.GUILD_VOICE_STATES
))
.setMemberCachePolicy(MemberCachePolicy.VOICE)
.enableCache(CacheFlag.VOICE_STATE)
.build();

Moderation Bot (Full Member Cache)

JDABuilder.createDefault(token)
    .enableIntents(GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_PRESENCES)
    .setMemberCachePolicy(MemberCachePolicy.ALL)
    .setChunkingFilter(ChunkingFilter.ALL)
    .enableCache(CacheFlag.ONLINE_STATUS, CacheFlag.ACTIVITY)
    .build();

Balanced Configuration

JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.VOICE.or(MemberCachePolicy.OWNER))
    .setChunkingFilter(ChunkingFilter.NONE)
    .enableCache(CacheFlag.VOICE_STATE, CacheFlag.EMOJI)
    .disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS)
    .build();

Accessing Cached Data

// Get cached guilds
List<Guild> guilds = jda.getGuilds();

// Get cached members (depends on cache policy)
List<Member> members = guild.getMembers();

// Get from cache or null
Member member = guild.getMemberById("123456789");

// Retrieve from API (not cache)
RestAction<Member> action = guild.retrieveMemberById("123456789");
Methods starting with get return cached data. Methods starting with retrieve make API calls.

Manual Cache Management

You can manually load members into cache:
// Load all members
guild.loadMembers().onSuccess(members -> {
    System.out.println("Loaded " + members.size() + " members");
});

// Load specific members
guild.retrieveMembersByIds("123", "456", "789").onSuccess(members -> {
    System.out.println("Retrieved " + members.size() + " members");
});

// Chunk guild (load all members)
guild.loadMembers(member -> {
    // This callback is called for each loaded member
    System.out.println("Loaded: " + member.getEffectiveName());
});

Memory Optimization

Monitor memory usage - Large bots should carefully configure caching to avoid running out of memory.
// For bots in many guilds, avoid caching all members
JDABuilder.createDefault(token)
    .setMemberCachePolicy(MemberCachePolicy.OWNER.or(MemberCachePolicy.VOICE))
    .setChunkingFilter(ChunkingFilter.NONE)
    .disableCache(
        CacheFlag.ACTIVITY,
        CacheFlag.CLIENT_STATUS,
        CacheFlag.ONLINE_STATUS
    )
    .build();

Best Practices

Start minimal - Begin with createLight() and only enable caching as needed.
Match intents to cache - Enable intents for the cache flags you want to use.
Don’t cache presence data unless necessary - GUILD_PRESENCES generates 99% of gateway traffic.

Build docs developers (and LLMs) love