Chapter 1: What Happens When There Are No “Best Practices”?

saht architecture trade-offs adr fitness-functions decision-making

Status: Notes complete


Overview

Modern software architecture exists in a domain defined by constant trade-offs rather than universal rules. Unlike many engineering disciplines, software architecture lacks a settled body of “best practices” precisely because every architectural decision is highly context-dependent — what works brilliantly in one organization, at one scale, with one team topology, will fail in another. Chapter 1 establishes this foundational truth and then arms the reader with tools and mental models to navigate it.

The chapter argues that the architect’s job is not to find “the right answer” but to understand which trade-offs are acceptable in a given context. The authors frame this as the central challenge of distributed architecture in particular: once a system is split across network boundaries, every decision about how pieces communicate, how data is owned, and how components are deployed carries a cascade of consequences — and none of those consequences are free. This is especially true in the post-monolith era, where teams have moved from avoiding distributed system problems to actively managing them.

The chapter also introduces the Sysops Squad, a fictional but realistic case study that will appear throughout the book. This saga grounds abstract architectural concepts in a concrete system under pressure, making the trade-off analyses that follow in later chapters legible and applicable to real-world situations.


Core Concepts

Architecture trade-off: A situation in which every available option offers some benefits and some costs, and the architect’s role is to identify which costs are acceptable in a given context. There is no option with only benefits.

Architectural Decision Record (ADR): A short document that captures a single architectural decision, the context in which it was made, the options considered, the decision reached, and the consequences (positive and negative) of that decision.

Architecture Fitness Function: An objective function, automated or manual, used to assess the degree to which a given architecture satisfies its architectural characteristics (e.g., performance, security, scalability).

Architectural quantum: A unit of architecture that has high functional cohesion and is independently deployable. Introduced briefly in Chapter 1 and developed fully in Chapter 2.

Architectural characteristic: A system quality attribute — such as scalability, elasticity, reliability, or security — that an architecture must satisfy. Sometimes called non-functional requirements, though the authors reject that term as it implies these concerns are less important than functional requirements.


Why There Are No Best Practices

The authors open with a deliberately provocative thesis: the term “best practice” is largely meaningless in software architecture. This is not cynicism — it is a structural feature of the discipline.

Why “Best Practices” Break Down

  1. Context specificity: A practice that is “best” at Google’s scale is actively harmful at a 10-person startup. A microservices pattern that suits a product with 50 independent teams creates operational chaos for a team of 5.
  2. Technology flux: The infrastructure landscape changes faster than best practices can be validated. A “best practice” from 2015 (e.g., “use a service bus for all inter-service communication”) may be obsolete, actively misguided, or simply replaced by superior approaches by 2021.
  3. Emergent complexity: Distributed systems exhibit emergent behaviors — properties that arise from the interaction of components that cannot be predicted by examining any single component in isolation. No practice is “best” against an emergent problem space.
  4. Trade-off inversion: Optimizing for one characteristic (e.g., performance) often degrades another (e.g., data consistency, security). The “best” choice depends on which characteristic is most important — and that is always a business/domain question, not a technical one.

What Architects Can Do Instead

Rather than seeking best practices, the authors argue architects should:

  • Understand trade-offs deeply and completely
  • Make decisions explicitly and document them (ADRs)
  • Continuously validate architectural assumptions (fitness functions)
  • Keep architectural definitions simple and shared
Best Practice Thinking       Trade-Off Thinking
--------------------         --------------------
"Use X because it's best"    "X gives us A and B, at cost C and D"
Static advice                Context-dependent analysis
Single answer                Multiple valid options
Hides costs                  Surfaces costs explicitly

Giving Timeless Advice About Software Architecture

The authors identify a paradox: architects need guidance that survives technology churn. Their solution is to operate at the level of trade-off analysis rather than technology recommendation.

Timeless pattern: “Understand what you are trading away when you make a choice” is advice that remains true regardless of which technologies exist.

Technology-specific advice ages poorly. Recommendations tied to specific tools, frameworks, or platforms have a half-life — often measured in years, sometimes months.

The book itself is structured around this principle: instead of recommending architectures, it provides frameworks for analyzing when one architecture style is preferable to another, under which conditions, for which goals.


The Importance of Data in Architecture

One of Chapter 1’s most important — and often underappreciated — contributions is its insistence that data is a first-class architectural concern.

Most architecture discussions center on services, components, and their interactions. But in distributed systems, data ownership, data access patterns, and data consistency requirements often determine what architectures are even feasible. The authors assert:

