Discord Bot Performance: Node.js Optimization for Production

Published on

How to optimize Node.js Discord bots for production. Covers memory management, caching strategies, sharding, database optimization, and monitoring.

Written by Space-Node Team – Infrastructure Team – 15+ years combined experience in game server hosting, VPS infrastructure, and 24/7 streaming solutions. Read author bio →

Your Discord bot works in development. In production with thousands of users across hundreds of servers, performance problems emerge. Here's how to handle them.

Memory Management

Gateway Intents

Only request the intents your bot needs:

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages
        // Don't include GuildMembers if you don't need member events
        // Don't include MessageContent if you only use slash commands
    ]
});

Each intent increases memory usage. GuildPresences alone can add 100MB+ on large bots.

Cache Control

discord.js caches everything by default. In production:

const client = new Client({
    intents: [...],
    makeCache: Options.cacheWithLimits({
        MessageManager: 50,      // Cache 50 messages per channel
        GuildMemberManager: 100, // Cache 100 members per guild
        PresenceManager: 0,      // Don't cache presences
        ReactionManager: 0,      // Don't cache reactions
        GuildScheduledEventManager: 0
    })
});

A bot on 1,000 servers can reduce memory from 2GB to 300MB with proper cache limits.

Sweep Old Data

Periodically clean caches:

const client = new Client({
    sweepers: {
        messages: {
            interval: 3600,  // Check every hour
            lifetime: 1800   // Remove messages older than 30 minutes
        },
        users: {
            interval: 3600,
            filter: () => user => user.bot && user.id !== client.user.id
        }
    }
});

Sharding

When your bot exceeds 2,500 servers, Discord requires sharding. Each shard handles a subset of guilds:

// sharder.js
const { ShardingManager } = require('discord.js');
const manager = new ShardingManager('./bot.js', {
    token: 'YOUR_TOKEN',
    totalShards: 'auto'  // Discord calculates needed shards
});

manager.on('shardCreate', shard => {
    console.log(`Launched shard ${shard.id}`);
});

manager.spawn();

Cross-Shard Communication

Getting data across shards:

// Get total user count across all shards
const results = await client.shard.broadcastEval(c => c.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0));
const totalUsers = results.reduce((acc, count) => acc + count, 0);

Database Optimization

Connection Pooling

const mysql = require('mysql2/promise');
const pool = mysql.createPool({
    host: 'localhost',
    user: 'bot',
    password: 'password',
    database: 'bot_db',
    connectionLimit: 10,
    queueLimit: 0
});

Caching Frequent Queries

Don't query the database on every command:

const guildSettings = new Map();

async function getGuildSettings(guildId) {
    if (guildSettings.has(guildId)) {
        return guildSettings.get(guildId);
    }
    
    const [rows] = await pool.query('SELECT * FROM guild_settings WHERE guild_id = ?', [guildId]);
    const settings = rows[0] || defaultSettings;
    guildSettings.set(guildId, settings);
    
    // Expire cache after 5 minutes
    setTimeout(() => guildSettings.delete(guildId), 300000);
    
    return settings;
}

Error Handling

Uncaught errors crash Node.js. In production:

process.on('unhandledRejection', (error) => {
    console.error('Unhandled rejection:', error);
    // Don't exit - log and continue
});

client.on('error', (error) => {
    console.error('Client error:', error);
});

Monitoring

Health Checks

setInterval(() => {
    const used = process.memoryUsage();
    console.log({
        rss: Math.round(used.rss / 1024 / 1024) + 'MB',
        heapUsed: Math.round(used.heapUsed / 1024 / 1024) + 'MB',
        guilds: client.guilds.cache.size,
        ping: client.ws.ping + 'ms'
    });
}, 60000);

PM2 Monitoring

pm2 monit  # Real-time monitoring
pm2 logs   # View logs

Hosting

For small to medium bots, Space-Node's Discord Bot plans provide dedicated resources:

  • Small (Free): Perfect for bots under 50 servers
  • Middle (€3/6mo): 5GB storage, 128MB RAM for growing bots
  • Large (€6/6mo): 10GB storage, 256MB RAM for established bots

For large bots (1,000+ servers), a VPS gives full control over the runtime environment and resources.

Space-Node Team

About the Author

Space-Node Team – Infrastructure Team – Experts in game server hosting, VPS infrastructure, and 24/7 streaming solutions with 15+ years combined experience.

Since 2023
500+ servers hosted
4.8/5 avg rating

Our team specializes in Minecraft, FiveM, Rust, and 24/7 streaming infrastructure, operating enterprise-grade AMD Ryzen 9 hardware in Netherlands datacenters. We maintain GDPR compliance and ISO 27001-aligned security standards.

View Space-Node's full team bio and credentials →

Launch Your VPS Today

Get started with professional VPS hosting powered by enterprise hardware. Instant deployment and 24/7 support included.

Discord Bot Performance: Node.js Optimization for Production