System Design Masterclass (Golang)

Answer-first: Optimal system design requires continuously balancing latency, throughput, consistency, and availability — each technical decision carries trade-offs. This series delivers deep architectural analysis, rigorous trade-off evaluation, and production-grade Go implementations for engineers building high-scale distributed systems.


[!NOTE] This series is designed for Senior Backend Engineers & Architects. We skip definitions and go straight to the technical core: formal theorem proofs, production case studies, and compilable Go code patterns used at companies like Shopee, Alipay, and PayPay.


📚 Series Syllabus

Tier 1: Core Patterns & Production Readiness

Master the foundational design patterns for optimizing individual services and storage layers.

  1. System Design Thinking & Trade-offs — CAP, PACELC & Clean Architecture

    • Formal CAP theorem proof (Gilbert & Lynch), PACELC database classification matrix, composite availability math.
    • Clean Architecture with Dependency Inversion in Go: Port/Adapter pattern with interface-driven testing.
  2. Load Balancing L4/L7 & Rate Limiting — DSR, API Gateway & Token Bucket

    • L4 vs L7 routing internals, Direct Server Return with HAProxy + Linux sysctl configuration.
    • Token Bucket rate limiting middleware in Go using golang.org/x/time/rate with per-client limiters.
  3. Caching Strategies & Cache Stampede — Singleflight, XFetch & Redis LFU

    • Write-Through vs Write-Behind vs Cache-Aside trade-off matrix with latency and data-loss analysis.
    • XFetch probabilistic early expiration (math + Go implementation), singleflight deduplication, tiered cache.
  4. Database Scaling & Connection Pool Tuning — Sharding, TiDB & PostgreSQL

    • B-Tree vs LSM-Tree storage engine internals, Range/Hash/Directory sharding strategies.
    • TiDB Percolator distributed 2PC, PostgreSQL 5–10 MB/connection overhead, database/sql pool tuning.
  5. Event-Driven Architecture & Kafka — Worker Pool, Backpressure & Exactly-Once

    • Kafka zero-copy sendfile() internals, sparse index lookup mechanism, Kafka vs RabbitMQ decision matrix.
    • Bounded Worker Pool with natural backpressure via channels, partition-aware ordered processing.

Tier 2: Advanced Reliability & Distributed Systems

Solve the hard problems that emerge when operating multi-service distributed systems at scale.

  1. Distributed Locks — Redlock Math, etcd Raft & Split-Brain Prevention

    • Redlock MIN_VALIDITY formula with clock drift math, step-by-step algorithm with mermaid flowchart.
    • Redis (AP) vs etcd (CP/Raft) decision matrix, redsync and etcd lease-based Go implementations.
  2. Idempotent API Design — Idempotency Key, SetNX Middleware & Stripe Pattern

    • Full HTTP response recorder middleware, payload hash for key-reuse detection, DB fallback schema.
    • 100-goroutine concurrent test proving mutual exclusion, exponential backoff with jitter formula.
  3. Saga Pattern & Distributed Transactions — Temporal, Outbox & Debezium

    • 2PC failure modes, Saga vs 2PC comparison, Orchestration vs Choreography trade-offs.
    • Temporal Go SDK with LIFO compensating transactions, Transactional Outbox, Debezium EventRouter config.
  4. Consistent Hashing — Virtual Nodes, Load Variance & CRC32 Ring in Go

    • Why modulo hashing fails at scale, virtual node standard deviation analysis (V=1 to V=1000 table).
    • Thread-safe CRC32 hash ring with sync.RWMutex, GetN replication, Redis Cluster hash slot routing.
  5. Observability & pprof — Memory Leak Diagnosis, CPU Profiling & GODEBUG

    • Six pprof endpoint grid with overhead percentages, inuse_space vs alloc_space decision guide.
    • 5-step heap diff memory leak diagnosis, goroutine leak detection, GODEBUG=gctrace=1 parsing.
  6. Security & API Rate Limiting — Token Bucket, Leaky Bucket & Redis Lua

    • WAF vs L7 API Gateway vs Application rate limiting, preventing client IP spoofing via PROXY protocol.
    • Local rate limiter lock contention mitigations, and production-ready Redis Lua sliding window script.
  7. Communication Protocols — gRPC vs REST vs GraphQL in Go Microservices

    • Serialization benchmarks (JSON vs Protobuf), Protobuf wire format encoding, and HTTP/3 QUIC stream transport.
    • GraphQL gateway complexity control formulas, ConnectRPC cleartext integration, and in-memory bufconn testing.

🏛️ Tier 3: Real-World Case Studies

Learn from the world’s most demanding distributed systems to understand how theory applies at extreme scale.


👉 Hire for architecture consulting if you need to solve scale challenges, optimize database performance, or design concurrency-safe systems for your organization.

