Choosing Gateway Intents and Partials in Discord.js: A Decision Guide for Memory and Latency
Discord.js bots often fail from misconfigured Gateway intents or partials. Learn how to choose a subset of intents with partials to balance memory, latency, and rate limits.
08 Sept 2025, 03:06 UTC

The Decision: Subset Intents Plus Partials
A Discord.js bot that stops responding to commands or exhausts memory often traces back to how Gateway intents and partials are configured. Intents tell Discord which event categories to send over the gateway connection. Partials tell the client to accept incomplete data structures and fetch details later. Choosing the wrong combination either starves the bot of events or forces it to cache unnecessary payloads.
The useful takeaway: for most bots, enabling a subset of intents—typically Guilds, GuildMessages, and GuildMembers—combined with partials for messages, channels, and members provides the best balance of functionality, memory use, and latency.
Constraints That Drive the Choice
Before picking a strategy, define what the bot must do and where it runs.
- Memory ceiling: Does the bot run in a container with limited RAM?
- Event scope: Does it need member presence, message content, or only guild-level metadata?
- Rate limit tolerance: Can the bot tolerate extra REST calls to fetch partial objects?
- Privileged intent access: Has the application been verified in the Developer Portal for presence or member data?
Comparing Supported Strategies
The following table summarizes common configurations. "All intents" means every non-privileged intent plus the privileged ones your application is approved for.
| Strategy | Intents | Partials | Memory Impact | Latency | Primary Risk |
|---|---|---|---|---|---|
| All intents, no partials | All available | None | High | Low | Memory exhaustion; large payloads |
| All intents, with partials | All available | Message, Channel, GuildMember | Medium | Medium | Excessive REST fetches |
| Subset + partials | Guilds, GuildMessages, GuildMembers | Message, Channel, GuildMember | Low | Medium | Missing events if an intent is omitted |
| Presence + partials | Guilds, GuildPresences | User, GuildMember | Low | Medium | Presence updates only; no message events |
Trade-offs Between Bandwidth, Memory, and API Calls
Intents control the volume of data Discord pushes to your bot. Enabling all intents increases payload size and can trigger gateway rate limits. Partials reduce memory by storing only identifiers (snowflakes) instead of full objects, but every property access on a partial triggers a REST API call. Those calls share the same rate limits as other endpoints, so aggressive fetching can lead to temporary bans.
Misconfiguration is a common failure mode. If you omit an intent, Discord simply does not send those events. The bot appears to crash or hang because event handlers never fire. Conversely, enabling privileged intents without portal approval causes the gateway connection to fail.
Implementation: Subset Intents with Partials
The following Discord.js v14 configuration enables a subset of intents and partials. Run this in your bot's main entry file, for example index.js. No special operating system permissions are required, but the bot token must belong to an application with the corresponding intents enabled in the Developer Portal.
const { Client, GatewayIntentBits, Partials } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers
],
partials: [
Partials.Message,
Partials.Channel,
Partials.GuildMember
]
});
client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}`);
});
client.on('messageCreate', async (message) => {
if (message.partial) {
message = await message.fetch();
}
console.log(`Received message from ${message.author?.tag ?? 'unknown user'}`);
});
client.login('YOUR_BOT_TOKEN');
Replace YOUR_BOT_TOKEN with your actual token. The message.partial check prevents errors when the message object is incomplete. If you need message content, add GatewayIntentBits.MessageContent to the intents array and request verification in the Developer Portal. Note that GuildMembers and MessageContent are privileged intents; Discord will not deliver those events until your application is approved.
Validating the Configuration
Confirm the bitmask before launching. Create a temporary file named check-intents.js in your project root and run it with Node.js using node check-intents.js. No Discord permissions are needed for this local check.
const { GatewayIntentBits } = require('discord.js');
const selected = [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers
];
const bitmask = selected.reduce((mask, intent) => mask | intent, 0);
console.log('Computed intent bitmask:', bitmask);
Expected check: the script prints a single integer. Compare it against the value shown in the Developer Portal under Bot > Privileged Gateway Intents. If the numbers differ, your runtime configuration does not match the portal settings.
To measure event behavior, log the messageCreate count and approximate payload size in a test guild. Enable only GuildMessages and observe whether messages arrive. Then toggle GuildMembers in the portal and confirm member-related events begin firing.
Limitations and Runtime Checks
Partial objects are transient. A fetched member or message may be evicted from cache, so code must handle missing properties gracefully. Avoid caching every partial indefinitely.
Rate limits apply to both gateway and REST endpoints. Excessive fetch() calls on partials can result in temporary bans. Use the client's cache before falling back to network requests.
If the bot receives no events, verify three things: the intents array in ClientOptions, the toggle switches in the Developer Portal, and that the bot has been re-invited with the correct scopes if permissions changed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.