“Architects who ignore data are only designing half the system.”

Key Data-Architecture Tensions

TensionDescription
Data ownership vs. data accessWho owns a piece of data determines who can change its schema, its semantics, and its availability guarantees
Consistency vs. availabilityIn a distributed system, you cannot have both strong consistency and perfect availability (CAP theorem echoes throughout the book)
Shared database vs. per-service databaseSharing a database couples services structurally; separate databases introduce synchronization complexity
Schema evolutionChanging data schemas in a distributed system requires coordination across services that may not be deployable simultaneously

These tensions recur throughout the book, particularly in the chapters on decomposition and data architecture. Chapter 1 flags them as non-negotiable considerations for any architectural decision.


Architectural Decision Records (ADRs)

ADRs are the book’s first concrete tool for managing the “no best practices” problem. Since there is no single right answer, the important thing is that decisions are made consciously, documented explicitly, and revisited when context changes.

ADR Structure

Title
-----
A short noun phrase describing the decision.
Example: "Use asynchronous messaging for order processing"

Status
------
Proposed | Accepted | Deprecated | Superseded by [ADR-XXX]

Context
-------
What is the situation that necessitates this decision?
What forces are at play (technical, organizational, deadline-related)?

Decision
--------
What was decided, stated in active voice.
"We will use..."

Consequences
------------
What becomes easier? What becomes harder?
Both positive and negative consequences must be listed.

Why ADRs Matter

Without ADRs, architectural decisions become tribal knowledge. New team members cannot understand why the system is structured the way it is; they only see the structure. Worse, the reasons for a decision — which often include “we couldn’t do X because of constraint Y” — are lost, meaning future architects may re-evaluate a decision without the full context that justified it.

With ADRs, decisions become auditable artifacts:

  • Teams can challenge assumptions when context changes
  • New architects learn the reasoning, not just the result
  • “Why is this done this way?” has a written answer

ADR Anti-patterns

Anti-patternProblem
ADR as rubber stampWritten after the decision to document, not to decide
Only recording successful decisionsDecisions that were reversed or superseded are equally valuable
ADRs without consequences sectionThe consequences section is what distinguishes an ADR from a simple changelog
Too granularADRs are for architectural decisions (significant, hard to reverse), not implementation choices

Architecture Fitness Functions

A fitness function is borrowed from evolutionary computing: a function that evaluates how close a candidate solution is to an ideal. Applied to architecture, a fitness function evaluates how well an architecture satisfies one or more architectural characteristics.

Types of Fitness Functions

By trigger:
  Continuous   — runs on every build/commit (e.g., performance tests in CI)
  Triggered    — runs on a schedule or on demand (e.g., monthly security scans)
  Temporal     — tests that verify time-based requirements

By scope:
  Atomic       — test a single architectural characteristic in isolation
  Holistic     — test combinations of characteristics that interact

By nature:
  Automated    — code-based tests (e.g., ArchUnit rules, load tests)
  Manual       — review processes, governance gates

Fitness Functions in Practice

A fitness function for service coupling might be an automated ArchUnit rule that fails the build if any service in the order domain imports a class from the payment domain directly.

A fitness function for performance might be a Gatling load test run in CI that fails if the p99 response time exceeds 200ms under 1,000 concurrent users.

A fitness function for security might be a OWASP ZAP scan that runs weekly and alerts if new high-severity vulnerabilities are introduced.

Why Fitness Functions Matter

Architecture tends to degrade over time through architectural drift — the gradual accumulation of small decisions that each seem locally reasonable but collectively move the system away from its intended structure. Fitness functions automate the detection of this drift, turning architectural intent into executable tests.

Without fitness functions:
  Architecture intent ---> Design ---> Implementation
                                          |
                                     Drift occurs silently

With fitness functions:
  Architecture intent ---> Design ---> Implementation
                               |               |
                           Fitness fn       Drift detected
                           (automated)      immediately

Architecture vs. Design: Keeping Definitions Simple

The authors address a chronic confusion in the field: the distinction between architecture and design.

Their position is deliberately pragmatic:

Architecture is whatever is hard to change later. Design is everything else.

This definition is operationally useful because it is context-sensitive. In a small service, choosing between a hash map and a list is design. Choosing whether the service owns its data or shares a database is architecture, because changing that decision later involves coordinating across services, potentially requiring data migrations and API renegotiations.

Why This Matters

The architecture/design distinction determines:

  • Who makes the decision (architect vs. developer)
  • How it gets documented (ADR vs. inline comment)
  • What governance applies (architecture review board vs. code review)
  • How costly reversal is (high vs. low)