gRPC vs REST vs GraphQL: Communication Protocols in Go

Answer-first: gRPC is optimized for internal microservices using binary Protobuf serialization over multiplexed HTTP/2 or HTTP/3 streams. REST uses standard JSON over HTTP/1.1 or HTTP/2, serving as the default for public APIs. GraphQL operates as an aggregator at the API gateway or Backend-for-Frontend (BFF) layer, allowing clients to query specific properties, but requires complexity limits and DataLoader batching to prevent server degradation. Prerequisite: This is Part 12 of the System Design Masterclass. Previous parts built the reliability patterns — this part covers comparing communication protocols and data formats for microservice communication. ...

June 18, 2026 · 11 min · Lê Tuấn Anh

Go API Rate Limiting: Token Bucket & Redis Lua

Answer-first: API rate limiting defends backend services by restricting request volume. Security requires a layered defense: Web Application Firewalls (WAF) block edge-level volumetric spikes, API Gateways manage L7 credentials and quotas, and application middleware enforces fine-grained business limits. Client identification must rely on validated, secure IP parsing (using the PROXY protocol or rightmost X-Forwarded-For checks). Prerequisite: This is Part 11 of the System Design Masterclass. Previous parts built the core components — this part covers securing APIs and managing client traffic spikes at scale. ...

June 18, 2026 · 9 min · Lê Tuấn Anh

Go Observability & pprof — Memory Leaks, CPU Profiling & GODEBUG

Answer-first: Go’s built-in pprof profiler provides CPU sampling, heap allocation analysis, goroutine stack inspection, and blocking profiler — all available as HTTP endpoints in running production services with minimal overhead. Heap diff between two snapshots is the fastest way to identify memory leaks. Prerequisite: This is Part 10 of the System Design Masterclass. Previous parts built the architecture — this part teaches you how to see inside a running system and diagnose production performance issues. ...

June 18, 2026 · 10 min · Lê Tuấn Anh

Consistent Hashing in Go — Virtual Nodes & CRC32 Ring

Answer-first: Consistent Hashing minimizes key remapping when cluster membership changes. Adding or removing one node from a modulo-hash cluster remaps nearly all keys (catastrophic cache miss storm). Consistent Hashing remaps only $K/N$ keys — the theoretical minimum necessary. Prerequisite: Part 9 of the System Design Masterclass. Read Part 4: Database Scaling for context on horizontal partitioning strategies. What You’ll Learn That AI Won’t Tell You Virtual Node Standard Deviation: The exact mathematical variance drop when increasing virtual node count ($V$) from 1 to 1000. RWMutex Lock Contention: Why using sync.RWMutex on the hash ring can cause lock contention under high multi-core throughput, and how to optimize with atomic values. CRC32 vs Murmur3: Why the choice of hashing algorithm on the ring impacts lookup distribution uniformity. Why Modulo Hashing Fails When Scaling Key Concept: hash(key) % N changes to hash(key) % (N+1) when a node is added, causing nearly all key-to-node mappings to change. This creates a massive cache miss storm as the entire working set must be reloaded from the database simultaneously. ...

June 18, 2026 · 8 min · Lê Tuấn Anh

Saga Pattern in Go — Temporal, Outbox Pattern & Debezium

Answer-first: The Saga Pattern coordinates distributed transactions across microservices by decomposing a large transaction into a sequence of local transactions. If any step fails, the system automatically executes compensating transactions in reverse order to undo completed steps. Each local transaction must be idempotent. Prerequisite: Part 8 of the System Design Masterclass. Read Part 7: Idempotent API Design first — compensating transactions in Saga must be idempotent. What You’ll Learn That AI Won’t Tell You Temporal Workflow Determinism: How Temporal’s event sourcing workflow engine replays Go code, and why random functions or time sleeps crash workers. Debezium EventRouter Tuning: The exact JSON configuration keys needed to customize Kafka routing keys and prevent partition ordering issues. Pivot State Analysis: Identifying the “point of no return” in a distributed saga where compensations are no longer allowed. What Are the Problems with 2PC in Microservices? Key Concept: Two-Phase Commit (2PC) is a blocking protocol with a coordinator single point of failure. If the coordinator crashes between the Prepare and Commit phases, all participants are blocked indefinitely with locks held — a catastrophic failure mode in microservices. These are the same core banking distributed transaction challenges seen in legacy systems. ...

June 18, 2026 · 8 min · Lê Tuấn Anh

Idempotent API Design in Go — Idempotency Key & Redis SetNX

Prerequisite: Part 7 of the System Design Masterclass. Read Part 6: Distributed Locks first. Idempotent API Design in Go — Idempotency Key & Redis SetNX Executive Summary & Quick Answer: Idempotent API design guarantees that retrying an identical HTTP mutation request (carrying a unique Idempotency-Key header) executes backend side-effects exactly once. Go implementations use Redis SETNX with request payload SHA-256 hashes to block duplicate requests and serve cached HTTP responses safely. ...

