23 articles in high level design › anti-patterns.
Learn why a single cache expiry can trigger millions of simultaneous DB reads, and how probabilistic early expiry, mutex-on-miss, and request coalescing stop it.
Understand how a mass cache invalidation event triggers a write thunderstorm, why it differs from thundering herd, and how stale-while-revalidate and background refresh prevent it.
Learn why long chains of synchronous microservice calls multiply failure probability, add latency with each hop, and how to identify and fix chattiness in your architecture.
Understand why microservices that share a database are worse than a monolith, how to detect a distributed monolith, and how to fix service boundaries without a rewrite.
Learn why distributed systems with two primaries accepting conflicting writes are dangerous, how fencing tokens and STONITH prevent data loss, and why quorum alone isn't enough.
Learn why fan-out-on-write fails for celebrity users, why fan-out-on-read fails under heavy read load, and how hybrid strategies handle both extremes in production news feed systems.
Understand why 2PC leaves participants in an indefinitely blocked state when the coordinator crashes mid-protocol, and why sagas and Raft-based consensus are used instead.
Learn why premature sharding creates expensive cross-shard queries, forces you to live with a bad shard key forever, and how to know when you actually need to shard.
Understand why splitting a small application into microservices adds distributed systems complexity before you have the scale or team size to justify it, and when to actually make the switch.
Learn why a single service that everything depends on becomes a single point of failure disguised as modularity, and how to break it apart without a full rewrite.
Understand why polling for state changes wastes resources and adds latency, when to replace it with webhooks, Server-Sent Events, or WebSockets, and how to evaluate the trade-offs.
Learn why operations without idempotency keys cause duplicate side effects on retry, how to design idempotent APIs, and why this matters most in payment and notification systems.
Learn why unbounded queues mask producer-consumer rate mismatches until they cause OOM crashes, and how backpressure, load shedding, and bounded queues prevent it.
Learn why cramming business logic, orchestration, authentication, and transformation into your API gateway creates a bottleneck and tight coupling that defeats the gateway's purpose.
Learn why Entity-Attribute-Value schema makes queries unreadable, indexes useless, and constraints impossible, and what flexible schema alternatives actually work at scale.
Learn why floating-point arithmetic silently corrupts financial calculations, how to use fixed-point integers or DECIMAL types safely, and why every cent counts in a payment system.
Learn why polymorphic foreign keys with a type discriminator break referential integrity and indexes, and what foreign key tables and typed joins look like as clean alternatives.
Learn why unbounded SELECT queries returning millions of rows crash applications, exhaust memory, and lock tables, and how cursor-based pagination solves what OFFSET cannot.
Learn why adding too many indexes degrades write performance, explodes storage, and slows query planning, and how to choose only the indexes your queries actually need.
Understand why SELECT * fetches unnecessary data, breaks column-store compression, invalidates cached query plans, and how explicit column selection fixes all three problems.
Learn why overloading NULL with multiple meanings creates three-valued logic bugs, silent query failures, and unmaintainable code, and how to use sentinel values and separate columns instead.
Learn why storing binary files as BLOBs in a relational database bloats row sizes, explodes backup times, and creates replication lag, and when object storage is always the right answer.
Learn how event-triggered synchronous calls stack latency and amplify failures across a service chain, and how async event handling breaks the coupling.