No, really, ask yourself the question: “who cares if my app is slow?” or, perhaps more accurately, why do they care? What is the purpose of the code you’re writing? Whom does it impact? And where is the author going with this?
Today I came across a post on social media discussing the benefits of offloading heavy data operations to the database for improved performance. The logic seems sound: databases are highly optimized for data storage and retrieval, and many developers have witnessed how a piece of well-crafted SQL can work wonders in a fraction of the time their application code would take. Fast is good; we like fast!
So it follows that we should leverage the database wherever possible to squeeze out all of those performance gains, right? Well, maybe in some cases. However, the problem with this line of thinking is that it assumes performance is the ultimate goal without considering the broader context.
Writing and maintaining SQL can be challenging — most people find it more difficult than coding in their application language1. Crafting a highly performant SQL query could take ten times longer than jotting down a few lines in a typical programming language. Furthermore, code is read more often than it’s written; by creating complex queries, you’re burdening others who need to comprehend your brilliant solution. And what happens when requirements change and the query needs updating? Good luck maintaining an extravagant query.
While there are other factors to consider in choosing between SQL and application code, the performance aspect serves as a vehicle to illustrate a prevalent issue in engineers’ thinking: writing software is not an isolated activity; it requires considering the real-world and business consequences of our code. The complete context.
Let’s consider this scenario: you have a functioning method that retrieves entities from a database and updates them iteratively. It’s not particularly fast, and SQL would offer a significant speed boost. So, should you rewrite it in SQL?
This is where we need to zoom out and consider the broader context. We must ask ourselves who cares if it’s slow because it might be perfectly acceptable as it is. Yes, it might be fine that it’s slow because nobody actually cares.
Does it run in the background, once per day, and complete in 10 minutes? That raises other questions, which could lead to alternative solutions.
Does the web server experience slowdowns during background processing? Yes, it does. Who cares? Customers care; page load times have increased from 1 second to 5. Can we schedule the job during off-peak hours? Can we execute it on another server? Is there a more performant language we can use? If not, then SQL might be the way to go. But hold on, do we have more urgent priorities to address first?
That’s what this is: seeing the bigger picture. This is one of the skills that Damn Good engineers have taken time to master, and it’s something we all need to learn to do better in order to avoid solving non-problems so that we can deliver better software.
Changing the way we think isn’t easy. I struggled with the bigger picture early in my career, and I still get sucked down into the weeds occasionally. I see others making the same mistakes almost daily. What helped me was acknowledging that there is a big picture — overarching project goals that deliver real value to real people; a forest around the trees — and that software engineering encompasses more than just writing code2.
Before blindly “writing code” to improve an application, pause and reflect on why you’re doing it — and who cares. There’s always room for improvement, but remember, perfect is the enemy of good3. Your time is finite; be sure to spend it wisely.
If performance were the main and only goal of software development, we would be writing web apps in C. ↩︎
A pet peeve of mine is referring to software development as “coding,” or the developers themselves as “coders,” as if people shovel requirements into a developer and out comes a feature with no processing in-between. ↩︎