UX on Platform Engineering

Design an Internal Developer Platform that your users love using

Fernando Villalba
20 min readJan 2, 2023

Why Focus on User Experience?

When reading about platform engineering you may see the term DevEx (Developer Experience) thrown about, and see new roles that focus on this area too. This is all very nice, but if we deliver platforms that are poorly designed, the developer experience will always suck.

In a previous article I mentioned that leaning on documentation as a crutch for bad design is a terrible practice. Here I want to expand on what great design and User eXperience (UX) means and how we can leverage these principles to create an Internal Developer Platform (IDP) that doesn’t suck to use:

https://www.reddit.com/r/devops/comments/stuep4/weve_spent_months_building_this_platform_devs/

I’ll be using the term design and User eXperience (UX) interchangeably in this article because great design delivers great user experience, and the principles of both disciplines go hand in hand.

Please note that UX must apply from the ground up to the entire platform (such as CLI, API, UI, etc), not just the UI. A bad UI often reflects a confusing underlying design.

A Definition of Great Design

I am leaning heavily on the phenomenal book “Design of Everyday Things” by Don Norman. In there he argues that great design has two characteristics:

Discoverability — Is it possible for users to figure out what the possible actions are to use that product?

Understandability — Is it easy for users to figure out how the product can be used, is the language clear enough?

So in a nutshell:

Great design communicates to the user the intended purpose of the tool in the most intuitive way possible.

Great! How do you make an IDP intuitive?

Intuition is described as the ability to comprehend without conscious reasoning. Or more precisely in our case, to be able to figure out how to use our IDP without needing explanations or perusing the manual.

In order to do this we need to be sensible. We of course cannot aim to design our platform for every persona on this planet. For example we don’t aim to make an IDP to give our computer-iliterate grandma infrastructure tasks, but…

We must create an IDP that’s intuitive to use even by the weakest link of every persona that it’s aimed for. For example, when designing for a developer persona, you must aim so the most junior, less competent, developer with a hangover can use it safely and intuitively.

Safely and intuitively are key words. Because good design is not just about making it easy, it’s also about preventing and/or mitigating costly mistakes.

In this section, I will be covering the following areas and explain how we can improve them to make the design of our IDP more intuitive:

  • Features (affordances)
  • Signifiers
  • Constraints
  • Mappings
  • Feedback
  • Conceptual models (language)

Features (Affordances)

Don Norman calls the actions that are possible with a tool affordances. Affordances are your intended and unintended IDP’s features (although in this article I will mostly use the term feature interchangably as it’s more familiar). A developer should make every effort to ensure the tool communicates as many features as possible intuitively while also discouraging features that can be harmful or an antipattern.

It’s generally better to have fewer, well designed and important features that are cohesive to your mission and the needs of your users than having a large stack of uncohesive features.

Having a large stack of uncohesive features can be very disorienting and confusing for your users.

The headache for new users…

AWS for example has hundreds of different and disjointed products, many of which are so similar, with overlapping functionality. For a new user this is incredibly overwhelming because not only you need to figure out what product does what, you also need to figure out which one suits your needs better and the tradeoffs when implementing one over the other.

I am going to use AWS and Amazon as an example a lot in this post because they are an excellent example of how you can deliver solid products with plenty of useful features that are terribly designed.

Given that IDPs are here to make your developer’s life easier while implementing compliance and security for your company, you want it to be simple to use and navigate, with opinionated solutions that apply to your organization.

Luckily within your company you can narrow the scope of what’s possible to suit your needs, and this is great because you can have tighter designs that are far more user friendly.

I will reiterate that having fewer, well designed features based on what your users need will make the experience dramatically better for them. For example, I used to own a Samsung TV that came with two remotes. One of them with the bare minimum most commonly used buttons with plenty of space around them “to breath”, another one that came with all bells and whistles with tightly packed buttons, guess which one me and my flatmates always used? Which one looks nicer to use to you?:

The two remotes that came with my Samsung TV, we only ever used the top, simpler one