The authors avoid the trap of making the definition technology-specific (“microservices are architecture, REST endpoints are design”). Instead, they anchor it in the concept of reversibility and impact, which remains stable across technology generations.


The Sysops Squad Saga

The Sysops Squad is a fictional IT support ticketing company whose system is undergoing a modernization initiative — migrating from a large monolith to a distributed architecture.

The Business Context

  • The company provides IT support for large enterprises
  • Customers file support tickets through a web portal
  • Tickets are routed to field technicians based on expertise and geography
  • Experts are dispatched to on-site locations
  • Billing, contract management, reporting, and knowledge base are all part of the system

The Problem

The existing monolithic application has accumulated years of technical debt:

  • All functionality is in a single deployable unit
  • Database schema is shared across all domains
  • Deployment is infrequent and risky
  • Teams step on each other during development
  • Individual components cannot be scaled independently

What Chapter 1 Establishes

Chapter 1 introduces the Sysops Squad to demonstrate that architectural problems are not abstract — they arise in specific business contexts with specific constraints:

  • The company has an existing team structure that affects what architectures are feasible
  • The existing data model is a constraint that limits options for decomposition
  • Business requirements (SLAs, ticket routing rules, billing cycles) impose non-negotiable correctness requirements
  • Budget and timeline constraints mean not every ideal solution is available

The saga demonstrates immediately that there is no architecture that solves all these constraints simultaneously. Trade-offs must be chosen. This sets the intellectual contract for the rest of the book.


Trade-off Summary

ApproachBenefitsCosts
MonolithSimple to deploy, single database, easy transactionsHard to scale independently, team coupling, slow deploys
MicroservicesIndependent deployability, team autonomy, targeted scalingDistributed systems complexity, data consistency challenges, operational overhead
Best practicesReduces decision fatigue, speeds onboardingHides context-dependence, ages poorly, leads to cargo-culting
Trade-off analysisContext-appropriate decisions, surfaces costsSlower decisions, requires deeper expertise
Undocumented decisionsFast in the short termKnowledge loss, repeated mistakes, inability to revisit
ADRsAuditable, revisable, teachableRequires discipline, maintenance overhead

Decision Framework

When to write an ADR: When a decision is significant (high impact if wrong), hard to reverse, or involves choosing between options that each have meaningful trade-offs.

When to use fitness functions: When you have an architectural characteristic that is important to preserve over time and can degrade silently (performance, coupling, security posture, code structure).

When to call something “architecture” vs. “design”: Ask “How costly is it to change this decision after the fact?” If the answer is “very — it requires coordinating across teams, services, or data boundaries,” it’s architecture.

When to distrust a “best practice”: Always ask what context the practice assumes. If that context does not match your context, the practice may not apply.


Key Takeaways

  1. Software architecture has no universal best practices — every decision involves trade-offs whose acceptability depends on context.
  2. The architect’s primary skill is trade-off analysis: identifying what you gain and what you sacrifice with each option.
  3. Architectural Decision Records (ADRs) make decisions explicit, auditable, and revisable — protecting institutional knowledge and enabling future teams to re-evaluate decisions with full context.
  4. Architecture fitness functions automate the enforcement of architectural intent, detecting drift before it becomes irreversible.
  5. Data is a first-class architectural concern in distributed systems — data ownership, consistency requirements, and schema evolution constrain what architectures are even possible.
  6. The distinction between architecture and design is best understood through reversibility: architecture is whatever is hard to change later.
  7. “Best practices” age poorly because they embed assumptions about technology, scale, team size, and domain that change faster than the practices themselves.
  8. The Sysops Squad saga grounds the book’s analysis in a realistic system — demonstrating that architectural problems arise from the intersection of business constraints, team structure, and technical debt.
  9. Fitness functions are borrowed from evolutionary computing and applied to architecture to create executable, objective measures of whether a system satisfies its architectural characteristics.
  10. Documenting the consequences of decisions (not just the decisions themselves) is the most valuable part of an ADR — it surfaces both what was gained and what was traded away.

  • ch02-coupling — Builds on Chapter 1’s trade-off framing by introducing the precise vocabulary of coupling in distributed architectures
  • ch03-decomposition — Applies the ADR and trade-off framework to the decision of how to decompose a monolith
  • DDIA Chapter 1 — Reliability, Scalability, Maintainability as parallel non-functional concern framing

Last Updated: 2026-05-30