Benjamin Cane
Portrait of Benjamin Cane
Benjamin Cane
October 7, 2026
architecture
Architectural blueprints spread out on a surface
Photo by Marina Zvada on Unsplash

System Design pro-tip: even if you think you’ve got the best design in mind, force yourself to create a viable second design.

This is an interesting practice I’ve picked up over the years to challenge my own thinking.

When I think I’ve got the right architecture right off the bat, I force myself to design another one. Why? To avoid bias.

The more experience you gain designing and operating systems, the easier it becomes to look at a problem and immediately have an idea of how to solve it. You’ve built an encyclopedia of patterns that you’ve seen work. That experience is incredibly valuable, but it also creates bias.

Tried-and-True Design Patterns Can Still Be the Wrong Solution

How many times have you worked on a platform where someone took a good design pattern and applied it without really understanding the why or the unique constraints of the use case?

I’m sure for many it’s more than once.

Success with a design pattern can make us want to apply it everywhere. I know because I’ve done this myself once or twice (or more…).

Maybe event-driven processing worked great for scaling one high-volume service. So when another high-volume problem appears, event-driven processing feels like the answer.

But what if that use case also demands extremely low latency? The time spent queuing and waiting for consumers may work against one of your most important requirements.

Event-driven processing isn't bad; it just doesn’t always fit the problem.

That is why, before jumping into a system design, I take time to really understand the requirements and constraints.

  • What requirements am I trying to satisfy?
  • What constraints do I have?

Constraints aren’t always technical; they can be organizational, operational, financial, or even time-based. Even if something is the right technical solution on paper, it might still be the wrong solution for the organization that needs to build, maintain, and operate it.

Let the problem, requirements, and constraints shape the architecture.

Then Design Another Solution as a Sanity Check

Even after understanding the requirements and constraints, when a solution seems too obvious, I force myself to design another option.

I don’t mean creating a deliberately bad alternative to say I’ve considered multiple options. I try to create a credible second design that I would actually be willing to build.

  • If my first design is event-driven via a message broker, what would a real-time gRPC version look like?
  • If my first design uses microservices, what would a monolith look like?
  • If my first design introduces a new platform, can I solve it with existing platforms?

Once I’ve established both designs, I evaluate them against the same requirements and constraints.

  • Which meets the needs better?
  • Which introduces more complexity?
  • Which is easier for the team to implement?
  • Which will be easier to maintain in the long term?

Sometimes the second design wins, but not always.

The Second Design Doesn’t Have to Win

The goal isn’t to find a second design that works better. It’s to challenge and validate your gut feeling against another credible option.

Many times I still choose my first design. But by exploring the second design and doing a pros/cons exercise, I often uncover challenges I hadn't considered.

This often leads me to adjust my first approach; the adjustments may be small, but the result is often better.

Even if I don’t adjust my first approach, I feel much more confident after validating it against a credible alternative. That confidence itself is a great outcome. Because now I’m not choosing an architecture simply because it’s familiar, but because I’ve challenged it against credible alternatives and it still makes sense.

Final Thoughts

Experience is a great tool for system design.

  • The more you build and experience the pain points of complexity, the more you embrace simplicity.
  • The more you maintain systems, the more you appreciate reducing overhead and building for the future.
  • The more you operate systems, the more you care about correctness and resiliency.

Experience develops good instincts about how systems should be built.

Those instincts are valuable. But they’re still worth challenging.

Not all use cases or situations are the same; something that worked once may not work again.

So when my gut tells me to take one approach, I try to validate it against other credible options.

The goal isn’t to prove my gut wrong. It’s to make sure I’m choosing the right solution for the right reasons.

Trust your gut, but verify.

Discuss on LinkedIn Newsletter Back to all posts

More to Read

  • September 30, 2026 One of my favorite aspects of gRPC isn’t the performance. It’s the well-defined contracts Protobuf provides. architecture
  • September 23, 2026 Message queues are great for handing off work, but how do you know the work actually happens? reliability
  • September 16, 2026 Some architecture principles should be rules. Others should be guidelines. architecture
  • September 9, 2026 Mishandling concurrency is one of the most common root causes of software bugs reliability
  • September 2, 2026 At what point does better performance stop being worth it? performance

Practical engineering notes by Benjamin Cane.