8 system design principles I learned after doing it wrong more than 50 times!

Priyank Verma
SquadStack Engineering
4 min readMar 11, 2018

At Squad, we strive to build awesome products to solve external (customer) as well as internal (team) needs. As a product engineer, the paramount part of your job is to design and build products. Essentially, you dig deep into the root cause of problems, design appropriate solutions and implement them into the end product.

Over the course of my journey so far, here are the 8 system and product design principles that I’ve learned from other awesome people at Squad, through feedback and simply not doing it right, a whole bunch of times.

1. Why?

What is the underlying problem that led to the feature request?

At Squad, you don’t just code the requirements into the software. As a product engineer, it’s your responsibility to remove the layers and expose the root problem that led to the feature requirement.

Get to know the root cause of the problem that you are trying to solve. Or even better, as Toyota Production System’s lean principles say “Genchi Genbutsu” i.e. ‘go and see for yourself’.

2. Robust, reliable and usable

How can you make the feature more robust, reliable and usable?

Once the essential feature requirements are finalized, we must concentrate on how to make the feature more robust, reliable and usable.

Things to ponder upon and take into consideration can be :

  1. The persona of the users who’s going to be using it
  2. Scenarios in which that feature would be used. E.g. in case of problems, then show more data than needed for faster resolution
  3. Building anative quality in a product so that it can self-correct or “Jidoka
Source: www.lean.org

3. The first iteration

Considering the ideal design and limitations, what’s the best first iteration that’s doable?

Given the time and resources you have, what’s the best first possible iteration of the product going to be? If it’s a large system or something you are building from scratch, there are always going to be iterations.

The main idea here should be to move fast and get things shipped. A product that is 90% done and shipped on time is always better than 100% and delayed.

4. Ease of future iterations

How easy will it be to make iterations on the current feature?

The design should incorporate all the non-functional requirements to make future iterations easy.

Scale the feature? Change a component? Use a different 3rd party service? Your implementation should be flexible enough to incorporate and encourage these enhancements.

Design patterns are your best friend here.

5. Bottlenecks with scale

What are the potential bottlenecks with scale?

Like the promised land, scale-land is where everyone wants to be, but it is scary. It breaks where it was not supposed to break and has witnessed more horror stories than a haunted castle.

What are the potential bottlenecks that are not a problem now, but will break at 5X, 10X or 100X scale?

List them down on the feature ticket, or better yet, document them in the code itself.

6. Capturing data and metrics

What’s the data that has to be captured and how will it be consumed?

Every feature in the product will need some data that needs to be captured to track it. It can be:

  1. Action logs
  2. Event logs
  3. Metrics
  4. Failures
  5. Anomalies

What affects this majorly is how that data will be consumed? Store it in a structure that will make the consumption of data easy and efficient. After all, the only motive to store data is to use it to support better decision making.

7. Developer experience

How good will the developer experience be when interacting with the code base of that feature?

There can be many developers who’ll use or modify the code that you are going to write.

How will their experience be when doing that? E.g. Will the test cases you wrote, make them feel confident enough to make changes fast?

Few points to consider:

  1. Is the code well documented?
  2. Are test cases strong enough?
  3. Is the code re-usable where it makes sense?
  4. Are functions small and is the code simple to read?

8. Was it successful?

What metrics will determine that the feature has been implemented successfully?

Finally, after all the fun-time you had creating the feature, what will determine that it has been implemented successfully?

The data you tracked will be of paramount importance here.

It can be the case that to track this quantitatively will not possible, but then can you track it qualitatively?

The idea here is that you can’t improve what you can’t measure.

Conclusion

Obviously, this is not an exhaustive list of things to take into consideration while designing a system or a product as an engineer. This just covered what I have learned so far by just doing things wrong on a number of occasions.

It’s fun to build stuff. Continuously improve (“Kaizen” in Toyota’s lean principles). Keep iterating. Keep shipping!

Does Squad sound like a workplace where you’ll thrive in? — we’re hiring!

--

--