Six principles of system design
Main illustration: Burak Beceren
The start of any journey begins with consulting a map.
But if you’re a product designer starting out on a new project, you might find yourself with a blank page, and the job of drawing the map: of defining the high-level design direction that your team is going to use to chart their course. Mess it up, and you could find yourself quickly marching your team off a cliff.
What you need to create is a clear overview of the system you’re all about to build – you need system design (not to be confused with a design system). This sounds simple, but can be incredibly challenging in practice. After all, how do you go about mapping something that doesn’t even exist yet?
“System design forces everyone into a shared common understanding before embarking on the process of building”
System design, then, is an act of creative cartography – it is like creating a map in advance of creating the territory. But it’s also incredibly valuable: it forces everyone into a shared common understanding before embarking on the process of building.
Creating a system design
Maybe I’m asking for trouble here: I’ve chosen to write about what is probably the most abstract part of the entire design process, that of forming conceptual ideas and trying to inject a picture of those ideas into a colleague’s brain. This is why many of us struggle with this stage. However, I think you can break it down into relatively simple terms.
In practice, system design work usually takes the form of a diagram: boxes and arrows describing the main parts of the product, and how they all connect to each other. As we’ve written before, a good system design defines the following:
- Elements: What are the core elements or objects in the system?
- Interconnections: How are the elements connected? What are the relationships? What are their inputs and outputs?
- Purpose: What does this achieve?
Creating this map is often an emergent process that happens collaboratively at a whiteboard (still the best tool there is for creating system designs: quick and dirty, modifiable, collaborative, and impossible to get lost in details). Given that it might be another while until any of us sees a whiteboard again, tools like Miro are a great digital alternative. But the ultimate output is almost always the same: a clear diagram illustrating objects and the relationships between them.
An example of system design for part of Intercom
You might think you can dodge this hard bit and just quickly talk it through instead. But language can be slippery: what I’m thinking and what you’re thinking may be significantly different, even though we’re using similar language.
What’s more, most products that require this level of mapping can get complicated quickly. It can also be hard just holding a clear picture of a complex system in your head.
So you need to be able to diagram those ideas out. Get your map down on paper. And most importantly, the team needs to get aligned on what we’re building.
Agreeing on a system design
Getting to that point, however, can be tough. Here are some common challenges you might encounter:
- Subjective preferences: Everyone disagrees over whose personal vision of the system represents the best or truest version.
- Pursuit of a “perfect” system: You lose yourself in designing the system as an end in itself, where the goal becomes inherent elegance or cleverness rather than practical value.
- Divergent mental models: Designers may naturally tend towards thinking in terms of layouts or user flows, Engineers in terms of code architecture, PMs in terms of value delivered. Those viewpoints need to converge.
- Scope creep: We expect too much of the system and believe that it should resolve all product problems. Once people start thinking in systems, they see how everything’s connected, which naturally leads them to add more and more scope “because, like, everything’s connected, man!” *exhales, coughs*
Herein lies the very point of doing this work. All of the things that make a canonical system design difficult to nail down are the reasons it’s worth doing. It’s difficult because it forces you to resolve ambiguity, ferret out unknown unknowns, get super-specific about how the system will work, and agree on it all.
The goal is to hammer out these differences early on, while doing so is still cheap. You don’t want to realize you’ve all been singing from different hymn sheets several months into building something, and then take on an expensive course correction. You want to figure all that out at the very start.
“You need to create the scaffolding for how you want your stakeholders to interrogate the system design”
So inevitably you reach the point where you think you have something you’re happy with. Now you just need to get everyone on board.
Just like when you’re presenting mockups for feedback, it’s not enough to just present your work on screen and expect instant alignment. As a designer, you need to create the scaffolding for how you want your stakeholders to interrogate the system design and structure their feedback, and not get sucked back into the misalignment that your work is intended to solve.
The purpose of principles
Most likely you already know how to do this. It probably happens all the time in Design Crit when giving UI feedback. You deliver your comments in terms of generally agreed principles.
For example, when giving UI feedback I try to frame any feedback as objectively as I can. “I don’t like the way you laid out that toolbar” is bad feedback: it’s subjective and closed-off. “Making the toolbar layout more like our other menus would increase consistency” is better: it’s couched in a well-understood principle (consistency) and opens the door to discussing rationale tradeoffs.
“There’s no Fitt’s Law or Gestalt Principles for boxes and arrows”
This approach to giving feedback is well-established when critiquing UI design, but there’s no Fitt’s Law or Gestalt Principles for boxes and arrows. And so in many cases the feedback can quickly become loose, reactive, and subjective.
When faced with a recent situation like this at Intercom, a group of us aligned on the following principles for assessing a system design. Rather than assessing the design and relying on overly subjective interpretations (“I don’t like it,” or “That’s not exactly how I think of it”) we tried to assess how well the system design stacked up against the following criteria.
Principles of good system design
(Note that these are not presented as universal principles of system design, but rather ones that worked for this specific project. Hopefully they are useful examples, but I urge you to take a shot at your own list.)
1. Keep it as simple as possible to address today’s known problems
Don’t add complexity to the system to solve hypothetical problems we might face in the future. Thinking ahead is great, but we shouldn’t take on the burden of planning for eventualities that might not even happen. Let’s not try to boil the ocean.
If we can make the system more open-ended without adding a ton of complexity to the system or adding lots of work, that’s great. But otherwise let’s stay focused.
Can we make this simpler? Are we making too many assumptions about how this may need to be extended in future?
2. Ensure that it’s legible
A successful system should be easy for users to understand when they interact with the product. They will need to look at the UI (when we design it) and be able to roughly figure out what the parts of the system are.
For example, Slack clearly exposes itself, where it’s possible to discern the underlying system by looking at it – there are channels, inside each channel there’s a stream of messages, each message can have a thread, etc.
Can the correct user mental model be expressed via the UI? Is the architecture of the system evident in the interface? Will users be able to figure this out without an explanation?
3. Move complexity to infrequently used parts of the system
We will accept less efficient workflows and higher learning curves for one-time tasks if it means we get to make common tasks faster and simpler.
Assuming there’s a certain burden of functional complexity that the system must carry (Tesler’s Law), then think about where you can live with having more complexity. For example, it’s more acceptable for it to be difficult for a manager to set up a team (which will happen once) than it is for a customer support rep to reassign a conversation (which will happen dozens of times a day).
Does this system require too much complexity up front? Are the least-used parts of the system over-exposed? Which users interact with each part of the system?
4. Don’t take on non-core problems
Don’t get distracted by the implementation details. Remember, you’re not designing the entire product when you’re designing the system: you’re designing the major interrelated parts of it. The system design needs to describe the shape of the solution. It doesn’t need to answer every detailed design question.
Try to figure out what are the core things that the system can handle and what things you will be able to solve by designing the UI, or with clear workflows, or settings if needed.
Is this the right zoom level for this diagram? Do we really need to solve this part of the problem at the system level?
5. Build it to scale from simple use case to complicated use case
One of the dangers of moving upmarket (i.e. focusing on larger customers) is that you can alienate and create unnecessary complexity for your smaller customers. It’s too easy to design just for the needs of your most demanding users. The most elegant systems allow for simple use cases that then scale up as needed.
Intercom, for instance, is used by two-person startups who want a way to chat with their customers, and it is also used by huge teams with complex needs. You want a system that works simply for the little guy and scales up in complexity for the big guy.
What parts of the system are relevant to all users? What parts are niche?
6. Prioritize adjacency to the existing system
All other things being equal, choose a system design that’s most similar to what we currently have: less for us to build, less change for our users to adapt to.
System design is an ongoing process, rather than a once-off project. Your product will evolve, and anytime there is an expansion of what the product does, or a change in how the product operates, that’s where the adjacencies in the existing system becomes a factor to assess.
Adjacency is beneficial because it reduces change aversion or it reduces the barriers to understanding what the new version of your product is.
How hard is it to get to this from what we have today?
Chart your own course
Like I said, these are not universally applicable principles, but hopefully they serve as an example to help you to assess and present your own system design work.
“System design is like creating a map of the complete product to act as a guide for the product teams that build it”
Ultimately, system design is like creating a map of the complete product to act as a guide for the product teams that build it. The art of system design comes in judging the scale just right – providing enough information to give an accurate sense of the terrain and not so much that it risks becoming a 1:1 representation of the product, like the proverbial Borgesian map that exactly covers the territory it is merely supposed to depict.
Get it right, and you’ll have an invaluable document that will align your whole team around a shared understanding, and a powerful tool to help you navigate the complexities ahead.
Are you a product designer interested in solving these problems? Join our team – we’re hiring in Dublin, London, or remote in Ireland or the UK.