Core Engineering Problems
I was thinking today about a core set of engineering problems that have emerged more than once in systems I've worked on. I'm not going to say or even pretend that this is a comprehensive list. This list doesn't even contain a single of the really hard-core computer science problems out there such as cache invalidation, naming things, or eventual consistency algorithms. No, this list is probably best described as a maslows hierarchy of needs for building internet software. If they are in place, the software has a chance of being something customers will love. If they are not in place, pain will ensue. What is this hierarchy of needs for software you ask? I break it down in to 4 software needs and 3 engineering needs.
4 things software needs before building features:
Trust (safety): This is so obvious that I at first didn't have it on the list. In order for customers to experience the delight of your new service and actually invest a part of themselves in using it, they need to trust it. They need to trust you. They need to trust that if they install your app, you won't do something bad to them or to their device. Whether they ask for it or not, a customer who stays with you wants an offering that prioritizes their safety over all else.
Scaling (+resiliency): This may often be overlooked early, and in some cases that's OK for early stage. However, before too long, economics + demand will require scaling and resiliency aspects. Customers expect you to be up when they want to use your service, at their convenience, not yours. This needs upfront design once demand emerges.
Engagement (+personalization): I can sense resistance to this requirement already. Why am I putting engagement and personalization in a list of otherwise nonfunctional features? It's intentional. In order to build features in the right way, we need to assume that we understand how our customers engage with our product, why do they keep coming back? And how is our service personalized to them and their needs. These are not features, they are critically core fundamentals that need to be understood and engineered as first class citizens before we consider adding anything else. If we start with these, features are just additive to the core.
Rendering (+globally): Understanding how you plan to render your experience to your customers across all of the devices your customer has in all regions of the world is often overlooked. I have seen so many systems that use HTML as some sort of content standard that I don't even blink anymore, but it shows a critical misunderstanding of how the internet works today, or an over-eagerness to jump on the latest javascript library before thinking about the customer experience. Customers expect to be able to access your service on any device that they have handy, at their preference, not yours, which more often than not is a mobile device. Building a service that scales globally across mobile (first) + web takes intention in the design and doing it well doesn't come for free.
3 things engineering teams need to build features:
Operations (minimize): Engineers need to own their code in production, but that shouldn't mean they are spending all of their time doing operations. Take time up front to build an automated set of operational capabilities, and always expect failure to happen and have a plan of action for when it does.
Safety (maximize): The number one thing, by far, that slows many engineering teams down is protocol that is intended to act as a safety net to keep failures from making it to production. It's the most frustrating thing in the world for everyone involved, including your customers to intentionally throw up safety protocols that require manual checks and sign-offs or manual testing before making a change. It's a defect, not a feature. Instead, make your deployments safe through automated testing, continuous integration and continuous deployments. The only safety nets you need (in most cases) are (1) instrumented observability that reliably tells you the availability of your experience (and wakes you up if it's down), (2) limiting your blast radius (rolling out change slowly), and (3) (most important) make rollbacks as fast as possible and automatic.
Tooling (stop coding stupid): Don't reinvent the wheel, embrace frameworks, use tools that auto generate the stupid code so that you can focus on features and functionality. Stop building snowflakes, and instead build what customers really need.
I'm 100% positive this is not a normative list, happy to hear other thoughts in the comments...