Guide

How to reduce discord.js memory usage

discord.js trades memory for convenience: it remembers a great deal so your code does not have to fetch it. For most bots, much of that memory holds things they never use.

← All guides2 min readUpdated

Measure first

Before changing anything, find out what the bot actually uses and whether it grows. process.memoryUsage() reports two useful numbers: rss, the total the process holds, which is what a memory limit is measured against, and heapUsed, the part your JavaScript objects occupy.

Log both every few minutes for a day. Memory that rises after startup and levels off is caches filling up, and the rest of this guide shrinks it. Memory that rises steadily and never levels off is a leak, covered at the end.

index.js

const mb = (bytes) => Math.round(bytes / 1024 / 1024);

setInterval(() => {
    const { rss, heapUsed } = process.memoryUsage();
    console.log(`memory: rss ${mb(rss)} heap ${mb(heapUsed)}`);
}, 5 * 60 * 1000);

Ask for fewer intents

Intents decide which events Discord sends your bot, and discord.js caches much of what it receives. The two that cost the most are Server Members and Presences: in large servers they mean holding every member and every status change.

A bot that only answers slash commands needs just the Guilds intent. Go through the intents your client requests and remove each one no handler depends on; the intents calculator shows what each one delivers.

Limit the caches

discord.js lets you cap each cache, or switch it off, when you create the client. Messages and presences are the usual candidates: most bots never look at an old message and never read a status. Sweepers go further, clearing entries on a timer so caches cannot grow for the lifetime of the process.

Only limit what you do not use. A cache set to zero means the data has to be fetched when you do need it, and code that assumed it was cached — reading guild.members.cache, for instance — will quietly find it empty.

discord.js

const { Client, GatewayIntentBits, Options } = require('discord.js');

const client = new Client({
    intents: [GatewayIntentBits.Guilds],
    makeCache: Options.cacheWithLimits({
        ...Options.DefaultMakeCacheSettings,
        MessageManager: 25,
        PresenceManager: 0,
        ReactionManager: 0,
    }),
    sweepers: {
        ...Options.DefaultSweeperSettings,
        messages: { interval: 3600, lifetime: 1800 },
    },
});

Do not fetch everything

A common startup pattern is to call guild.members.fetch() for every server when the bot becomes ready, so the member cache is complete. In a few large servers that is the single biggest use of memory the bot has, and it is rarely needed: fetch the one member a command is about, when the command runs.

Find leaks in your own code

If memory keeps rising with caches limited, the growth is in your code. The usual forms: a Map or array that entries are added to and never removed from, such as cooldowns keyed by user; an event listener attached inside a command, so every use adds another (Node warns with MaxListenersExceededWarning); and a timer started on every reconnect.

For cooldowns and anything else keyed by user, remove the entry when it expires rather than leaving it for ever.

A cooldown that cleans up after itself

const cooldowns = new Map();

function startCooldown(userId, ms) {
    cooldowns.set(userId, Date.now() + ms);
    setTimeout(() => cooldowns.delete(userId), ms);
}

Sharding will not save memory

Sharding splits a bot's servers across several connections, and discord.js's ShardingManager runs each shard as its own process. That spreads the load, but every process carries its own copy of Node.js and the library, so total memory goes up, not down. Discord requires sharding from 2,500 servers; below that, it costs memory for nothing.

How much a bot needs

With intents and caches trimmed, a discord.js bot in a few hundred servers sits comfortably in 256 MB, which is what our free servers have. If yours has genuinely outgrown that after trimming, the paid plan gives it more room on the same server, without moving anything.

FAQ

Questions

Would switching to Bun or discord.py use less memory?

Perhaps a little, but the caches are the same idea in every library, so trimming intents and caches matters far more than the runtime. Change the settings before changing the language.

What does it look like when a bot runs out?

Node stops with "JavaScript heap out of memory", or the process disappears with "Killed" when the system ends it first. Both are covered in the error reference.