Julian Yaman

Julian Yaman

How Hybrid Sharding for discord.js Bots Saved 75% of my previous Memory Usage

How Hybrid Sharding for discord.js Bots Saved 75% of my previous Memory Usage

And also currently saved 100% of my AWS server fees I had to pay!

Subscribe to my newsletter and never miss my upcoming articles

Before I start with this article, I want to welcome everyone to my newly created blog. In the future, I will share some of my experiences as a developer with you and what I learned from them. I also want to share tools I found while programming on projects which were really helpful for me and could also be very useful for you.

Hope you follow my blog ๐Ÿ˜„

And now, let's jump right into it!


Introduction

Currently, I run a Discord bot which is used on over 4900 servers (on Aug 01, 2021). The primary goal of the bot is to fetch summaries of articles on Wikipedia, make the more "pretty" and to send them as an embed to a text channel on a Discord Server. But there was one major performance issue: the bot needed up to 4 GB of RAM.

I host my bot on AWS to guarantee good availability and to scale up / down more easily. But AWS server fees are quite high, depending on the EC2 instance you chose.

Before I made the performance updates, I paid over $1 each day just for hosting the bot on an EC2 instance. After some research, I found out that the Sharding Manager was the main reason why I had such a high memory usage.

This changed after I found a package on GitHub, which helped me a lot!

It's called discord-hybrid-sharding.

๐Ÿค” How Does It Work?

The package describes itself as following:

The first package which combines Sharding Manager & Internal Sharding to save a lot of resources, which allows Clustering!

The package promises savings on server resources up to 60%.

Internal Shards creates multiple shard connections to the Discord API within a single process (from An Idiot's Guide). Sadly, it is not ideal for bots with many guilds. But the package provides a solution for that.

It uses so-called "Clusters" which work like normal Shards with a Sharding Manager. It spawns multiple Internal shards in one cluster. Therefore, you won't have multiple "normal" Shards but one Main cluster which combines multiple internal shards.

In my case, it would mean that I could switch my current 5 "normal" shards to 5 internal shards and eventually combine them to (currently) a single cluster.

And this was exactly what I did.

What was the result?

I was able to reduce my memory usage from 4 GB to about 700 MB! That's a RAM usage savings of over 75%!

By reducing the memory usage that drastic, I was now able to downscale and eventually to save costs on server fees!

I now use the free t2.micro instance from AWS. You can use a t2.micro EC2 instance on AWS with 1 vCPU and 1 GB of RAM for free for 750h per month. Therefore, I don't have to pay a single cent until the 750h are used.

๐Ÿ› ๏ธ๐Ÿ’ป How Can I Use It?

The installation and the usage is pretty simple.

  1. Download it from npm with npm i discord-hybrid-sharding.

  2. Include the module into your Shard file

    const Cluster = require("discord-hybrid-sharding");
    let {token} = require("./config.json");
    const manager = new Cluster.Manager(`${__dirname}/bot.js`,{
                                        totalShards: 7 ,
                                       ///See below for more options
                                        totalClusters: 2, 
                                        mode: "process" ,  //you can also choose worker
                                        token: token
                                     })
    manager.on('clusterCreate', cluster => console.log(`Launched Cluster ${cluster.id}`));
    manager.spawn(undefined, undefined, -1)
    
  3. Insert the following code to your Bot file

    const Cluster = require("discord-hybrid-sharding");
    const Discord = require("discord.js");
    const client = new Discord.Client({
      shards: Cluster.data.SHARD_LIST,        //  A Array of Shard list, which will get spawned
     shardCount: Cluster.data.TOTAL_SHARDS, // The Number of Total Shards
    });
    client.cluster = new Cluster.Client(client); //Init the CLient & So we can also access broadcastEval...
    client.login("Your_Token");
    

You can also eval over Clusters:

let guildcount = (await client.cluster.broadcastEval(`this.guilds.cache.size`)).reduce((acc, guildCount) => Number(acc + guildCount), 0);
message.channel.send(`I am in ${guildcount} guilds`)

You can find more information about Hybrid Sharding and the package in its repository on GitHub.

๐Ÿ“˜ Conclusion

Hybrid Sharding saved me a lot of memory usage and therefore also currently all of my money. And even upscaling to an instance with 2 GB of RAM would mean saving a lot of money in the long run compared to the previous situation.

I hope you can use this package to also enjoy saving server resources and to improve the performance of your bot in general.

๐Ÿ‘‹ Thank you very much for reading this article.

๐Ÿ”— Stay Connected

โ˜• Support me on Buy Me A Coffee.

ย 
Share this