System Design: Design Principles and Patterns

Master Single Responsibility at system scale, Loose Coupling vs High Cohesion, Domain-Driven Design (DDD), Bounded Contexts, Anti-Corruption Layers, Eventual Consistency & CRDTs, and Read-Heavy vs Write-Heavy system design.

1. Single Responsibility at System Level & Loose Coupling vs High Cohesion

At the architecture level, the Single Responsibility Principle (SRP) dictates that each microservice must encapsulate a single distinct business domain and maintain its own private datastore. High Cohesion ensures related logic lives together, while Loose Coupling ensures services communicate asynchronously via events without fragile dependencies.

System-Level Single Responsibility Principle (SRP) & Private Datastores

System Design

Encapsulating Auth, Orders, and Payments into independent microservice boundaries

100%
Loading system design canvas…

Tight Coupling Cascading Failure Hazard vs Loose Coupling Event-Driven Mesh

System Design

Replacing synchronous HTTP chains with asynchronous Kafka/EventBridge event streams

100%
Rendering diagram…

Tight Coupling Hazards

Synchronous RPC chains multiply unreliability.

  • Cascading Outages: If Service D has a 1% error rate, upstream services A, B, and C fail
  • Deployment Gridlock: Services must be deployed simultaneously due to shared models
  • Shared Database Anti-Pattern: Multiple services querying the same SQL database tables

Loose Coupling & High Cohesion

Building autonomous resilient microservices.

  • High Cohesion: Order calculations, discounts, and line items live in Order Service
  • Asynchronous Events: Order emits "OrderPlaced" event; downstream services react independently
  • Database Per Service: Strict zero-sharing of persistence layers

2. Domain-Driven Design (DDD) Basics & Tactical Building Blocks

Domain-Driven Design (DDD) (Eric Evans) aligns software design with complex business domains through an agreed Ubiquitous Language and clear tactical building blocks.

DDD Tactical Building Blocks & Aggregate Consistency Boundary

System Design

Aggregate Root, Entities, Value Objects, and Domain Event publishing

100%
Loading system design canvas…

1. Entities vs Value Objects

Identity vs Immutable Attributes.

  • Entity: Defined by unique identity (e.g. Order ID: "ord_123")
  • Value Object: Defined by attributes with no identity (e.g. Money($50, USD)); immutable

2. Aggregate Root

Enforcing transactional consistency.

  • Consistency Boundary: Encapsulates child entities and value objects
  • All external mutations must pass through the Root methods to guarantee business rules

3. Domain Events

Capturing state changes as events.

  • Immutable record of something that occurred (e.g. "PaymentReceivedEvent")
  • Published asynchronously to message brokers

Domain-Driven Design (DDD) Order Aggregate Root & Domain Event Dispatcher in TypeScript

A TypeScript aggregate root that encapsulates Order invariants and dispatches domain events on state changes.

3. Bounded Contexts & The Anti-Corruption Layer (ACL) Pattern

A Bounded Context defines the explicit boundary within which a domain model and its ubiquitous language apply. A "User" in the Auth context has a different data model than a "Customer" in the Billing context. When integrating with legacy systems, an Anti-Corruption Layer (ACL) translates foreign schemas to protect the clean domain model.

Bounded Contexts & Anti-Corruption Layer (ACL) Integration Map

System Design

Preventing legacy monolithic schema leaks into modern cloud microservices

100%
Rendering diagram…

Context Mapping Patterns in Microservices

Managing relationships across domain boundaries.

  • Anti-Corruption Layer (ACL): Adapter layer translating legacy payloads into clean domain entities
  • Shared Kernel: A small, mutually agreed-upon subset of the domain shared between two teams
  • Customer-Supplier: Upstream team provides APIs tailored to the downstream team's requirements

4. Eventual Consistency Trade-offs & CRDT Convergence

Distributed systems operating across multiple datacenters sacrifice strict immediate consistency for high availability (CAP Theorem AP / BASE model). Replicas synchronize in the background, achieving Eventual Consistency. Conflict-Free Replicated Data Types (CRDTs) guarantee deterministic convergence without expensive distributed locks.

Eventual Consistency Conflict-Free Convergence with CRDT PN-Counters

System Design

Mathematical merge functions resolving concurrent writes across multi-region replicas

100%
Rendering diagram…

BASE vs ACID in Distributed Systems

Trading immediate consistency for global availability.

  • Basically Available: System remains operational despite node failures
  • Soft State: System state may drift temporarily between replicas
  • Eventual Consistency: Replicas converge once updates cease

Conflict-Free Replicated Data Types (CRDTs)

Lock-free mathematical consistency.

  • Commutative & Associative: Update order does not affect the final result
  • PN-Counter: Tracks positive increments and negative decrements separately
  • Used in: Collaborative editors (Figma, Google Docs), Redis Enterprise, and chat apps

Conflict-Free Replicated Data Type (PN-Counter CRDT) in Node.js

A PN-Counter CRDT implementation that merges concurrent increments and decrements without conflicts.

5. Read-Heavy vs Write-Heavy System Design

System design requires tailoring storage and compute engines to the expected Read-to-Write ratio of the application.

Read-Heavy vs Write-Heavy Architectural Paradigms Comparison

System Design

Contrasting CDN edge caching and read replicas against LSM-Tree sequential logs and Kafka write buffering

100%
Loading system design canvas…

Read-Heavy Optimizations (Twitter, Wikipedia)

Minimizing read latency across high query volumes.

  • Multi-Tier Caching: In-memory Redis + CDN Edge caching (CloudFront)
  • Read Replicas: Horizontally scaling read-only database replicas
  • Denormalized CQRS: Precomputing views into search engines (Elasticsearch)

Write-Heavy Optimizations (IoT, Financial Ledgers)

Maximizing ingestion throughput without disk I/O bottlenecks.

  • LSM-Trees (Cassandra/RocksDB): Appending writes sequentially to Memtable and WAL
  • Write Buffering: Ingesting into Kafka message queues and flushing in bulk batches
  • Sharding: Partitioning writes across nodes by Device ID or Hash

Knowledge Check

1. What is the definition of High Cohesion and Loose Coupling in system design?

2. What role does an Anti-Corruption Layer (ACL) play in Bounded Contexts?

3. What characterizes an Aggregate Root in Domain-Driven Design (DDD)?

4. How do Conflict-Free Replicated Data Types (CRDTs) achieve eventual consistency?

5. What architectural pattern is primary in Read-Heavy systems (e.g. Twitter Feed)?