Software Architecture

Software Architecture Overview

Software Architecture Overview

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.

Software Architecture — Article Indexen.senkohome.com/arch-intro-index-software/

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.

Three Major Software Architecture Patterns Choose partitioning that fits scale and organization. "Can we operate it" matters more than elegance Monolith Single Application User Products Payment 1 DB Studio Apartment Everything in one room Fastest to start building Simple operations & monitoring Small-Medium / Small Team "Monolith = outdated" is a misconception Microservices User Service Products Service Payment Service Delivery Service API Apartment Management Keys, water, contracts per unit Parallel development is a strength Dramatically higher operational cost Large-Scale / Many People & Teams Don't choose if under 30 people Modular Monolith Single App (Internal Division) User Products Payment 1 DB 3-bedroom House Rooms are separate but same house Operations as simple as monolith Easy to split later Medium-Scale / Preparing for Future Split When in doubt, this is the go-to "Splitting is always possible, merging back is hell." Starting with modular monolith is the iron rule
PatternTraitFits
MonolithTraditional structure: everything in one appSmall-to-mid scale / small teams
MicroservicesEach capability as an independent serviceLarge scale / many people, many teams
Modular monolithMonolith with explicit internal modular boundariesMid 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.

AspectMonolithMicroservices
Ease of startingExcellent — simplePoor — complex
Small-scale opsExcellent — easyBad — overkill
Large-scale, multi-teamPoor — frequent merge conflictsExcellent — parallel work
Deploy unitWhole app at oncePer-service
Blast radiusPropagates everywhereEasier 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 sizeRecommended structureDBLanguagesAPI style
1-3Monolith1 DB1 (TS, etc.)REST
3-10Monolith → Modular monolith1 DB1-2REST + some WebSocket
10-30Modular monolith1-2 DBs<=2REST + internal gRPC
30-100Modular + partial microservicesPer use case2-3REST + gRPC + events
100+Microservices (core) + modular monolith (operational domains)Per service3-5gRPC + 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.

Modular Monolith Architecture Image Divide a single app into modules, communicating only via interfaces Single Application (One Deployment Unit) User Controller Service Repository Entity Public API (Interface) Products Controller Service Repository Entity Public API (Interface) Payment Controller Service Repository Entity Public API (Interface) Notification Controller Service Repository Entity Public API (Interface) Direct Reference Prohibited Shared DB (One) Single repo = AI can reference all code at once Between modules, only via interface. Direct reference is prohibited Operations like monolith, structure like microservices. The go-to architecture of 2026

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 moveWhy it is bad → what to do instead
Going to microservices with fewer than thirty peoplethe same ending as Segment in 2020 — you sink into the swamp of distributed transactions
Choosing microservices for performanceinter-service communication overhead makes performance worse; scale vertically first
Adopting new technology with neither information nor people behind itin five years nobody can write it and the project freezes
Running a monolith with no module boundariespast ten people, change conflicts become constant; draw the boundaries from the start
Mixing five or more languages in one projectmaintenance staff are spread thin; two or fewer is healthy
Implementing authentication yourselfit 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.

Section Structure and Three Groups of Software Architecture From skeleton → communication → cross-cutting, descending from big picture to individual design decisions Group 1: Skeleton Define overall structure and choose tools 1. How to Choose Overall Structure Monolith / Microservices / Modular Monolith 2. How to Choose Programming Language TypeScript / Go / Rust / Java / Python 3. FW & Module Design Next.js / Spring Boot / Clean Architecture Decide structure first, then tools Group 2: Communication How to connect between modules 4. API Design REST / gRPC / GraphQL 5. Transaction Design ACID / Eventual Consistency / Saga 6. Error Handling Retry / Circuit Breaker Design communication on top of the skeleton Group 3: Cross-cutting Common themes across all communications 7. Authentication & Authorization OAuth / OIDC / JWT / RBAC 8. Session Management Cookie / JWT / Refresh Token Read alongside the Security chapter Spans all layers Designing communication without deciding the skeleton causes structure-tool mismatches

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.

ItemExamples
Overall structureMonolith / Microservices / Modular monolith
Module designLayered / Domain-Driven / Hexagonal
Programming languageJava / C# / Python / Go / Rust / TypeScript …
FrameworkSpring / .NET / Next.js / Django …
App serverSpring Boot / Tomcat / Gunicorn / Node.js …

Communication, authentication and transactions.

ItemExamples
API styleREST / GraphQL / gRPC / WebSocket
Transaction designACID (the four DB consistency guarantees) / Eventual consistency / Saga (compensation-based pattern for distributed transactions)
Error handlingException policy / Retry / Circuit Breaker (cuts off calls after consecutive failures)
LoggingStructured logs / Correlation IDs / Aggregation backend
EncryptionIn-transit / at-rest policy
Session managementCookie / 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.

📚 Series: Architecture Crash Course for the Generative-AI Era (23/95)