There are two things you need to understand when implementing features in your IDP:

  1. More features means more flexibility, but it also means less usability.
  2. When you make a list of all the features needed for your platform, your users will likely use the top 20% of the features, 80% of the time. This is what’s referred to as the Paretto Principle. So organize your time and efforts around the most important features.
There is a tradeoff between number of features (flexibility) and usability
https://uxdesign.cc/80-20-rule-how-the-pareto-principle-is-helping-designers-in-2020-7207b75f2f40

Signifiers

Signifiers are visual or other types of cues that help users understand and navigate the features of your IDP, these can be labels, icons, tooltips, and other types of visual indicators or interactive help.

However, it is also important for you to minimize the use of signifiers wherever possible. Signifiers should only be used where design cannot be intuitive in any other way. Too many signifiers can also be a sign of bad design. This is because they can clutter the UI or CLI output and overwhelm your users. By designing a platform with a clear and intuitive structure and layout, you can often reduce the need for signifiers and create a more user-friendly experience.

However, it is also important for you to minimize the use of signifiers wherever possible. Signifiers should only be used where design cannot be intuitive in any other way. Too many signifiers can also be a sign of bad design. This is because they can clutter the UI or CLI output and overwhelm your users. By designing a platform with a clear and intuitive structure and layout, you can often reduce the need for signifiers and create a more user-friendly experience.

Example of signifiers as arrows used to veil bad design on a stove

Remember this:

Design > Signifier > Documentation

Your design should be clean enough to be intuitive on its own but if that’s impossible, use a signifier. Only refer the user to the documentation as a very last resort.

It’s okay to leverage signifiers more heavily first if you can’t think of a better way to make the design more intuitive. Thankfully software is not like stoves and we can keep iterating to make it better!

Constraints

Constraints are a way of guiding the behaviour of your users by limiting their actions and decisions, they have two advantages when it comes to design.

  1. By narrowing down the scope of what’s possible, it’s easier to figure out the intended functionality of the IDP.
  2. Making undesirable antipatterns difficult or impossible.

Internal Developer Platforms are different to other tools because we want to be opinioned for compliance, security and delivering clean infrastructure. Therefore you should aim to implement features in a way that are constrained or make it difficult to achieve undesirable outcomes.

For example, an IDP should not be designed like git, where antipatterns like Gitflow are too easy to achieve. IDPs are fundamentally created to achieve very particular company outcomes and reducing cognitive load so infinite flexibility may be counterproductive.

A really good example of constraints being put into action are video games, where you have boundaries to limit the amount of things you can try, making it easier to find what you need to do.

Here is a good example of a constraint in the first level of Mario teaching the user how to play. A mushroom is heading towards you but you don’t know if it is an enemy. The designers put a brick ceiling that stops you from avoiding it, meaning you inexorably learn that the mushroom is good for you.

https://medium.com/swlh/the-perfect-game-tutorial-analyzing-super-marios-level-design-92f08c28bdf7

In an IDP you can leverage constraints with Role Based Access Control (RBAC) too. Why should a developer be able to see all the options that are available to a platform engineer? That just makes the experience more cluttered and harder to understand.

Mappings

Features and properties in an IDP should be mapped in a way that is easy to infer the relationship between them. For example if you have a workload running, it makes sense to have a link that takes you to the logs and back, or just display the logs next to the workload, not in a completely different location detached from it.

Example of intuitive mappings, compare with picture on signifiers above.

In your IDP you should make sure to map around a core property or feature and organize the information around it. For example if a workload is a unit of deployment in your IDP, it makes sense to have all its properties and related features close to it in the UI, also it makes sense to be able to look at the properties and associate them with their workloads, etc.

Feedback

Whenever you perform an action, your IDP should provide feedback about the success or failure of such action. This should be useful and not create irritation or panic as poor feedback can be worse than no feedback at all.

Good feedback tells you when a property has been saved, when your submission has been sent, when a workload is deploying, when an error has ocurred, etc. Better feedback gives actionable information. For example when you run a command and the error tells you what command will fix it, etc.

Here is an example of beautiful feedback provided by Kind:

The feedback is beautiful and useful, telling you what to do next.

And more good feedback from the gcloud CLI:

