In the fast-paced world of startups, we often rush to add new features without looking back. After three years of this “move fast” approach, our code became a tangled mess, making debugging a nightmare, and even simple database changes felt impossible.
This blog is about our journey from chaos to order. We’ll explain the problem, share our thoughts, and describe the steps we took to clean up our code and make our system work smoothly. If you’re facing a similar mess and want to learn how to make things right, keep reading.
My general thoughts to solve the problem is:
- refactor codebase
- monitor everything
- optimize bottlenecks
after monitoring and optimizing we can decide whether we need to scale vertically or horizontally
Am doing them in 2 steps which is simpler.
1- Soft Refactor (copy/paste)
I don’t know if this term exists but anyway, I will find it
in this refactor we don’t change anything in logic or flow, just make the code cleaner and simpler by copying/pasting things.
split features: long files divided into smaller ones for example instead of having all db models inside
modelsdir and create files inside it
<feature_name>_models.pyand the same for views, signals, tasks, and so on
views should be short: take input from request and pass input to the right controller then return the response it shouldn’t have the logic inside it
DRY: move shared repeated logic to the
group things: related things should shown grouped, for readability and I mean functions, URLs, serializers, etc
after this process you will have cleaned files, simple views, and most complex parts are moved to controllers
which is fine for now and this will boost our speed in the next steps
2- Hard Refactor
unlike the last step this will be dangerous if you don’t have tests or your tests don’t cover enough cases
but enough copy/paste and let’s do this.
hard refactor process
remove duplication: now complexity lives in controllers mainly check duplicates and try to write more general
functions/mixinsthat do general cases with variables
generic viewsetsthis will allow you to make much with less code
library: use famous libraries for the common tasks
code design: think deeper to find if there is a design pattern that will make things simpler
SOLID: try to apply clean code principles as you can but keep in mind don’t over-engineering or waste time
Database: avoid it as much as you can but is mandatory to keep in mind this
- when applying database normalization keep in mind this code in production :D
- if you decide to add a new table/column you should copy data to this new ones
- if you decide to move table/column you should add them as computed properties on the model so the code doesn’t break or the structure changed in the frontend response
- also think about how much data are in this table how long migrations will take, and during this time you will use database replicates or what
- add/remove indexes that will boost the performance
after this process, you will test if everything is working right but also debug process is simple now because the code is much better
How can you drive a car with closed eyes ?!!
Open your eyes, and observe your system so you can make the right decision for your startup.
- basic logging
just search and you will find tons of tools very powerful will help you