The Simplest Way to Solve Hard Problems
I've noticed something strange about hard problems. When a problem becomes difficult, our first instinct is usually to make the solution more complicated.
We add another layer. Then another abstraction. Then another process to manage the previous process. Before long, the problem has become so complicated that we can no longer remember what the original problem was.
I've done this many times.
A customer comes to you with a problem. Then they explain the problem. Then they explain why the problem exists. Then another stakeholder adds another requirement. Someone else adds an exception. Before long, the problem has become a giant collection of requirements, constraints, edge cases, and things that apparently must happen.
You start thinking about architecture. You start thinking about databases, APIs, services, infrastructure, permissions, integrations, and all the other things that might be needed. And suddenly you are solving a very complicated problem.
But sometimes the original problem was not complicated at all.
I learned this while building my first company, Phobosq. We worked with enterprise customers, and enterprise customers have a particular way of describing problems.
They don't necessarily give you a small problem. They give you the entire world around the problem.
A stakeholder might explain what the user needs, why they need it, what happened in the past, what another department wants, what the existing system does, what the sales team expects, what might happen in the future, and what happens in one unusual case.
All of those things may be true. But they are not necessarily the problem.
I remember one type of project where the customer wanted a system for their salespeople. Their customers would show them a design. The salesperson would take a picture of that reference design and upload it to the application. The system would then find similar designs from their existing design collection and show the salesperson the relevant ones.
When you hear the whole enterprise story around it, it can sound like a large and complicated system. There are customers, salespeople, applications, design libraries, image processing, search, databases, integrations, and all sorts of requirements.
But if you remove everything around it, what are we actually trying to do?
A salesperson takes a picture. We compare that picture with the designs we already have. We show the similar ones. That's it.
The heart of the problem is basically similarity matching. Once you see it that way, the problem changes. You can start thinking about the actual technical question instead of carrying the entire story in your head.
This became a habit for me. After meetings, I would go through my notes and try to connect what everyone had said. I didn't try to remember every sentence. I tried to understand the relationships between the things they said.
Then I would try to write the problem in one sentence. Sometimes the sentence would be very simple. That was the point. I wanted someone else to read it and understand what we were actually trying to solve without needing the entire meeting.
And if I couldn't write that sentence, I usually felt that I hadn't understood the problem yet.
This sounds like a small thing, but I think it is one of the most useful habits I've developed. Try to make the problem understandable before trying to solve it.
There is a temptation, especially in technology, to start solving too early. Someone describes a complicated requirement and the engineer immediately starts thinking about the implementation. But implementation is downstream of understanding.
If you misunderstand the problem, a technically excellent solution is still a bad solution. You can build the wrong thing very efficiently.
Complexity often comes from the description
I've started to think that there are two kinds of complexity. There is real complexity. And there is descriptive complexity.
Real complexity exists in the problem itself. For example, predicting the weather is genuinely complicated. There are many variables and interactions that cannot simply be removed.
But descriptive complexity is different. It comes from the way we describe something.
A customer might describe a problem using twenty requirements. That doesn't mean there are twenty fundamental problems. There might be three. Or one.
The ability to find that one is valuable. It is almost like compressing the problem. You take a long conversation and turn it into a short statement without losing what matters.
The shorter statement is not necessarily more correct. But if it captures the essence, it becomes much easier to reason about.
This is also why I sometimes try to explain complicated things to my 16-year-old cousin. He doesn't need to understand the technical details. That's actually why it works.
If I explain something to someone who already knows the technology, I can hide behind technical language. I can say things like architecture, pipeline, vector search, embeddings, services, indexing, and all the other words that make something sound understandable.
But when I explain it to someone who doesn't know those things, I have to answer a much more basic question:
What are we actually trying to do?
That question is useful. If I can't explain it simply, maybe the problem isn't that my cousin doesn't understand. Maybe I don't understand it well enough.
We confuse the problem with the solution
This happens all the time. A company has been doing something one way for ten years. Someone asks why. The answer is usually some version of:
"Because that's how the system works."
But that's not a reason. That's a description of the current solution. The current solution is not the same thing as the fundamental problem.
This is where I think first-principles thinking becomes useful. You don't have to throw away everything that came before you. You don't have to assume everyone else is stupid. You simply ask:
What actually has to be true?
Everything else is worth questioning.
This distinction becomes particularly important when you're building something new. You may look at an existing system and think:
"This is the only way this can work."
But maybe it isn't. Maybe it is just the way someone solved the problem ten years ago.
There is a big difference between:
"This is impossible."
and
"Nobody has done it this way."
The first is a statement about reality. The second is a statement about history. We often confuse them.
The best question is sometimes not "how?"
When a problem looks difficult, we usually ask:
How do we solve it?
That's a reasonable question. But sometimes it is too early.
A better sequence might be:
What are we actually trying to solve?
Then: What must be true for this to work?
Then: What can we remove?
And only then: How should we build it?
This changes the kind of thinking you do. Instead of starting with architecture, you start with reality. Instead of asking what components you need, you ask what outcome you need. Instead of accepting every requirement as fundamental, you try to understand why it exists.
And sometimes you discover that half the complexity came from the way the problem was presented.
Simple does not mean easy
There is an important distinction here. Making a problem simple to understand does not necessarily make it easy to solve.
The similarity problem in the example may still require difficult engineering. You may need good representations, efficient search, a large design collection, a good ranking system, and many other things. The underlying engineering can be hard.
But at least you know what you're trying to make work. That's valuable.
A simple problem statement doesn't promise a simple implementation. It gives you a clear target.
I think this is why some of the best technical systems look simple from the outside. The simplicity is not necessarily because the problem was simple. It may be because someone spent a lot of time removing everything that didn't need to be there.
I now try to compress problems
This has become almost automatic for me. When someone gives me a complicated problem, I don't want to immediately add things to it. I want to compress it.
A meeting might contain fifty statements. I want ten important points. Ten points might become three ideas. Three ideas might become one sentence.
And that one sentence should be something that another person can understand without needing the entire history.
Once I have that sentence, I can start breaking it down again. What are the fundamental pieces? What assumptions are we making? Which constraints are real? Which ones are just inherited? What is the simplest thing that could possibly work?
Then I can build back up.
This is very different from simplifying the problem by ignoring important details. The details still matter. But I want to know which details matter before I give them equal importance.
The danger of making a problem bigger
There is a strange tendency in organizations to make problems bigger. A customer says:
"We need to find similar designs."
The team starts discussing a complete recommendation platform. Then personalization. Then analytics. Then dashboards. Then multiple user roles. Then integrations. Then future scalability.
None of these things are necessarily bad. But the original question has disappeared.
You can spend months building the machinery around a problem without ever testing whether the core problem has been solved.
This is especially dangerous because complicated work can look like progress. A large architecture diagram feels like progress. A hundred-page requirements document feels like progress. A huge backlog feels like progress.
But sometimes the most useful thing someone can do is write one sentence on a whiteboard.
This is what we are actually trying to solve.
Now everyone can disagree with that sentence. That's good. At least they are disagreeing about the same thing.
Maybe the hardest part is knowing what to ignore
Good problem solving isn't only about knowing what to think about. It is also about knowing what not to think about yet. When everything seems important, nothing is. You need to find the center.
This is probably why I keep coming back to simplicity. Not because simple things are always better. Not because complexity is always bad. And certainly not because every hard problem has an easy solution.
It's because simplicity makes reasoning possible. If you can describe the problem clearly, you can question it. If you can question it, you can break it apart. If you can break it apart, you can identify the assumptions. And once you know the assumptions, you can finally ask whether they are actually true.
That is where new solutions come from.
I used to think solving difficult problems was mostly about becoming better at handling complexity. Now I think it is partly the opposite. Sometimes the important skill is to look at a complicated problem and keep removing things until you can see what is actually there.
A customer can give you a hundred requirements. A stakeholder can give you ten constraints. An existing architecture can give you twenty years of precedent.
But underneath all of that, there may still be a very small problem waiting to be understood.
So when something looks impossibly complicated, I try not to ask immediately: "How do we build this?"
I ask: "What are we actually trying to do?"
And then I try to put the answer in one sentence. If I can do that, I usually feel like I've made the first real step toward solving it.
Because sometimes the simplest way to solve a hard problem isn't to become better at solving complicated problems. It is to make sure the problem is as simple as it really is.