June 18, 2026 · 9 min · Lê Tuấn Anh

Distributed Locks in Go — Redlock Math, etcd & Split-Brain

Prerequisite: Part 6 of the System Design Masterclass. Read Part 5: Kafka & Event-Driven first. Distributed Locks in Go — Redlock Math, etcd & Split-Brain Executive Summary & Quick Answer: Distributed locks enforce mutual exclusion across independent microservice instances. Redis Redlock achieves high-performance locking across quorum master nodes with Lua-script atomicity, while etcd provides linearizable Raft-backed leases with fencing tokens to guarantee absolute safety under network partitions. Key Takeaways: Redlock Validity Formula: Lock validity equals $\text{TTL} - \text{elapsed_time} - \text{clock_drift}$; if validity $\le 0$, release immediately. Fencing Tokens: Monotonically increasing fencing tokens (e.g. etcd revision numbers) block delayed GC-paused lockholders at storage layer boundaries. Raft vs Redis Quorum: Use etcd for high-correctness financial transactions and Redis Redlock for high-throughput rate limiting or worker job distribution. What You’ll Learn That AI Won’t Tell You Redlock Clock Drift Math: Why unsynchronized system clocks (NTP drifts) allow two clients to acquire the same Redis lock, and how to verify with fencing tokens. Rsync Lock-Release Failures: The dangerous Lua script race condition when executing un-coordinated lock releases in Redis under network partitions. etcd Keep-Alive Overhead: How etcd’s HTTP/2 stream heartbeats impact cluster CPU utilization when holding thousands of concurrent locks. Why Do Race Conditions Occur in Distributed Systems? Key Concept: Race conditions occur across server processes when multiple servers independently read and then write shared state without coordination. A single-process mutex doesn’t help — you need a lock mechanism visible across all processes. ...

June 18, 2026 · 8 min · Lê Tuấn Anh

Kafka Worker Pool in Go — Backpressure & Exactly-Once

Prerequisite: Part 5 of the System Design Masterclass. Read Part 4: Database Scaling first. Kafka Worker Pool in Go — Backpressure & Exactly-Once Executive Summary & Quick Answer: High-throughput event streaming in Go leverages Kafka zero-copy sendfile() kernel transfers combined with bounded goroutine worker pools. Natural backpressure is achieved using buffered Go channels, while partition-pinned workers preserve message ordering without distributed locks. Key Takeaways: Zero-Copy Performance: Kafka bypasses user-space buffer copies via sendfile(), routing data directly from Linux page cache to network socket buffers. Channel Backpressure: Bounded Go channels automatically throttle poll loops when downstream workers reach memory capacity limits. Partition-Aware Ordering: Pinning specific Kafka partition IDs to dedicated worker goroutines maintains strict message sequence guarantees. What You’ll Learn That AI Won’t Tell You Kernel-Level sendfile() Mechanics: How zero-copy I/O bypasses the context switches between user and kernel space, preventing CPU cache invalidation. Worker Pool Partition Pinning: Why mapping partitions to specific workers is the only way to maintain order processing sequences without locking. Offset Commit Transaction Math: Implementing transactional offset commits inside Go consumers to guarantee idempotency under broker rebalances. Kafka vs RabbitMQ — When to Use Each? Key Concept: Kafka is a distributed commit log — messages are retained indefinitely, consumers manage their own offsets, and replay is possible. RabbitMQ is a message broker — messages are deleted after acknowledgment, the broker handles routing complexity, push-based delivery. They solve different problems. ...

June 18, 2026 · 8 min · Lê Tuấn Anh

Database Sharding in Go — TiDB, PostgreSQL & Connection Pools

Prerequisite: Part 4 of the System Design Masterclass. Read Part 3: Caching Strategies first. Database Sharding in Go — TiDB, PostgreSQL & Connection Pools Executive Summary & Quick Answer: Horizontal database sharding partitions SQL tables across independent database nodes using hash or range shard keys. In Go services, combining application-level shard routing with tuned database/sql connection pools (SetMaxOpenConns, SetMaxIdleConns) prevents RAM exhaustion and write bottlenecks. Key Takeaways: Shard Key Selection: High-cardinality keys (e.g. user_id) prevent write hot-spotting compared to range keys like timestamps. Connection Pooling: PostgreSQL allocates 5-10MB RAM per open backend connection; tune Go SetMaxOpenConns to avoid memory exhaustion. NewSQL Scaling: Distributed SQL databases like TiDB implement Percolator 2PC over Raft consensus groups to provide horizontal scale with full ACID semantics. What You’ll Learn That AI Won’t Tell You PostgreSQL Connection Memory Math: Why each PostgreSQL connection eats 5–10MB of server RAM, and why a naive database/sql pool configuration crashes databases. TiDB Percolator Failures: The exact edge cases where primary lock failures leave secondary locks orphaned, and how TiDB’s async lock resolver cleans them up. LSM-Tree Write Amplification: The performance penalty of Cassandra/TiKV compaction cycles on SSD disk lifespan. Vertical vs Horizontal Scaling — When to Switch? Key Concept: Vertical scaling (scale-up) increases resources on a single server — simple but has a hard physical ceiling and non-linear cost growth. Horizontal scaling (scale-out) adds more servers — no theoretical ceiling, linear cost, but significantly higher operational complexity. ...

