A blueprint-style diagram of a custom suit and a software architecture diagram. The caption reads 'Tailor Made Software Architecture'

I’ve spent the better part of the past year developing a formal model, process, and distilling a way of thinking about software architecture. The result is an approach I’m calling Tailor Made Architecture. This is the first post in a long series to explore these ideas. If this topic is of interest to you, note that this blog has an atom feed to subscribe to updates. Check out my speaker website for speaking dates where I will be covering this topic. Also, if these ideas resonate and you’d like to participate in an immersive, hands-on, three-day workshop; I’ll be giving the next workshop in Dallas, TX November 13-15. Early-bird discounts are available through October 13th.

You can get a quick teaser for the broader work here:

What Exactly is Architecture?

If we were to take a random sample of 10 practicing architects and asked the question “what is architecture” we would likely get at least a dozen different answers. A quick survey of open “architect” roles underscores the diversity (and often incompatibility) of existing definitions. For some, an architect is primarily a kind of “super-developer” responsible for the patterns and conventions adopted by the rest of the team. For others, an architect is just a cloud platform expert. I won’t lie, sifting through these various “architect” positions often left me with lingering imposter syndrome about my qualifications to perform this kind of job. Ultimately I found myself working at Fortune 100 fintech firm with the title of “Chief Architect.” I headed up a team of architects and one of the biggest challenges was reaching consensus on a definition. We started by looking at various definitions.

In 2007, the International Standards Organization (ISO) published ISO/IEC 42010:2007 - “Systems and software engineering — Recommended practice for architectural description of software-intensive systems” which defined software architecture as:

“The fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution.”

We see similar definitions across a number of other sources, including “Software Systems Architecture” by Rozanski and Woods where architecture is defined as:

“Software architecture is the discipline concerned with model-based description and analysis of software systems, with a particular focus on the system’s highest-level component and their interaction.”

and “Software Architecture in Practice” by Bass, Clements, and Kazman

“The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.”

as well as many of others. The common themes relate to the organization of the system, the major components or elements, their interactions, and the decisions that drive the design and evolution of the system. All these definitions address the “what” of software architecture, but omit the “why.”

Why Architecture?

“Why is more important than how” -Second Law of Software Architecture

“Why” is the operative word here. What value does architectural thinking bring above that of a senior developer focused on the building and delivering the features of the software system? At its core, architectural decisions drive the essence of the software; everything it can do beyond providing the defined features and functions.

A quick look at state-of-the-art architecture literature shows us eight patterns for organizing the components along with their expected strengths and weaknesses when it comes to these capabilities.

A blueprint-style diagram of eight common architecture patterns - Layered monolith, modular monolith, microkernel, microservices, service-oriented architecture, service-based architecture, event-driven architecture, and space-based architecture

Each one of these patterns emerged over time as a reoccurring, common solution to a certain set of problems. At a high-level, these represent eight options for defining components, their boundaries, and their interactions. It’s possible to build a software system with a given set of features/functions using any of the above patterns. Architecture transcends features and functions by providing a set of high-level design-decisions that determine the capabilities of the system beyond the features.

“If you do not have the right architecture in place—or you choose the wrong architecture for a given project—generally the functionality may work, but the application as a whole will not be a success.”

-Mark Richards

I believe this quote is exemplified by a study of the launch of Twitter in 2006/2007. Twitter was launched on the hypothesis that people would find this idea of “microblogging” compelling. A set of features was built and deployed that were a hit. Within a few months, however, we began to see the infamous fail-whale.

Twitter fail-whale

While the functionality worked, the system as a whole struggled. It lacked important capabilities that originated not from features and functionality, but from architecture decisions. Over the next several years, Twitter evolved their architecture to elicit capabilities like scalability, elasticity, and reliability. Although the features remained fairly static during the transition, the capabilities ensured the platform would continue to grow more successful over the years. Does that mean the architecture of 2006 Twitter was wrong? Not necessarily. The original architecture of Twitter likely fit in 2006, but it didn’t in 2008. I say “likely” because I don’t entirely know. There is value to getting software released quickly to resolve market uncertainty, and there is value in building something scalable out of the gate to avoid considerable growing pains. Each approach has pros and cons; each approach involves trade-offs. In software architecture, there’s no objectively “right” answer, there are no “best practices” only trade-offs. The upside of this fact is that, although we now have access to sophisticated large language models (LLMs) that are demonstrating proficiency in generating code, they only tend to operate well in fields where there are known/defined best practices and rules to follow. Conversely, they tend to perform poorly in problem spaces that aren’t so cut-and-dried. The kind of thinking, reasoning, and navigation of nuance that good architects exhibit remains a long way away from being automated by LLMs like ChatGPT.

Thinking, Reasoning, and Navigating Nuance