Here you are not only told it is the wrong flag, but given a close alternative!

Bad feedback would be excessive log output that’s meaningless to the user and overloads her with information she needs to review and offers no benefit. Or software giving too many warnings and alerts where the user is alarmed but no action can be taken or is needed.

Conceptual models (and Language)

When creating your IDP you should leverage existing conceptual models the user is familiar with. One obvious example is the use of colour, you wouldn’t use green for an error and red for success as that’s not how people understand it.

Here is an example of terrible design, where red is used for the allowed action with a checkmark and green for denying with a cross, or maybe the other way around? Hard to tell! That’s why it’s bad design

https://www.reddit.com/r/userexperience/comments/hua9gu/guess_where_youre_supposed_to_sit/

Another example of leveraging conceptual models badly is Jenkins using blue balls for successful deployments. In this case is because the creator of the tool is Japanese and in Japan they used blue as green — perhaps he never thought that Jenkins would be popular world wide.

Hence, one of the most popular Jenkins plugins is one that changes the blue balls to green.

If some of you are giggling at the repeated mention of “blue balls”, know that I am too.

The most popular Jenkins plugins change blue balls to green.

Language is another extremely important factor to consider here when designing our IDP, especially how we name properties and features of our platform.

Not only you must name the properties and features of your IDP in a way that leverages the existing understanding of your users but you should also try and name them to match the way the user experiences them in your platform and not the way you understand them internally.

A good example on how NOT to do this is the way AWS names their external static ips, “Elastic”. I remember when I first used AWS I was very confused as to how to assign an static ip address to the server in great part due to this reason.

This example is very interesting because in the minds of AWS engineers these ips are elastic because you can reassign them from one server to another, so from that point of view it makes some sense. But the problem is that this is not the way new users to the platform will see it. Whenever you provision a server you want to assign it a static ip address, that is, a ip that will not change when you pause the instance. Elastic as a name, feels like the stark opposite of what it aims to describe, hence the confusion.

GCP on the other hand calls exactly the same concept a Static External IP Address, which in my opinion makes it far more intuitive and easier to infer. And it looks like Azure has done a better job in this sense too:

Can’t say I’d recommend Azure over AWS, but credit where it’s due

At this point you may be tempted to think, “oh this doesn’t matter much, my users will consciously get it when it is explained to them once and then it will be smooth sailing from there on”.

The answer is a big NO. Your users may consciously get your inverted conceptual model, your counter-intuitive naming and your awkward mappings, but it will trip them continuously and make their life so much harder. If you do not believe me, look how insanely difficult it is to learn riding a bike with an inverted handle:

8 Principles of Great Design

In the previous section I gave an outline of the areas you can improve to make your design more intuitive, here I want to give you some principles you should always follow to ensure your design is always in top form.

1. There are no bad users, just bad design

Never blame your users for errors they make. Remember how we talked about designing for the weakest link of every persona? This doesn’t mean we assume our users are stupid. We are simply designing to mitigate and avoid human error.

If you average human experience as a whole, it is mired with errors. We all have bad days and make stupid mistakes, it is what makes us human and fallible, but it’s also what makes us wildly creative.

Do you know who is uncreative and virtually infallible? Computers. That’s why we use them — to help us be creative while reducing our errors. It is our duty to design computer software that empowers the very human creative spirit.

In order to help you design systems that eliminate human error or mitigate its impact, implement the 5 whys method.

The root cause should never be the user, keep asking why!

Keep asking why but don’t stop at human error and blame the user even if you need to do 6 or 7 whys. Instead find ways to prevent users from making the same mistake in the future or mitigate the impact of the error.

You won’t be able to predict all errors a user will make. You are not responsible for anticipating all of them, but you are responsible to address these errors when they occur!

Sawstop is an example of spectacular design to prevent human error — and save human lives! (Or at least limbs):

Finally, it is also important that as an user you don’t see yourself as stupid when you don’t easily get something, because you may likely be a victim of terrible design!

2. Teach Design Principles to ALL your Platform Engineers

Your IDP should probably have a product owner, and the product owner must make extra sure that everyone involved in the creation of your platform understands UX principles very well. That includes the most people-averse of your backend engineers too!

