---
title: Scaling a Discord bot economy for fun
date: 2026-08-15
description: Cause it was fun
tags: [discord, databases]
---


## Why?
One of my friends messaged me asking if I could add economy support to brunk, a Discord bot that I run for me and my friends' communities. It started as a Discord voice tracker, logging when people joined and left. Eventually it grew to have starboards, music, and now an economy system.

## What Broke?
Well, as soon as I told my friends the economy system should be working, about 30 people started using it at once, immediately making my poorly configured SQLite database fall apart. The main command, `/gamble`, would read an index for a user, find their balance, do its logic, and then write it back to the database. But with 30 people using it all at once, and Discord delivering many command requests at once, the bot started to choke and either error, time out, or crash. Every time it crashed I would hear a collective groan and a flame war starting over who crashed it. I quickly realized that the boat I had was no longer big enough.

## Migration.
I moved the economy database to `Postgres`, a great database backend that I've used for many of my projects. I had issues with migration because I had foolishly set up the Postgres container to only have network access to `Chudite`, the internal name of the bot in Docker's networking system. I fixed that issue and started importing the SQLite database. It took oddly long—about 3 minutes for a 12 KB database—and I never fully figured out why. I think the script I cobbled together wasn't the greatest. I'm no longer interested in figuring it out anyway. I finished rewriting the bot to use Postgres and transferred it over. It worked well, a lot better than before the migration, but then as more people found out (the owner pinged literally everyone in a 300-ish-person server), it started choking again. I started to wonder if it was due to hardware limitations, but logging showed that I/O wait and CPU were well below 15 percent, even with 3 music streams happening at once, which can roughly take up 2 to 3 percent per stream on the bot and about 3 percent on Lavalink. I realized that I hadn't set up connection pooling, which meant that for every single economy request, it was generating a connection to the server, retrieving data, closing it, reopening it once the logic was done (if it was a write), and then finally resting for the next command. I resolved that and then it started working great! I saw up to 80 reads/writes per second, which is well below the hypothetical max of my VM, but my code isn't the best and I was happy. It was no longer limited by my code; the pipe was finally big enough.

## Then I decided on semi-passive coin collection.
Someone suggested that users get coins for every 10-ish messages they send, which I implemented. I noticed that I was now choking the database again. I immediately realized that I was appending 0.1 to 0.3 coins per message, which for a bot with 12 servers and 700-ish members isn't entirely a lot, but my code isn't great since I write this for fun. Users didn't realize that they were getting coins for their messages, as anything output by the economy system is rounded. I added buffering in memory, which relieved the load on my database. It was configured at 10 messages per flush, and it still works great.

## Faster deployments.
I was doing all of this work live while my friends were actively bombarding my bad code at the start. I had to juggle my time between fixing my bad code, restabilizing the bot, and then eventually dealing with them wanting new features. A big problem was deploying new updates. It originally took about 3 minutes per deployment, which was unacceptable for their Instagram Shorts and Twitter-riddled minds. I found out it was recloning the entire Docker container, not just the new bot code. I monkeypatched a fix that's still there to this day, and it brought deploy times down from about 3 minutes to 15 seconds.

## Overall
It was a neat project to test and a fun way to try to fix things as fast as possible. I never really had to deal with users actively trying to use things when something was buggy or down. Please note that this isnt a guide or exactly what i did, i just wanted to write something to test out my new rendering engine.
