The Technical Debt of a 6-Year-Old Discord Bot

Tags: #programming, #python, #personal | 2026-03-04


6 years ago, I created a simple Discord bot in Python using discord.py library with the help of a random YouTube video (because, at the time, Python was the only programming language I knew, and I didn't wanna waste my precious teenager time learning JavaScript.) I didn't really care about the code quality; I just wanted to learn something new. Thus, a single giant Python file with hundreds of lines of code, named Ibara, was born.

Ibara Picture of Ibara Bot, made by @mery__S2_

P.S: The name Ibara was directly taken from one of my favourite characters from the anime/novel series "Hyouka." Check it out if you haven't already; it's a masterpiece.

Anyways, Ibara was a simple bot that functioned like "if a user sends this, reply with this", like this:

if message.content.startswith("!ping"):
    await message.channel.send("Pong!")
elif message.content.startswith("!hello"):
    await message.channel.send("Hello!")
elif message.content.startswith("!help"):
    await message.channel.send("Here are the commands blabla")
...

It was a mess, but it worked. However, after some time had passed, I noticed that the bot was taking longer and longer to reply to some commands. When I tried to debug it, I noticed that the if-else conditions that were on the end of the file were taking a lot more time to execute than the ones at the beginning of the file. Welp, this was a big problem, and I've come to the realisation that I have to refactor the code, so I did. Behold, Ibara 2.0's command handling system:

@client.command()
async def ping(ctx):
    await ctx.send("Pong!")

@client.command()
async def hello(ctx):
    await ctx.send("Hello!")

@client.command()
async def help(ctx):
    await ctx.send("Here are the commands you can use: !ping, !hello, !help")
...

The problem was solved! And, to be honest, this was enough for me at the time. I could add new commands without worrying about the performance of the bot, and maintaining the code was a bit easier. However after, uhh let's see... 4 years, I wanted to refactor the code again because we weren't really using the bot anymore and I wanted to bring it back to life. So, with the help of cogs that allowed me to split the code into multiple files, I was able to create a more modular bot and Noot was born.

Noot Picture of Noot Bot

P.S: Yeah, we changed the name. Ibara was a bot that we used to have in a server that we don't use anymore, and we wanted to give it a fresh start, so we renamed it to Noot. I guess you could take a wild guess on where the name Noot came from lol. Yeah, it's the sound that the penguin from the show "Pingu" makes.

This time refactoring took a lot of time and effort, but it was definitely wort- hmm, eh, kinda worth it. Yes, cogs certainly made the code more modular and easier to maintain, but they also added a lot of complexity to the codebase. This time I wasn't the only one working on the bot, and some of the decisions we made were not the best ones. For example, using multiple JSON files to store some data, making those JSON files one server-specific, all cogs having their own JSON read/write functions, not having a central error handling system, etc... All of these decisions made the codebase more complex and harder to maintain, and things kept breaking every 1-2 months. However, we tried to keep up with the maintenance and kept adding new features, but it was a never-ending cycle of breaking things and fixing them.

conclusion

Current state of the bot Current state of Noot Bot

So, here we are, with 183 commits, 35 cogs, and 23 one-server-specific JSON files acting like a database; we stand on the peak of technical debt. The bot is still alive and has a lot of cool features, but it's a mess. At the time of writing this, we are thinking about refactoring the code again, but we are not sure if we can handle the amount of work that it would require. Well, we'll see. Next time, I hope I write to you guys about how we refactored the code and how it turned out, but for now, I just wanted to share this story with you guys and maybe give you some insights on how to avoid some of the mistakes that we made along the way.

The main takeaway from this story is that technical debt can accumulate very quickly, and it can be very hard to get rid of it once it's there. So, if you're starting a new project, try to think about the future and the maintainability of your code before writing it.

← Back to posts