I hope that this article made it abundantly clear already but I will reiterate again:

Design is not just the domain of graphic designers and frontend engineers. It is also extremely important that backend engineers or any other DevOps/platform engineer involved understands design very well.

This is because the frontend and user facing elements of your platform will be a representation of the backend, so if backend engineers don’t understand design, you are likely to have an awful platform.

There are a million memes showing how the frontend is always so much prettier than the backend, which may be truth for user facing websites and some applications, but for DevOps tools it generally isn’t the case at all. A badly designed backend will show its ugly face everywhere in the CLI, UI and API.

https://twitter.com/codersrank/status/1409804583438852097

I know too many super smart developers who are very good at coding but absolutely terrible at understanding what good design is (or communication in general, so to make it even worse, their documentation also sucks). I suspect this is why AWS is so badly designed too and part of the reason why we need IDPs, because developers are overwhelmed with complexity that’s exarcebated by terrible design.

It is not enough to have a product manager dictating design or hire a UX expert, that’s because many of the design decisions will be done organically by the team, and it is impractical to have someone external micromanaging them on good design practices.

3. Spending more time at design will save your company time

Imagine you are feeling lazy and decide not to spend 50 hours improving your design so your users can save 25 minutes of looking at your documentation to perform a certain task in your platform.

Now let’s say that on average your users end up spending 30 minutes looking at the documentation for this feature, probably more because they often forget.

And let’s say this feature was used 1000 times in your company by various users of the platform over a period of one year. That’s 500 hours.

Your laziness just cost your company 500 hours of engineering time and your users will also be disgruntled and resent the platform you created because they had to do extra work to use it.

Save company time, and make friends in the process — improve your design!

https://uxdesign.cc/interaction-design-is-more-than-just-user-flows-and-clicks-4cc37011418c

This is what’s called Tesler’s law:

It is more efficient for a designer and engineer to invest an extra week in simplifying an application’s complexity rather than requiring millions of users to spend an additional minute learning how to use the application.

In a previous article I pointed out that an over-reliance on documentation was generally a sign of terrible design, because it means the work of design is being outsourced to the user in the form of tedious manual processes. Here is a hilarious example of how bad documentation of GE light bulbs echoes poor design:

If you want to dramatically improve your user experience, don’t ask your users to look at the documentation for complicated steps, or tell them to create a bash script, or do anything redundant and time consuming you could do yourself!

4. Understand the Personas that will use your IDP

Whenever you are designing your IDP, you need to find a balance between what you are trying to achieve and what your users need. Sometimes your needs may be at odds with what developers want, so it is your job to find elegant compromises that suit both.

IDPs are there to serve developers (it’s in the name) and achieve software delivery velocity, but they also need to serve infrastructure engineers and maybe even project managers or users on the business side.

Either way, your strategy should include creating a list of all the personas that would be using your platform and itemise the list of features they will need (Keep it short). Remember you can expose or hide these features based on their permissions and you should always make it easy for them to achieve their goals.

Again, always design for the weakest link of the persona you are delivering features for. Make it safe, make it intuitive.

5. Beauty is also important — the Aesthetic Usability Effect

I initially dismissed beauty as a bonus when writing this and I wasn’t even going to include it. But reading multiple studies done on how beauty influences users appreciation and eagerness to use a product, I changed my mind.

Beauty in your design is not unlike beauty in finding a partner, it won’t keep your suitors around if you are just a pretty face with a terrible personality, but it will certainly draw them in and make them more forgiving of your flaws.

This is what’s called the aesthetic usability effect and plenty of studies have been done that prove beyond doubt that a beautiful design helps to draw your users in and keep them hooked if the usability matches up.

These studies on the aesthetic effect on users have proved the following:

  1. A well-designed product or interface can distract users from minor flaws in usability, leading them to be more forgiving of these issues.
  2. A pleasing design can create a positive impression in people’s minds, which leads them to perceive the design as more effective than it may actually be.
  3. A visually appealing design can hide usability issues and prevent them from being identified during testing.

