Practical tips for identifying when you are over-engineering.
A simple way to think about over-engineering is—are you wasting your today for an unknown tomorrow? “Unknown” is the keyword here.
Are you building for a million users—at a time—when a couple of hundred users use your application?
While building features, are you trying to accommodate fictitious(assumed without any basis) future needs?
Are you using technologies that you do not need today, with the assumption you might need them in the distant future?
What leads to over-engineering?
Will this scale?
Is a question software developers keep getting asked. It is a question software developers lose their sleep over.
To mitigate the scaling question, developers tend to over-engineer. From day one, they try to take care of that momentous day when their application will have a million users(they lose sight of the fact that, right now, there are only a couple of thousand users using their application).
Let me tell you a dirty secret—scaling is a commodity today; the cloud has made it so. While designing your application, as long as you follow the three pillars of scalability—statelessness, idempotency, and coding to interfaces—scaling is a breeze.
Lure of abstraction
Software developers love abstraction—it is satisfying to hide the perceived ugliness and complexity of the underlying system in a so-called easy to use, beautiful interface.
There is a thin line between abstraction and over-engineering. Read more about this here.
When developing features, it is intellectually satisfying to feel that what you are creating today will cater to every future use case(irrespective of whether it is needed or not); in pursuing this euphoric feeling, people over-engineer. Instead, build to a rigid scope, assuming that you will need some enhancements and changes in the future.
Buzz word driven development
Using technologies that are in vogue today without thinking whether they add value or not. Because someone wrote a blog post about a shiny new technology does not imply it will add value to your application stack. Follow the pragmatic school of thought—use boring technologies.
A majority of the bugs that I have seen in my professional career have resulted from over-engineering—bugs arising from using components and technologies that one does not need or understand.
What is not over-engineering?
Things you do to increase your time to market is not over-engineering. They might have a one-time cost(when working on them) but will pay off due to the subsequent lower time to market. Automation and engineering tooling that focus on developer productivity fall in this category. It is easy to dismiss these as over-engineering, but they are not.
Anything that makes it easy to ship features faster is not over-engineering(how and what you should do is a nuanced question).
Like any subjective matter, over-engineering is contextual—depends on the team, the stage at which the company is in, the engineering culture, the kind of market the company is in, and one’s skills. One man’s over-engineering is another man’s under-engineering.
Comic from XKCD