Apply the framework of opposites to come up with alternatives. For example - push vs pull, strong vs eventual, sync vs async, dense vs sparse. Whenever you encounter a design choice, ask yourself what the opposite approach would look like. That often gives you a viable alternative to evaluate.

Also, not every potential design needs to be thought through in detail. A lot of this comes from experience, but thinking in a structured way helps you build that muscle over time.

It is similar to what we do with the Minimax algorithm, where we prune paths that we know will go nowhere or be suboptimal. A passing comment on why we should not pursue such an option is usually good enough.

There is no point in unnecessarily designing a system around a suboptimal trade-off just for the sake of completion.

More importantly, which trade-offs should be eliminated depends on the following factors:

  1. Product requirements (expected UX)
  2. Engineering feasibility
  3. Team’s capabilities
  4. Delivery Timelines
Arpit Bhayani

Principal Engineer II at Razorpay - building Agent Studio, Ex-staff engg at GCP Memorystore & Dataproc, Creator of DiceDB, ex-Amazon Fast Data, ex-Director of Engg. SRE and Data Engineering at Unacademy. I spark engineering curiosity through my no-fluff engineering videos on YouTube and my courses