Ultimately though, it’s far easier to create beauty out of simplicity than out of clutter and a poor design, so once you have nailed down the simplicity and intuitive parts of your design, you can then worry about making it beautiful.

Also, it’s worth highlighting that even though I consider a beautiful design very important, I would argue that it’s the last factor to consider among all others discussed here, as shown by this meme, beauty doesn’t always win if usability doesn’t match up:

https://www.reddit.com/r/userexperience/comments/ercae4/this_always_happens/

I will reiterate that beauty is not only the domain of the UI, in the Feedback section above there is an image of Kind CLI output that looks great, with icons and all the trimmings, which makes it much more appealing to look at than bare text.

6. Abstracting is good, but beware of doing it too much

I talked a lot about simplicity and uncluttered interfaces here, but it’s also important not to abstract away every useful property in a feature to keep the design clean as that can lead to frustration and extra work as well.

If there are many options to be displayed, learn to leverage convention over configuration and hide the advanced options behind an expandable menu.

7. Beware of Bad Design Stockholm Syndrome

You may get away with a badly designed IDP and successfully convince one or a few teams to get used to it and love it for its other virtues. After all, a badly designed product is not always necessarily a bad product, AWS and Amazon in general have proven that masterfully. The Amazon store is a confusing mess to navigate, but they deliver packages exceedingly fast and free, have every product under the sun and offer great customer service (and you could argue that at least these are elements of great user experience too!).

AWS on the other hand had an insane 7 years lead time over the competition, their products are generally robust enough to use and they deliver features and new products extremely fast.

I call bad design stockholm syndrome when the designers and first users get used to a badly designed product and then tirelessly justify it to newcomers without improving the design at all.

This is more common than you think because users tend to blame themselves when they don’t get something. This is because no one wants to be seen as the stupid guy who doesn’t get your design.

Bad design usually turns into lots of documentation, countless how-tos and explanations, bash scripts to mitigate the poor design of the platform and your new users pulling their hair spending too many hours learning the IDP you created with the hope they will one day like it and understand it too.

You see this a lot with AWS. Many engineers get certified, peruse the documentation constantly, create tools to make it easier to use, and spend hours and years learning to use it to the point where they get inured to it and champion it, in effect, validating terrible design.

I believe one of the reasons why IDPs are becoming popular is because they abstract away developers from the pain of having to use something like AWS directly, so it is very important we don’t make the same mistake and deliver another monstruosity that’s very difficult to learn and use. Hence why it is imperative we understand design well when delivering IDPs.

8. Learn from game design!

There is a lot to learn about user experience from game design. Games cannot afford to have a terrible design and still be successful. If a game is not user friendly it will likely fail, even if other things about it are great.

Also games need to be designed to be engaging so their best option is to find elegant ways to teach you how to play. I always find fascinating how good games manage to teach players how they work without heavy tutorials. Especially complex games:

I also recommend taking a look how the first Mario game tackled teaching you how to play in such a transparent and intuitive way:

Conclusion

There is a lot to unpack in this long post and I could have gone further giving more specific examples on how to apply these principles to the various areas of an IDP, but I think I will leave it for a future article

The main takeaway is that UX design is of paramount importance for all areas of your IDP, if you do not deliver an elegant solution that your devs love using you are making all the same mistakes that AWS has done and you won’t be helping the situation much.

Applying these principles is harder than learning them, but at the very least if you understand this you can use them as compass when designing and implementing your IDP.

Additional Reading

I hope I whetted your appetite to learn more about UX and applying it to platform engineering or any other DevOps tool. Here are some more books and resources you can read on the topic:

Blogs and Articles

Books

“The Design of Everyday Things” by Don Norman (Audio, Cheeky Audio, Summary): This classic book explores the principles of good design and how they can be applied to the design of everyday objects and systems. It is a great introduction to the field of UX design.

Universal Principles of Design by William Lidwell: Lots of design principles you can leverage to improve the UX of your IDP.

“Don’t Make Me Think” by Steve Krug: This book is a practical guide to usability testing and design, and it provides a wealth of tips and techniques for creating user-friendly websites and applications.

--

--