Extracted Topic
Drawing correct service/module boundaries (using Bounded Contexts, coupling/cohesion analysis, and communication-pattern choice) as the foundation for microservices, event-driven, and layered architecture decisions - this is the single load-bearing skill the post repeatedly returns to (it names "drawing service boundaries" as "the hardest problem," lists boundary/decomposition and communication style as the top two of its own "five decisions" that drive 80% of architectural outcomes, and shows the same concern - domain purity, event-vs-call coupling, layer contracts - playing out identically across the layered, microservices, and EDA sections).
The Vital 20%
- Bounded Context identification (Evans' DDD) as the primary heuristic for where to cut a system into services or modules
- Coupling vs. cohesion as the evaluation lens for any proposed boundary
- Synchronous vs. asynchronous connector choice and the temporal-coupling consequences of each
- Dependency direction / interface-first design (Repository pattern, Hexagonal/Ports-and-Adapters, Dependency Inversion)
- Conway's Law as a constraint on which boundaries are actually sustainable
- Evolutionary boundary-setting: modular monolith first, extract-on-evidence (Fowler's guidance), Strangler Fig for migration
- Idempotency and eventual consistency as unavoidable costs of async boundaries
- Recognizing and naming your most expensive existing coupling (a diagnostic skill, not just a design one)
20-Hour Plan
Session 1 - Explain what a "component," "connector," and "configuration" are, and classify 5 real dependencies in a codebase you know using that vocabulary
- Core concept(s): Architectural vocabulary - components, connectors, configurations, coupling, cohesion
- Resource(s): SEI/Carnegie Mellon definition of software architecture (as cited in the post) plus Bass, Clements & Kazman, Software Architecture in Practice (3rd ed.), Ch. 1-2
- Hands-on task: Pick a real system you work in. List 10 components and, for each pair that interacts, name the connector (function call, HTTP, queue) and classify it sync/async.
- 15-min review:
- Can you define "high cohesion, low coupling" without using the word "modular"?
- Which of your 10 listed components has the most connectors, and is that a smell?
- Write one sentence distinguishing a connector from a configuration.
Session 2 - Draw a dependency-direction diagram for an existing feature and identify any layer/interface violations
- Core concept(s): Layer contracts, dependency inversion, interface vs. implementation (Parnas)
- Resource(s): Parnas (1972), "On the Criteria to Be Used in Decomposing Systems into Modules," CACM 15(12) - read the original abstract + section on information hiding; Alistair Cockburn, "Hexagonal Architecture" (alistair.cockburn.us)
- Hands-on task: Reproduce the post's TypeScript
UserRepositoryexample in a language you use daily - write a domain interface with zero infrastructure imports, then an infrastructure implementation of it. - 15-min review:
- Does your domain class import anything from your infra layer? If yes, fix it.
- What would break if you swapped Postgres for an in-memory fake - anything?
- Name one place in your real codebase where dependency direction is currently backwards.
Session 3 - Identify 2-3 candidate Bounded Contexts in a real or sample domain and justify why each deserves its own model
- Core concept(s): Bounded Contexts, ubiquitous language, the "same word means different things" signal
- Resource(s): Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software (2003), Part IV (Bounded Context chapters); Martin Fowler, "BoundedContext" (martinfowler.com/bliki/BoundedContext.html)
- Hands-on task: Take a domain term you use (e.g., "Order," "User," "Account") and write down 3 different meanings it has in 3 different parts of your system or org. Sketch the context boundary each implies.
- 15-min review:
- Produce a one-paragraph context map for your example domain.
- Which context, if any, is currently forced to share a model it shouldn't?
- What breaks if two contexts silently drift to different meanings of the same word?
Session 4 - Given a monolith module list, decide which modules are extraction candidates and which should stay, with a one-line reason each
- Core concept(s): Modular monolith, extract-on-evidence, YAGNI applied to service boundaries
- Resource(s): Sam Newman, Building Microservices (2nd ed., O'Reilly), Ch. 1-2 ("Do I even want microservices?"); Martin Fowler, "Microservices" (martinfowler.com/articles/microservices.html) - specifically the "MonolithFirst" linked essay
- Hands-on task: Take (or invent) a 6-module monolith. For each module, score it on: scaling needs, deployment frequency needed, team ownership clarity. Decide keep-vs-extract.
- 15-min review:
- Which module scored highest for extraction, and what evidence (not vibes) supports it?
- What operational cost would extracting it add (list 3 concrete things: e.g. new deploy pipeline, new datastore)?
- Restate Newman's core caution about microservices as the default.
Session 5 - Trace one Conway's Law mismatch in your own org and propose a boundary change that would remove it
- Core concept(s): Conway's Law (both directions), team-topology alignment with service boundaries
- Resource(s): Melvin Conway (1968), "How Do Committees Invent?" Datamation 14(5) - original 1-page article; supplement with Newman's Building Microservices Ch. 10 (organizational alignment)
- Hands-on task: Map your team structure against your service/module ownership. Circle any service touched regularly by 2+ teams.
- 15-min review:
- Name one service that is a "distributed monolith" because one team owns too many pieces, or one monolith fought over by too many teams.
- What boundary change would align team and system structure here?
- Why does the post say Conway's Law "cuts both ways"?
Session 6 - Choose sync vs. async for 4 realistic cross-service interactions and justify each choice by its coupling consequence
- Core concept(s): Temporal coupling, request/response vs. event publication, when async is worth the eventual-consistency cost
- Resource(s): Peter Deutsch, "The Eight Fallacies of Distributed Computing" (Sun Microsystems, 1994) - read all eight; the post's own Order/Inventory event-publishing example
- Hands-on task: Reproduce the post's
order.placedevent example (or equivalent) in a language of your choice: an emitting service that publishes an event instead of calling another service directly. - 15-min review:
- For each of your 4 interactions, which fallacy from Deutsch's list would bite hardest if you'd chosen sync instead?
- What is the "acceptable lag" for your async case, and who decided that?
- What happens if your event is delivered twice - does your code care?
Session 7 - Design an idempotent consumer for a duplicate-delivery scenario
- Core concept(s): At-least-once delivery, idempotency keys, deduplication, event versioning
- Resource(s): Post's own
handleOrderPlacedexample (schema-versioned event handling); AWS documentation, "Amazon SQS: How Amazon SQS Works - At-Least-Once Delivery" (docs.aws.amazon.com/AWSSimpleQueueService); Chris Richardson, microservices.io pattern page on "Idempotent Consumer" - Hands-on task: Write a consumer function that processes the same event twice (simulate by calling it twice with the same payload) and prove via a dedup table or key-check that the second call is a no-op.
- 15-min review:
- What field in your event carries the deduplication key?
- What breaks if that key is missing from an incoming event?
- Explain in one sentence why "exactly-once" is misleading terminology.
Session 8 - Diagnose one existing distributed-failure risk in a design (yours or a case study) and add one mitigation
- Core concept(s): Partial failure, cascading timeouts, circuit breakers, bulkheads
- Resource(s): Michael Nygard, Release It!: Design and Deploy Production-Ready Software (2nd ed.), Ch. 5 (Stability Patterns - Circuit Breaker, Bulkhead)
- Hands-on task: Take one synchronous call chain in your system (A calls B calls C). Add a circuit breaker or timeout budget around one hop, using any circuit-breaker library in your stack (e.g.,
opossumfor Node,pybreakerfor Python) or a hand-rolled version. - 15-min review:
- What timeout value did you pick, and what's it based on (p99 latency? guess?)
- What does your circuit breaker do when tripped - fail fast, fallback, or queue?
- Which upstream caller is protected now that wasn't before?
Session 9 - Write a full ADR for a real boundary decision you've made or are facing
- Core concept(s): Documented architectural reasoning, options-with-tradeoffs framing
- Resource(s): Michael Nygard, "Documenting Architecture Decisions" (cognitect.com blog, 2011) - the original ADR proposal; the post's own ADR-0012 example as a template
- Hands-on task: Using the post's ADR template exactly (Status/Context/Decision Drivers/Options Considered/Decision/Consequences), write a real ADR for a boundary or communication-pattern decision from your own work.
- 15-min review:
- Did writing the ADR change your actual decision? If so, how?
- Which option did you reject, and can you state its strongest counter-argument fairly?
- Is your decision explicitly revisable - what would trigger revisiting it?
Session 10 - Plan a Strangler Fig migration for one bounded piece of an existing monolith
- Core concept(s): Evolutionary migration, incremental boundary extraction, fitness functions for boundary integrity
- Resource(s): Martin Fowler, "StranglerFigApplication" (martinfowler.com/bliki/StranglerFigApplication.html); Neal Ford, Rebecca Parsons & Patrick Kua, Building Evolutionary Architectures (O'Reilly, 2017), Ch. 3 (Fitness Functions)
- Hands-on task: Pick one module identified in Session 4 as an extraction candidate. Write the 3-step traffic-routing plan (old path / dual-write or facade / new path) and one automated fitness-function check (e.g., a lint rule or CI check) that would catch domain-layer imports from infrastructure.
- 15-min review:
- What routes traffic during the transition - a facade, feature flag, or proxy?
- What is your rollback plan if the new service misbehaves mid-migration?
- Write the one CI check you'd add to prevent this boundary from eroding again.
What This Plan Deliberately Skips
Container orchestration/Kubernetes mechanics, observability tooling setup (OpenTelemetry, Prometheus), CAP theorem proofs and formal consistency models, and general non-functional-requirement elicitation (performance/security tactics in the abstract) - all real per the post, but downstream of getting boundaries right, not prerequisite to it.