About this article
This article is the entry point of the “Software Architecture” category in the Architecture Crash Course for the Generative-AI Era series, surveying the domain at the bird’s-eye level.
Layered, DDD, hexagonal, clean, microservices, modular monolith — this is the most ideologically fragmented field in the entire stack. This article surveys the major structural patterns and gives you the practical decision axis: “can our scale, skill, and timeline actually run this?”
A full list of all articles in this category, with summaries and learning points, is available at the following page.
Before you read this
This article is mostly about development: programs and APIs. If IT vocabulary is unfamiliar, reading the primer "Programs and APIs" first makes it far easier to follow. You can also look anything up in the glossary as you read.
What is software architecture in the first place
Imagine a building’s structural design. Timber, steel, or reinforced concrete — the choice of skeleton determines the scale you can build, the ease of renovation, and the structure’s lifespan. Interior design (application architecture) sits on top of this skeleton, so changing the skeleton later is an enormously expensive undertaking.
Software architecture is the domain that decides an application’s overall structure — monolith, modular monolith, microservices, etc. It encompasses skeletal decisions such as language selection, API design, and DB connection strategy.
If you start development without deciding the software architecture, as the codebase grows the code tangles together, and every change breaks something unexpected.
Why software architecture matters
Structural choices cannot be undone later. Migrating from monolith to microservices costs closer to “rebuilding” than “remodeling.” The structure you pick at the start determines the team’s development velocity, scalability, and operational burden.
A mismatch between scale and architecture is fatal. A 3-person team running microservices gets crushed by operations; a 100-person team maintaining a monolith jams the deploy pipeline. Choosing the structure that matches your organization’s scale is the architect’s most important call.
The design philosophy you choose sets the lifespan of the code. Layered, DDD, Clean Architecture — philosophies abound, but the practical answer is to choose by the single criterion of “can our team run it?”
This area pairs with system architecture by focusing on “the external structure of the application — the heart of the system being constructed.” Decisions made here also propagate strongly into application architecture, so consistency between the two matters.
Every school of thought has both supporters and detractors, and social media hosts a daily holy war. But what matters in practice is not “which doctrine is truly correct” but the single question “can our team actually run it?”
Beautiful design that nobody can run is meaningless; ugly design that the team can run is a success. The decision axis is not doctrine — it is whether your scale, skills, and timeline can keep it alive.
The three big patterns of overall structure
Software architecture’s overall structure splits into three large patterns.
| Pattern | Trait | Fits |
|---|---|---|
| Monolith | Traditional structure: everything in one app | Small-to-mid scale / small teams |
| Microservices | Each capability as an independent service | Large scale / many people, many teams |
| Modular monolith | Monolith with explicit internal modular boundaries | Mid scale / preparing for future split |
In housing terms: monolith = a studio (everything in one room), modular monolith = a 3-bedroom house (rooms separated, same house), microservices = renting out each unit of an apartment building (free per unit, but keys/water/contracts handled individually). That framing maps scale to load.
Reaching for “apartment-building management” before the studio gets cramped guarantees you’ll exhaust yourself collecting rent.
Monolith against microservices is the axis everything else hangs off.
| Aspect | Monolith | Microservices |
|---|---|---|
| Ease of starting | Excellent — simple | Poor — complex |
| Small-scale ops | Excellent — easy | Bad — overkill |
| Large-scale, multi-team | Poor — frequent merge conflicts | Excellent — parallel work |
| Deploy unit | Whole app at once | Per-service |
| Blast radius | Propagates everywhere | Easier to isolate |
“Microservices from day one” is the canonical over-engineering case. Modular monolith is the current default; gradual splitting begins after the org crosses ~30 people.
“Splitting is always an option later, but unsplitting is hell.” Start with modular monolith.
A scale × software-structure ladder
In software architecture, the recommended structure is mostly determined by team headcount. Conway’s Law (the empirical observation that org structure determines system structure) is heavily in play.
The conclusion up front: 1-10 people → TypeScript single-DB monolith is plenty. Promote to modular monolith at 10-30. Carve out partial microservices once you exceed 30. As of 2026, this is the route with the lowest failure rate.
| Team size | Recommended structure | DB | Languages | API style |
|---|---|---|---|---|
| 1-3 | Monolith | 1 DB | 1 (TS, etc.) | REST |
| 3-10 | Monolith → Modular monolith | 1 DB | 1-2 | REST + some WebSocket |
| 10-30 | Modular monolith | 1-2 DBs | <=2 | REST + internal gRPC |
| 30-100 | Modular + partial microservices | Per use case | 2-3 | REST + gRPC + events |
| 100+ | Microservices (core) + modular monolith (operational domains) | Per service | 3-5 | gRPC + Kafka |
The practical floor for microservices is “30+ team members + 5+ dedicated ops engineers.” Cases like Segment’s 140-service reversal to monolith (2020), or Amazon Prime Video’s 2023 consolidation from serverless+microservices into a monolith with 90% infrastructure cost reduction, are textbook: distribution out of scale always breaks down.
Start with modular monolith. Splitting is always an option later. Unsplitting is hell.
How to choose — selection by case
If it is a new web service — a startup or early-stage SaaS
Modular monolith + TypeScript + Next.js + REST + cookie sessions. Reconciles speed of starting and ease of splitting later — the current default. Single-DB ACID, no distributed transactions: the configuration least likely to invite bugs.
If a grown small-to-mid SaaS has outgrown its monolith
Phase-migrate to modular monolith → carve out only the genuinely bottlenecked features. Full microservices migration just spikes ops cost without commensurate business value. Saga + Outbox (write the message together with the DB update so it can be reliably delivered later) only enters the picture once you actually carve something out.
If it is a core system with complex business logic — finance, insurance, healthcare
Spring Boot or ASP.NET Core + Clean or Hexagonal + DDD + strong consistency (ACID). Long-lived domains heavy with business rules pay back the investment in protecting the domain from external dependencies. OIDC + SSO foundation for unified permission management is the standard.
For a SaaS or consumer service expecting traffic spikes, Modular monolith + eventual consistency on the read path + CDN + cache layer. Keep writes strongly consistent, scale reads horizontally with eventual consistency. Healthier than premature microservices: identify the bottleneck and scale that part.
AI decision axes — A design that is easy for AI to read is easy for the team too
Architecture selection sets the ceiling for AI adoption
When having AI write code, the single biggest factor affecting accuracy is the “quality of context you can hand to AI.” If type definitions and schemas exist as code, AI reads them and generates accurate code. Conversely, if the design only lives in wiki diagrams or Slack verbal agreements, AI can’t see it and you have to manually explain it every time.
The key insight: the design properties that favor AI (explicit types, standard protocols, modular separation) are exactly what has always been considered “good design.” The AI era doesn’t demand exotic architectures — teams that have been doing good design all along benefit the most from AI.
Why monoliths are structurally advantaged for AI
In microservices, specs are scattered across multiple repos. When modifying Service A, you need the API spec from Service B, the event schema from Service C, and type definitions from shared libraries all loaded into AI’s context simultaneously — just gathering information takes effort.
In a modular monolith, all type definitions, schemas, and tests live in a single repo, so AI can reference the related code at once. Boundaries are drawn logically as modules (packages) while physically managed in one repository — this configuration is the most rational default for the AI era.
Mainstream tech stacks directly determine AI accuracy
Mainstream stacks like Next.js + TypeScript + Prisma have hundreds of thousands of implementation examples in public GitHub repositories. Because AI training data contains these patterns abundantly, the quality of generated code is stable.
For in-house frameworks or niche libraries, AI can’t reference similar public code, so it may get even basic usage wrong. Adding “has AI already been trained on this?” as a selection criterion is the 2026 reality.
Pitfalls and forbidden moves
Of the forbidden moves the individual articles cover in detail, here are the six that matter at whole-structure level.
| Forbidden move | Why it is bad → what to do instead |
|---|---|
| Going to microservices with fewer than thirty people | the same ending as Segment in 2020 — you sink into the swamp of distributed transactions |
| Choosing microservices for performance | inter-service communication overhead makes performance worse; scale vertically first |
| Adopting new technology with neither information nor people behind it | in five years nobody can write it and the project freezes |
| Running a monolith with no module boundaries | past ten people, change conflicts become constant; draw the boundaries from the start |
| Mixing five or more languages in one project | maintenance staff are spread thin; two or fewer is healthy |
| Implementing authentication yourself | it ends up full of holes; delegate to Auth0, Clerk or Firebase Auth |
Knowledge structure of this category
This category comprises 8 articles, divided into three groups that descend from the overall skeleton to individual design decisions.
Group 1 (Skeleton) decides monolith/microservices overall structure, then selects language, framework, and module partitioning to match. Choosing language or framework before overall structure causes a mismatch between structure and tools.
Group 2 (Communication) designs how modules and services connect on top of the skeleton. REST/gRPC/GraphQL selection is covered in the API article; distributed transaction handling in the Transaction article.
Group 3 (Cross-cutting) — Auth & session management spans all communications. Read alongside the Security Architecture category’s authentication article for both implementation and policy perspectives.
What you must decide — what’s your project’s answer?
For each of the following, articulate your project’s answer in 1-2 sentences. Leaving them ambiguous now will always come back as “why did we decide that?” later.
Structure, language and framework.
| Item | Examples |
|---|---|
| Overall structure | Monolith / Microservices / Modular monolith |
| Module design | Layered / Domain-Driven / Hexagonal |
| Programming language | Java / C# / Python / Go / Rust / TypeScript … |
| Framework | Spring / .NET / Next.js / Django … |
| App server | Spring Boot / Tomcat / Gunicorn / Node.js … |
Communication, authentication and transactions.
| Item | Examples |
|---|---|
| API style | REST / GraphQL / gRPC / WebSocket |
| Transaction design | ACID (the four DB consistency guarantees) / Eventual consistency / Saga (compensation-based pattern for distributed transactions) |
| Error handling | Exception policy / Retry / Circuit Breaker (cuts off calls after consecutive failures) |
| Logging | Structured logs / Correlation IDs / Aggregation backend |
| Encryption | In-transit / at-rest policy |
| Session management | Cookie / JWT (JSON Web Token, signed token) / Refresh Token |
Summary
This article served as the entry point for the “Software Architecture” category, surveying the domain.
This is an ideologically fragmented field, but the decision axis boils down to “can our team run it?” The 2026 default: modular monolith + mainstream framework + standard protocols, anchored on the principle “AI-friendly = human-friendly.”
The next article opens the deep dive: how to choose a programming language.
Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book
I hope you’ll read the next article as well.
Also popular with readers
📚 Series: Architecture Crash Course for the Generative-AI Era (23/95)
