Nik Kantar

Thursday, December 29, 2022
3 min read

Solve the Problem You Have

It’s all too easy to find oneself solving the wrong problems. Here’s how I try and combat that.

You might’ve encountered this quote from Donald Knuth’s book “The Art of Computer Programming”:

“Premature optimization is the root of all evil.”

It’s pretty common for us software engineers to overengineer things. The opportunity is usually right there and it can be so easy to imagine a bit of extra abstraction that appears to fit just right. But quite often our guesses are wrong, because we can’t actually see the future. Tragic, I know.

Here’s a step-by-step guide for avoiding this pitfall:

  1. Solve the problem you have.
  2. Solve problems you can reasonably expect to have soon.
  3. Stop.

1. Solve the problem you have.

Obviously, you have to solve the actual problem in front of you.

If you’re building an email notification system, build an email notification system. Build the services you need to generate email contents, interact with your email service provider, and whatever else you need for the thing to do what it’s actually supposed to do.

2. Solve problems you can reasonably expect to have soon.

Less obviously, it’s probably OK to go a little beyond the scope of the current project if a bit of effort can go a long way toward making life easier down the line.

If you’re building an email notification system, maybe you can store notifications in the database with type="email", anticipating other kinds of notifications. And maybe your services for dispatching requests to your email service provider can send any kind of email, and the caller supplies all the data.

What even is “reasonable” anyway?

That’s the sixty four thousand dollar question!

In my experience, most work done to futureproof something makes it more complicated to maintain before said future arrives. It then stands to reason that the decision about whether or not to do it is largely driven by how likely the target future use cases are, how well they’re presently known, and what the anticipated cost of refactoring is.

3. Stop.

Don’t solve problems you think you might have some day. Don’t try and support every imaginable variation of every feature.

Don’t build push notifications just because you’re in there already. Don’t add enterprise features for a hobby-level project. Don’t optimize for seven hundred thousand concurrent users before you’ve even launched. Don’t abstract utilities to accommodate use cases not even on your road map. Don’t invent problems with a false sense of urgency.

Resist the temptation. You probably have something more important you could do instead. Go do that.

Tags: programming

Thanks for reading! You can keep up with my writing via the feed or newsletter, or you can get in touch via email or Mastodon.

Self-Hosting Follow-Up
2022: The Year of Habits in Review