In this post, I wanted to describe a mental model that I’ve developed over the years for iterative improvement. I wouldn’t quite call it a “framework”, as it doesn’t present specific guidelines or steps to success. Instead, I’ve found it to be a helpful way to visualize and consider the steps we take toward our goals.
The “Solution Space”
The hardest exam I ever took in college only had four questions. It was for my Data Structures & Algorithms course, which was all about using algorithms to solve hard problems as efficiently as possible. So on the final exam, every question would describe a problem like “Find the fastest route between two points in a graph“, and you would have to 1) propose an algorithm that solved the problem, and 2) prove that your algorithm was the most efficient solution. In other words, even if your algorithm solved the problem, if it wasn’t the best possible answer you got zero points. If you happened to pick the best algorithm but you couldn’t prove it, you got 50% credit.
We had three hours to answer four questions, and I left with a crick in my neck that lasted two days. The class average was 48%. I was ecstatic to get a C.
I think about that exam a lot because for the first time in my life, it wasn’t enough to simply solve a problem. That class taught us students to obsess over finding solutions that were provably better than all the others. And – perhaps at danger to my sanity – I proceeded to transfer that obsession into my work in business.
Of course, in a business context we don’t always get things right, nor can we usually tell for certain whether or not there’s a better solution to be had. What we can do, however, is iterate and compare results. In other words, if it’s unclear how our solutions will translate to outcomes, we can start with our “best try” and then change little things to see whether they make outcomes improve or worsen.
In my mind, I visualize this process of iterative improvement as climbing a mountain in the dark. We know we’re somewhere on the mountain, but aside from educated guesses, we’re not sure whether a step forward will take us downward or upward on the slope. So the best we can do is take that step and observe what happens. If every step is an iteration, and we only follow steps that take us upward, then we’re bound to gain altitude (and improve our solution) over time.
With that in mind, if we zoom out and visualize all of the possible steps we could take, we might come up with something that looks like a topological map of an entire mountain range. On this map, any point we can stand is a possible solution, and we can “walk” between adjacent solutions via iteration. It follows, then, that the distance between any two points corresponds to how different the solutions are (as it’d take more steps to get to a further solution). Finally, if our altitude represents how optimal our solution is, that means the highest peak of the tallest mountain on the map represents the best possible solution to our problem.
I like to call this concept – this visualization of all possible solutions – a problem’s “solution space“. (The term has been borrowed from a related concept in computer science.)

Local Vs. Global Maxima
Visualizing a problem’s “solution space” in this way reveals a few interesting insights.
The first is that there’s likely a huge number of possible solutions, as represented by the vastness of the mountain range. It might not feel intuitive at first, but this tends to hold true for most problems. Consider any user experience or marketing website or tech architecture or legal agreement. There’s an near-infinite amount of variation in how these can be designed, even though a realistic attempt probably wouldn’t touch most of them. Imagine, for instance, a Terms of Service that simply read “By using this, you agree to not be an asshole about it.” Does it technically get the job done? Yes, although most probably agree it isn’t the best approach.

A second insight from this visualization is that you don’t have to reach the absolute summit to get pretty high up on the mountain. In other words, there are plenty of solutions that are “good enough” for the real world, and some of them may be completely different or take completely different approaches.

Finally, the third and most important insight is that if we naively follow the aforementioned procedure for iterative improvement – that is, if we only take adjacent steps that move us further up the mountain – that it’s possible we’ll get “stuck” in a place that isn’t actually the best overall solution. This is because when we’re surrounded by steps which only take us back downward, we might not have the ability to see that going back down in a different direction may allow us to climb even higher.

This third insight reveals the important distinction between local vs. global maxima (maxima = plural of “maximum”). A “local maximum” is a point on the mountain range which is higher than all the points around it, but it isn’t the highest point overall. Whereas the “global maximum” is a single point – the actual summit of the tallest mountain (e.g., the Everest in the Himalayas). In reality, there may be many local maxima which exist below our “target altitude”, but their existence is often misleading. Recall that we’re climbing in the dark, so if we’re only only able to navigate by observing adjacent steps, we may think we’ve reached the highest we can go, when in reality we’ve only reached a local maximum.