June 18, 2026 · 9 min · Lê Tuấn Anh

Caching Strategies in Go — Cache Stampede, XFetch & Redis LFU

Prerequisite: Part 3 of the System Design Masterclass. Read Part 2: Load Balancing L4/L7 first. Caching Strategies in Go — Cache Stampede, XFetch & Redis LFU Executive Summary & Quick Answer: Caching strategies in high-traffic Go services combine Cache-Aside for read-heavy operations, Write-Through for financial records, and Write-Behind for event counters. Mitigating Cache Stampede requires golang.org/x/sync/singleflight deduplication and XFetch probabilistic early recomputation. Key Takeaways: Cache Stampede Prevention: singleflight collapses parallel cache miss requests into a single database fetch, preventing DB pool exhaustion. Probabilistic Early Refresh: XFetch evaluates $ -\beta \times \delta \times \ln(\text{rand}()) $ to recompute expiring keys before TTL reaches zero. Eviction Policies: Redis LFU (Least Frequently Used) tracks access frequency bits to retain hot items under memory pressure better than LRU. What You’ll Learn That AI Won’t Tell You XFetch Mathematical Constants: How to configure the scaling factor ($\beta$) in XFetch to balance background refresh CPU usage against cache miss rates. Redis Memory Allocation Overhead: How Redis’s internal jemalloc allocator causes memory fragmentation, and why LRU evictions don’t immediately free up RAM. Singleflight Leakage: The danger of singleflight lockups when backend queries hang indefinitely, and how to guard it using Go context timeouts. How Does Cache Stampede Happen? Key Concept: Cache Stampede (thundering herd) occurs when a popular cached key expires and multiple concurrent goroutines simultaneously detect a cache miss — then all query the database simultaneously. The burst of duplicate DB queries can exceed connection pool capacity and cause cascading failure. ...

June 18, 2026 · 10 min · Lê Tuấn Anh

Load Balancing L4/L7 in Go — DSR, Rate Limiting & API Gateway

Prerequisite: Part 2 of the System Design Masterclass. Read Part 1: System Design Thinking first. Load Balancing L4/L7 in Go — DSR, Rate Limiting & API Gateway Executive Summary & Quick Answer: L4 load balancing routes traffic at the transport layer using IP/TCP metadata with minimal CPU overhead, whereas L7 load balancing inspects HTTP headers, cookies, and URLs for intelligent content-based routing. Combining L4 Direct Server Return (DSR) with L7 Envoy API Gateways and Go token-bucket rate limiters handles peak traffic spikes smoothly. ...

June 18, 2026 · 10 min · Lê Tuấn Anh

Go System Design: CAP, PACELC & Clean Architecture Primer

Prerequisite: This is Part 1 of the System Design Masterclass series. Familiarity with basic distributed systems concepts and Go syntax is assumed. Go System Design: CAP, PACELC & Clean Architecture Primer Executive Summary & Quick Answer: System design in Go balances CAP/PACELC trade-offs across consistency, availability, and latency. Clean Architecture isolates business logic behind Go interfaces while dependency injection decouples domain layers from database and transport protocols. Key Takeaways: CAP Theorem: Network partitions force an absolute choice between Consistency (CP) and Availability (AP). PACELC Matrix: When normal operation occurs (else), systems trade off Latency (L) versus Consistency (C). Clean Architecture: Domain interfaces isolate business logic from SQL/gRPC infrastructure, enabling unit testing without mocks. What You’ll Learn That AI Won’t Tell You CAP Theorem Realities: A rigorous look at Gilbert and Lynch’s proof showing why network partitions force an absolute choice between availability and consistency. PACELC in Practice: Why latency-consistency trade-offs are the real bottleneck in healthy networks, and how Go services suffer under Spanner’s commit wait times. Clean Architecture Cost: The compilation and memory allocation overhead of interface-driven design in Go. How Do You Build System Design Thinking? Key Concept: System design mastery is built on three pillars: mastering foundational theorems (CAP, PACELC), practicing trade-off analysis on real-world case studies, and repeatedly decomposing large problems into measurable, independently scalable components. ...

June 18, 2026 · 9 min · Lê Tuấn Anh