There’s currently no direct, academic path to become an architect. Consequently most architects grow into the role from IC developer roles after a number of years. Think about it this way: imagine a self-taught developer enters the industry with the ability to hack together some code to make the computer do something. Over time this developer begins to see that their approach of hacking together code to ship features may be an expedient means to and end but the resulting codebase is becoming unwieldly and difficult to maintain. Over time they adopt design patterns that make the code more maintainable and robust. This process continues over years and the developer gains more and more long-term perspective. Eventually, if they’ve had to live with–and learn from–their decisions they develop a broad base of knowledge and a sense of what good code and good systems look like. It is this experience that yields fertile soil for becoming a burgeoning architect. The transformation, however, is not complete.

Since architecture, at its core, is grounded in decisions that elicit capabilities in a system–and given there are many different paths to achieve said capabilities, each fraught with trade-offs and pitfalls–architecture decisions should originate from thinking about capabilities, not code. This is not always easy. Take the ongoing debates about REST vs graphQL vs gRPC vs whatever. The function of all these things might reductively look like different approaches to simply move data across the wire yet the capabilities of each can be massively different. gRPC trades performance for tight-coupling and highly constrained clients. graphQL brings speed to market, developer productivity, and some flexibility at the cost of long-term evolvability and scalability. (Mature) REST allows a system to be completely decoupled enabling massive long-term evolvability, abstraction, and longevity but that trade is made in exchange for potentially massive up-front design work and network performance. “An average developer might argue that one of these options is objectively superior, but thinking like an architect means realizing that none of these are inherently good or bad, or superior or inferior; they are different approaches that involve different trade-offs. The best choice is the one with the optimal set of trade-offs based on the needs of the business and the actual problems being solved.

There are no best practices, only trade-offs.

Every decision involves trade-offs. Every. Single. One.

Often it is said architects don’t aim to produce the best architecture, just the “least worst” architecture. This looks different for every project, every time. It often looks different for the same project over time. This is not an easy space to navigate. We want to define an architecture that holistically aligns with the needs and the nature of the business.

Understanding Business Drivers

As a practicing architect, I will be the first to tell you there are technologies that I think are cool, there are technologies I enjoy working with, and there are even architecture patterns I prefer. These are my biases that I try hard to separate from my architecture decisions. Ultimately no matter how cool, how shiny, how trendy, how good technology X will look on my resume; if it doesn’t directly solve a business problem and provide relative business value it has no place in my architecture. In short, we can’t have a conversation about architecture until we have had the “business conversation.” Beyond the current problem set, the architect brings a different/broader perspective. Interpreting business drivers requires a certain visionary quality; to look at the present with an eye toward the future (without overengineering the solution) and often reading between the lines. Like the saying goes in jazz, “you’ve got to listen to the notes that aren’t being played.” All of these require new tools and techniques that aren’t in most developer’s (or budding architect’s) toolboxes. We’ll go deeper into these skills in a later post.

The typical business problem space is complex. There are often many competing priorities and several interrelated and cross-dependent problems to solve. It would be wonderful if the business spoke the language of developers and architects but that fantasy has no basis in reality. The business is going to speak the language of the business. They will talk about things like feasibility, cost, compliance, user satisfaction, and domain challenges. A core skill of an architect is to be able to speak the language of the business and translate business requirements, vision, marketing materials, and pitch decks into the language of the architect. Further we must communicate with the development teams (as well as other organizational areas) in their language. In short, as Nate Schutta often says, we must be the Organizational Rosetta Stone.

The Rosetta Stone on display in the British Museum, London CC BY-SA 4.0

This is all, of course, part of developing a new set of “soft skills” that don’t always come naturally.

Breadth vs Depth

In addition to shifting focus from functions to capabilities, architects must possess vision, wisdom, and problem solving skills. As a developer, my value was largely a function of my technical depth. I brought deep knowledge of the specific technologies I worked with. Becoming an architect requires inverting my focus to breadth rather than depth which can be a challenging shift. I had to let go of a certain amount of depth to focus on a broader foundation of knowledge - I needed additional tools. I spend a great deal of time at conferences and, when I’m not speaking, my aim is to sit in sessions focused on technologies that I’m not actively using and, at times, technologies I have never even heard of. This gives me what David Epstein calls “Range.” I have to understand the broader technology ecosystem, the available tools, the problems they solve, and their relative strengths and weaknesses.

My technical (and non-technical) breadth is the toolbox I work from. If I only possess depth in a handful of areas, I too-easily fall into the trap of solution-space thinking (i.e. this is what I know how to do, therefore this is what I will do). Depth still matters, but balancing depth in some areas vs breadth in others is a tightrope that we, as architects, must constantly walk. This requires yet another mindset shift as well as letting go of some of our depth (which has been our value proposition throughout most of our careers.)

Summary

Moving into an architect role requires many shifts in how we work, think, and learn. I encourage anyone to enter this space with “the beginner’s mind” and to be comfortable being new at something again (uncomfortable 10+ years into a career). It can be daunting, it can be rewarding. It is the space that I find myself happiest working in, and the same is true of the best architects I know. Also note that “Architect,” like “leader” are not necessarily constrained to titles; as an individual can embody the virtues and attributes of a leader without a former title, many thinking developers embody the attributes of a great architect without ever boasting the title or position in the org chart.

Over the course of this series I will dive deeper into many ideas introduced today and continue to build up the Tailor Made model and process. Thanks for joining me on this journey.