Evolutionary Vs. Revolutionary Iteration
This all brings me to the big question: How can we tell if we’re “stuck” at a local maximum, and if so how do we “break free” from it?
To better illustrate this, let’s bring this into the real world with an example. Consider for a moment, the problem of designing a home page for a food delivery service. (and for brevity, we’ll just examine hero sections)
Here are the home pages for four leading food delivery services:

Now, each of these homepages showcase minor differences which relate to their business goals and market positioning. GrubHub presents a healthy lunch, whereas Uber Eats opts for burgers and coke. Caviar goes more playful and abstract in their visuals. DoorDash includes a variety of dishes and a subtle nod to their mobile app experience, while GrubHub includes a small link to suggest ordering via the app. Uber Eats, on the other hand, would rather upsell you on an Uber One subscription which gets you $0 delivery fees. All pages includes links to register/login, although DoorDash and Caviar put their links closer to the address input, because you can use a saved address if you sign in (a nice, value-oriented CTA). But one thing that every hero section does is provide a big, easy delivery address input – because that’s always the first necessary step to ordering food. Your location determines the available restaurant options.
So let’s return to the “solution space” visualization. All of these homepages are pretty similar, and in an industry as mature as online food delivery, it’s pretty common to see many competitors converge to similar points on the mountaintop. They all use a similar solution because… it works.

Now, let’s imagine that we’re Caviar and we want to start inching our way up the mountain. Our metric for success is conversion rate. This can be defined many ways, but let’s define it as the percentage of people who, upon loading the home page, will either register/login or enter their delivery address.
The quickest way to iterate is usually swapping out colors, imagery, and headlines. Or you can experiment with different presentations and positions for buttons and calls to action (CTAs). By using an A/B testing solution, you can automatically send incoming traffic to different variations and see which variation performs the best. This is often how data-driven, mature companies squeeze performance improvement out of their user experiences. They feel confident that their solution is already pretty good, so they don’t want to mess too much with the proven formula. And they operate at great enough scale that even small improvements to conversion can result in big gains.

I call this type of iteration “evolutionary change“, and it’s the same type of “naive iteration” that I mentioned above. It happens in bits and pieces, with small steps through the solution space, always toward higher altitude. And like the general concept of evolution, if you were to step your way backwards through past iterations, you’d see a gradual change between any two points in time.
In most cases, this type of evolutionary change works well, but it is also the easiest way to get trapped by a local maximum. In other words, pushing pixels around the page – while relatively low-risk – can only yield a limited improvement.
How, then, do we jostle ourselves out of a local maximum? By trading evolutionary change for revolutionary change.
Unlike evolutionary change, revolutionary change involves taking a completely different approach to your solution. Instead of making small changes to what you already have, go back to the drawing board and see what fresh perspectives you can apply to solve your problem. Any big change involves risk, but you also have the opportunity to airdrop yourself to another side of the solution space, and potentially one that can get you closer to the global maximum (i.e., best possible solution).

So when is a revolutionary change warranted? I hate to say it, but it depends. In the same way that it would take a ton of resources to call a helicopter to carry you to the other side of a mountain, a revolutionary change can take huge amounts of time and effort, and there’s still no guarantee that your destination will be better than where you started.
That said, some key inflection points that warrant revolutionary change include:
- Expansion of business lines (e.g., when the Uber app started offering more than just rides)
- Rebrand to better align with customers and users (e.g., Patreon’s rebrand for creatives)
- At a start-up while you’re still trying to achieve product-market fit.
- If you feel in your gut that something just isn’t working.
Revolutionary change doesn’t only apply to earth-shaking, company-wide change, either. I still use this framework every day for smaller problems that arise while designing user experiences, tech architectures, and marketing pages. For example, if we’re having a really hard time trying to represent an idea on a new homepage, we often go back to consider the idea itself. What if the idea itself isn’t clear or compelling enough, and we’re just spinning cycles on high-fidelity designs – pushing ourselves toward a local maximum? Remembering to take a step backward to re-evaluate the approach often ends up saving us time and putting us on a better path to success.
In Conclusion
That was a lot of thoughts. But it all comes back to thinking about work in the context of the “solution space”. No matter what I’m tackling, I tend to consider where we are on the mountain range of success. Doing so helps to avoid wasting time on evolutionary changes that don’t move the needle, and also keeps me ever-mindful of considering different approaches to solving problems. Because navigating to the summit of any mountain is hard, treacherous work, but thinking about it holistically can help us find the right approach to reach our goals.