Software architecture cheat sheet
Software, solution and enterprise architecture on a few screens: quality attributes and the tactics behind them, when to pick each architecture style, who owns which data, integration patterns, an ADR template, the C4 levels, cloud cost levers, strangler-fig migration, and the enterprise basics of capability maps, value streams and the TIME portfolio model. Keep it open during design reviews and roadmap planning.
The architect's job on one line
Find the few decisions that are expensive to change, make them on purpose with the people affected, write them down, and keep checking that the system still matches them. Everything else, let the team decide quickly (The architect's job, Design reviews).
Quality attributes and tactics
Turn every "-ility" into a scenario with a number: source, stimulus, environment, response, measure. "During the festival peak, 4 times the normal 60,000 orders a day, checkout p95 stays under 800 ms" can be tested; "checkout must be fast" cannot (Quality attributes).
| Attribute | Scenario to write | Tactics to reach for | Lesson |
|---|---|---|---|
| Performance | p95 latency at peak load | Caching, indexes, async work in queues, fewer network hops | Quality attributes, Caching |
| Scalability | Load the system must take next year, and how fast it grows | Stateless services, horizontal scaling, partitioning, read replicas | Scale up vs out |
| Availability | SLO such as 99.9% a month, and allowed downtime | Redundancy, health checks, failover, graceful degradation | p99 and SLOs |
| Resilience | What the user sees when a dependency fails | Timeouts, retries with backoff, circuit breakers, bulkheads, fallbacks | Timeouts and retries |
| Modifiability | How long a typical change takes and how many teams it touches | Clear module boundaries, low coupling, high cohesion, stable interfaces | Architecture styles |
| Security | Who may do what, and what happens when an account is stolen | Least privilege, defence in depth, encryption, audit logs | Security |
| Observability | Time to find the cause of a slow request | Structured logs, metrics, traces, a request id everywhere | Observability |
| Data integrity | What must never be lost or duplicated (payments, stock) | Transactions, idempotency keys, outbox, reconcilers | Outbox and sagas |
| Cost | Cost per order or per store per month | Right-sizing, autoscaling, storage tiers, fewer moving parts | Cloud and cost |
| Deployability | How often and how safely you can release | CI/CD, feature flags, backward-compatible changes, canaries | Shipping |
Trade-offs that keep coming back
Attributes pull against each other. Name the trade-off out loud in the review instead of hiding it (Quality attributes, CAP and consistency).
- Consistency or availability during a network split (CAP), and latency or consistency the rest of the time.
- Performance or modifiability: caches and denormalized copies are fast but are more to keep in step.
- Independence or simplicity: more services means more freedom for teams and more operations work.
- Security or convenience: every extra step at login costs some users.
- Cost or resilience: a second region doubles some bills.
Architecture styles: when to pick which
Start with the simplest style that meets the scenarios. Mangrove's order platform is still one NestJS modular monolith shared by four teams; it splits out a service only when a scenario demands it (Architecture styles, Service boundaries).
| Style | Good when | Costs you | Lesson |
|---|---|---|---|
| Monolith | One small team, a new product, unclear domain | Grows into a "big ball of mud" without boundaries | Architecture styles |
| Modular monolith | A few teams in one codebase; the default for most companies | Needs discipline: modules talk through interfaces, own their tables | Service boundaries |
| Microservices | Many teams that must deploy and scale independently; clear, stable domains | Network failures, distributed data, many pipelines, on-call per service | Service boundaries |
| Event-driven | Several parts react to the same business event (order placed, stock received) | Harder to follow a flow; needs idempotent consumers and good tracing | Architecture styles, Queues and jobs |
| Layered | Simple apps with CRUD screens | Business rules leak across layers; changes cut through every layer | Architecture styles |
| Hexagonal (ports and adapters) | Core rules must be tested without the database or vendors | More interfaces and files | Architecture styles |
| Serverless functions | Spiky or rare workloads, glue between services | Cold starts, vendor limits, harder local testing | Cloud and cost |
| Offline-first clients | Tills, scanners and riders on patchy networks | Sync, conflict rules, versioned clients in the field | Offline sync |
If you see X, reach for Y
Most architecture problems show up as team pain long before they show up as outages.
| You see | Reach for first | Then, if needed | Lesson |
|---|---|---|---|
| Every change touches five modules | Redraw boundaries around business capabilities | Move code and data together into one module | Data ownership |
| Two services write the same table | Give the table one owner; others call its API or read its events | A read-only copy fed by events | Data ownership |
| Releases wait for other teams | Backward-compatible contracts and feature flags | Split the deployable along team lines | Service boundaries |
| A chain of synchronous calls fails often | Timeouts, fewer hops, cache reference data | Events and a local copy instead of a call | Timeouts and retries |
| Saved in the database but the event never went out | Transactional outbox | CDC as the relay | Outbox and sagas |
| A process spans services and can half-fail | Saga with compensating actions | An orchestrator with a state machine | Outbox and sagas |
| The cloud bill grows faster than orders | Cost per order dashboard; tag every resource by team | Right-size, reserve steady load, delete idle environments | Cloud and cost |
| Nobody remembers why something was built this way | Write ADRs for new decisions from today | Reconstruct ADRs for the three most painful old ones | ADRs and C4 |
| An old system nobody dares to touch | Characterization tests, then strangler fig | Anti-corruption layer around it | Legacy migration |
| Three apps do the same job in three departments | App portfolio review with the TIME model | One target platform with a migration roadmap | App portfolio |
Data ownership rules
- Every table has exactly one owning module or service. Only the owner writes it (Data ownership).
- Others get data through the owner's API, its published events, or a read-only copy they keep themselves.
- Name one source of truth for each key fact: stock on hand, price, customer address (Capability maps).
- Copies are allowed; disagreement is not. Decide which copy wins and how it catches up.
- No shared database between services that deploy separately: it couples their releases and their schemas (Service boundaries).
- Reporting reads from a warehouse fed by events or CDC, not from production tables (Data stores).
Integration patterns
How the Store app, POS, Partner app and warehouse systems exchange data at Mangrove (Architecture styles, Queues and jobs).
| Pattern | Use when | Watch out for | Lesson |
|---|---|---|---|
| Synchronous API call | The caller needs the answer now (price check, stock reservation) | Latency adds up; set timeouts; the callee's outage becomes yours | APIs |
| Queue (point to point) | Work one worker should do once (send receipt, resize image) | At-least-once delivery: handlers must be idempotent | Queues and jobs |
| Pub/sub events | Several systems react to one fact (order placed) | Event schema becomes a contract; version it | Queues and jobs |
| Change data capture | Stream a database's changes to search, warehouse or caches | Exposes table structure; publish clean events where you can | Data stores |
| Batch file transfer | Old systems, suppliers, nightly finance exports | Late data, partial files; validate and quarantine bad rows | POS sales sync |
| Webhook | An outside system tells you something happened | Verify signatures; expect duplicates and lost calls | No overselling |
| API gateway or backend-for-frontend | Many clients need one entry point, auth and rate limits | Keep business rules out of the gateway | Architecture styles |
| Anti-corruption layer | A legacy or vendor model would leak into your design | One more layer to maintain | Legacy migration |
ADR template
One decision per record, about one page, kept in the repository next to the code (for example docs/adr/0007-modular-monolith.md). Never edit an accepted ADR's decision; write a new one that supersedes it (ADRs and C4).
# ADR 0007: Keep the order platform a modular monolith
Status: Accepted (2026-03-02). Supersedes: none.
Deciders: Nadia (tech lead), Ken (EM), platform team.
## Context
4 teams (about 30 engineers) share one NestJS app and one Postgres.
Festival peak is 4x normal (240,000 app orders a day).
Pain today: modules call each other's tables directly.
## Options
1. Split into 6 microservices now.
2. Modular monolith: modules own their tables, talk via interfaces and events.
3. Do nothing.
## Decision
Option 2. Revisit when one module needs its own scaling or release cadence.
## Consequences
+ One deploy, one database, simple on-call.
+ Boundaries ready if we split later.
- Needs a lint rule that blocks cross-module imports.
- One bad migration can still affect everyone.C4 model: four zoom levels
Draw only the levels your audience needs. Most teams keep levels 1 and 2 up to date and draw level 3 when a container is complex. Every box has a name, a type and one line on what it does; every arrow says what flows and how (ADRs and C4).
| Level | Shows | Mangrove example | Audience |
|---|---|---|---|
| 1. System context | Your system, its users and the other systems around it | Order platform, customers, riders, payment provider, warehouse system | Everyone, including execs |
| 2. Container | Deployable or runnable parts: apps, APIs, databases, queues | Mangrove app, NestJS API, Postgres, Redis, job queue, Back office | Engineers, ops, security |
| 3. Component | Main modules inside one container | Orders, Slots, Stock and Payments modules in the API | The team that owns it |
| 4. Code | Classes and functions | Generated from code, if at all | Rarely needed |
Cloud and cost levers
Measure cost per unit of business (per order, per store, per active user), not just the monthly total. Then pull the levers in this order (Cloud and cost, FinOps).
| Lever | How | Typical effect | Lesson |
|---|---|---|---|
| Delete waste | Idle environments, unattached disks, old snapshots, forgotten test clusters | Quick wins, no risk | FinOps |
| Right-size | Match instance size to measured CPU and memory | Often large savings on over-provisioned servers | Cloud and cost |
| Schedule | Turn off dev and test outside working hours | Those environments run about a third of the week | FinOps |
| Commit | Reserved capacity or savings plans for steady base load | Lower unit price in exchange for a 1 or 3 year commitment | Cloud and cost |
| Autoscale and spot | Scale with traffic; interruptible capacity for batch jobs | Pay for peaks only during peaks | Cloud and cost |
| Storage tiers | Lifecycle rules move old files and logs to cheaper tiers | Matters once logs and images pile up | Cloud and cost |
| Data transfer | CDN for public files, keep chatty services in one zone | Egress is easy to overlook | Files and CDNs |
| Build or buy | Compare total cost of ownership, including people and on-call | A managed service often costs less than the engineers to run your own | Build or buy |
Legacy migration: strangler fig, step by step
Replace an old system piece by piece behind a routing layer, instead of a big-bang rewrite. Mangrove used it to move goods received notes (GRN) off the old store back office (Legacy migration).
- Put a facade or proxy in front of the old system so every call passes through one place.
- Write characterization tests that record what the old system does today, bugs included.
- Pick one thin slice with clear value and low risk (for example "view GRN history").
- Build it in the new system; route a few stores (start with S-014) to it; compare results in shadow mode.
- Move data with a one-way sync first, then switch the source of truth when the slice is stable.
- Repeat slice by slice. Remove old code as each slice moves, so you never run two full systems forever.
- Decommission: switch off, archive the data, cancel the licence. Put the date in the plan.
Enterprise architecture basics
Enterprise architecture looks at the whole company: what it must be able to do, how value reaches customers, and which applications support that (Why EA).
| Tool | What it is | Mangrove example | Lesson |
|---|---|---|---|
| Capability map | What the business does, as stable nouns, independent of org chart and systems; 2 or 3 levels deep | Sourcing, Inventory management, Store operations, Last-mile delivery, Customer payments | Capability maps |
| Heat map | Capabilities coloured by importance and how well they are supported today | Inventory accuracy (82%) marked red: high importance, weak support | Capability maps |
| Value stream | Stages that deliver one outcome to a customer, end to end | "Get groceries delivered": browse, order, pick, deliver, resolve issues | Value streams |
| Application portfolio | Every application with owner, cost, users, capabilities supported and health | Three stock-count tools across regions | App portfolio |
| Target state and roadmap | Where the landscape should be in 2 or 3 years, and the steps to get there | One inventory platform; old tools retired by store region | Target and roadmap |
| Governance | Light rules: principles, an architecture review for one-way doors, standards | "Buy for commodity capabilities, build for differentiating ones" | Governance |
TIME model for the app portfolio
Score each application on business value and technical health, then place it in one of four boxes (Gartner's TIME model) (App portfolio).
| Box | Business value | Technical health | Action |
|---|---|---|---|
| Tolerate | Low | Good | Keep running, minimal spend, no new features |
| Invest | High | Good | Fund and extend; it is a platform to build on |
| Migrate | High | Poor | Move its capability to a new platform (strangler fig) |
| Eliminate | Low | Poor | Retire it and move or archive its data |
Design review questions
- Which quality scenarios drive this design, with numbers?
- Which decisions are one-way doors, and are they in an ADR?
- Who owns each piece of data, and what is the source of truth?
- What happens when each dependency is slow or down?
- How do we deploy, roll back and migrate data without downtime?
- What does it cost per order at today's load and at the festival peak?
- How will we know it works in production (metrics, alerts, dashboards)?
- What would make us revisit this decision?
See Design reviews.
Glossary
Plain definitions of the terms used most in the Architecture line.
- Quality attribute
- A measurable property of a system such as performance, availability or modifiability. Quality attributes
- Quality attribute scenario
- A testable statement of a quality goal: stimulus, environment, response and a measure. Quality attributes
- Tactic
- A design technique that improves one quality attribute, such as caching for performance. Quality attributes
- Coupling
- How much one part must change when another changes; lower is better. Architecture styles
- Cohesion
- How closely the things inside one module belong together; higher is better. Architecture styles
- Bounded context
- A part of the domain where each term has one clear meaning and one model, often owned by one team. Service boundaries
- Modular monolith
- One deployable application with strong internal module boundaries. Service boundaries
- Microservices
- Small services deployed separately, each owning its own data. Service boundaries
- Event-driven architecture
- Parts of a system communicate by publishing and reacting to events. Architecture styles
- Hexagonal architecture
- Business logic in the centre with ports, and adapters that connect it to databases, APIs and UIs. Architecture styles
- Data ownership
- The rule that exactly one module or service may write a given piece of data. Data ownership
- Source of truth
- The one place whose copy of a fact wins when copies disagree. Data ownership
- Outbox pattern
- Writing an event to a table in the same transaction as the data, then publishing it. Outbox and sagas
- Saga
- A long business process split into local steps, each with a compensating action. Outbox and sagas
- ADR (architecture decision record)
- A one-page note recording one decision, its context, options and consequences. ADRs and C4
- C4 model
- Four zoom levels for diagrams: context, container, component and code. ADRs and C4
- Fitness function
- An automated check that a system still meets an architecture goal, such as a test that blocks cross-module imports. ADRs and C4
- One-way door
- A decision that is expensive or impossible to reverse; it deserves slow review. Design reviews
- FinOps
- The practice of making engineering, finance and product share responsibility for cloud cost. FinOps
- Total cost of ownership (TCO)
- All costs of a system over its life: licences, cloud, people, support and exit. Build or buy
- Strangler fig
- Replacing a legacy system piece by piece behind a routing layer until the old one can be switched off. Legacy migration
- Anti-corruption layer
- A translation layer that keeps a legacy or vendor model from leaking into your own design. Legacy migration
- Capability
- Something the business must be able to do, independent of who does it or which system supports it. Capability maps
- Value stream
- The end-to-end stages that deliver one outcome to a customer. Value streams
- TIME model
- Tolerate, Invest, Migrate, Eliminate: four actions for an application portfolio based on value and health. App portfolio
- Target architecture
- The planned future state of systems and capabilities, with a roadmap to reach it. Target and roadmap
- Architecture governance
- The light rules and reviews that keep decisions consistent across teams. Governance
Courses on Kolom
- Software and Solution Architecture: quality attributes, styles, data ownership, cost, ADRs and C4, and legacy migration.
- Business and Enterprise Architecture: capability maps, value streams, portfolio, target state and governance.
- Distributed Systems: consistency, retries, service boundaries, outbox and sagas.
- System Design Case Studies: running a design review on real Mangrove problems.
- Finance for Tech Teams: FinOps, business cases and build or buy in money terms.
What to read next
- Software Architecture in Practice by Len Bass, Paul Clements and Rick Kazman. The source of quality attribute scenarios and tactics.
- Fundamentals of Software Architecture by Mark Richards and Neal Ford. A broad, practical tour of styles and trade-offs.
- The C4 model by Simon Brown at c4model.com.
- Martin Fowler's articles at martinfowler.com, including "StranglerFigApplication" and "MonolithFirst".
- ADR examples and templates collected at adr.github.io.
- Building Evolutionary Architectures by Neal Ford, Rebecca Parsons and Patrick Kua, on fitness functions.