Bird
Raised Fist0

Synchronous vs Asynchronous Communication - When Each Wins

HLDmediumInterview freq: high
Choose your preparation mode4 modes available
▶
Request Trace
Step 1/7
API Gateway (Nginx + Envoy)

Receives client request and routes based on operation type

Determines if request is synchronous or asynchronous

Protocol:HTTP/1.1 or HTTP/2
BeforeClient request just arrived at API Gateway
AfterRequest routed to synchronous service or Kafka for async
Synchronous Service (gRPC/HTTP2)

Processes synchronous request immediately

Reads/writes data directly from/to Cassandra

Protocol:gRPC/HTTP2
BeforeRequest arrived at synchronous service
AfterResponse generated after DB interaction
Database (Cassandra)

Handles read/write for synchronous request

Stores or retrieves data as requested

Protocol:CQL
BeforeSynchronous service issued DB query
AfterData persisted or fetched for sync response
Kafka Cluster

Queues asynchronous request event

Durably stores event for later processing

Protocol:Kafka
BeforeAPI Gateway routed async request to Kafka
AfterEvent durably stored in Kafka topic
Asynchronous Worker Pool

Consumes event from Kafka and processes task

Performs DB operations asynchronously

Protocol:Kafka
BeforeEvent available in Kafka topic
AfterTask processed and results stored
Database (Cassandra)

Persists results from async worker

Writes processed data asynchronously

Protocol:CQL
BeforeAsync worker prepared data to store
AfterData persisted for async request
Result Store (Redis + Cassandra)

Caches or stores final results for fast retrieval

Supports quick reads for both sync and async results

Protocol:Redis GET/SET and CQL
BeforeProcessed data available in DB
AfterResults cached and ready for client queries
🏗️
Architecture Diagram
Architecture Diagram
┌───────────────────────────────┐
│ API Gateway                   │
│ (Nginx + Envoy)               │
└───────────────┬───────────────┘
                │ HTTP/1.1 or HTTP/2
                ▼
┌───────────────────────────────┐
│ Synchronous Service           │
│ (gRPC/HTTP2)                  │
└───────────────┬───────────────┘
                │ gRPC/HTTP2
                ▼
┌───────────────────────────────┐
│ Database (Cassandra)          │
└───────────────┬───────────────┘
                │ CQL
                ▼
┌───────────────────────────────┐
│ Result Store                  │
│ (Redis + Cassandra)           │
└───────────────────────────────┘

                ▲
                │ Kafka
┌───────────────┴───────────────┐
│ Kafka Cluster                 │
└───────────────┬───────────────┘
                │ Kafka
                ▼
┌───────────────────────────────┐
│ Asynchronous Worker Pool      │
└───────────────┬───────────────┘
                │ CQL
                ▼
┌───────────────────────────────┐
│ Database (Cassandra)          │
└───────────────┬───────────────┘
                │ CQL
                ▼
┌───────────────────────────────┐
│ Result Store                  │
│ (Redis + Cassandra)           │
└───────────────────────────────┘

This architecture contrasts synchronous and asynchronous communication paths. The API Gateway routes requests based on latency and durability needs. Synchronous requests flow directly to the Synchronous Service, which interacts with Cassandra for immediate response, suitable for low-latency operations. Asynchronous requests are published to Kafka, decoupling client interaction from processing. The Asynchronous Worker Pool consumes Kafka events, processes tasks, and writes results back to Cassandra. Redis caches results for fast retrieval. This design balances real-time responsiveness with scalable, durable background processing, illustrating when each communication style wins.

Primary Focus

✓

Practice

(1/5)
1. A high-traffic web application experiences multiple clients simultaneously requesting the same expired cache key, causing a sudden spike in backend load. Which component or strategy best prevents this thundering herd problem?
easy
A. Implement a distributed lock or mutex around cache regeneration
B. Use a simple cache with a short TTL to ensure freshness
C. Increase backend server capacity to handle peak load
D. Use a CDN to cache all dynamic content indefinitely

Solution

  1. Step 1: Identify the cause of thundering herd

    Multiple clients request the same expired cache key simultaneously, causing backend overload.
  2. Step 2: Evaluate prevention strategies

    Distributed locks or mutexes ensure only one client regenerates the cache, preventing backend overload.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Distributed locking serializes cache regeneration, preventing thundering herd [check]
Hint: Distributed locks serialize cache rebuilds to prevent stampedes [OK]
Common Mistakes:
2. In a primary-replica replication system, at step 4 the replica receives a batch of write-ahead log entries from the primary. What is the replica's exact state after applying these entries?
easy
A. Replica marks entries as committed and acknowledges primary before applying
B. Replica applies entries to its data store and then acknowledges primary
C. Replica applies entries and immediately serves reads from them before acknowledgment
D. Replica buffers entries without applying until primary confirms commit

Solution

  1. Step 1: Trace replica behavior at step 4

    Replica applies WAL entries to its local store to catch up with primary.
  2. Step 2: Understand acknowledgment timing

    Replica acknowledges primary only after applying entries to ensure durability and consistency.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Replica applies then acknowledges -> ensures data durability [check]
Hint: Apply WAL entries before ack -> durability ensured [check]
Common Mistakes:
3. A messaging system must handle 925K message writes per second and fan-out delivery to millions of users with minimal latency. Which component best decouples message ingestion from fan-out delivery to ensure durability and scalability?
easy
A. Use a relational database with row-level locking for message storage and fan-out
B. Use HTTP polling from clients to fetch new messages periodically
C. Use Redis pub/sub for message delivery to all subscribers
D. Use a distributed log system like Kafka partitioned by conversation ID

Solution

  1. Step 1: Identify Kafka's role in decoupling ingestion and delivery

    Kafka partitions by conversation ID to guarantee ordering and durability, allowing high write throughput and asynchronous fan-out.
  2. Step 2: Eliminate other options

    Relational DB with locking can't handle high write concurrency; Redis pub/sub lacks durability and persistence; HTTP polling adds latency and load.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Kafka partitions -> durable, ordered, scalable message ingestion [check]
Hint: Kafka partitions ensure durable, ordered, scalable ingestion [OK]
Common Mistakes:
4. At 10x scale of global traffic, which component in the BGP-based routing infrastructure is most likely to fail first, and why?
hard
A. Edge routers, because their CPU cannot handle the increased packet forwarding rate
B. Route reflectors, because they become overwhelmed maintaining full routing tables and propagating updates
C. Network monitoring systems, because data volume exceeds processing capacity causing delayed alerts
D. Client devices, because they cannot process rapid route changes at scale

Solution

  1. Step 1: Identify bottleneck at scale

    Edge routers handle packet forwarding at line rate; at 10x traffic, their CPU and forwarding ASICs are stressed first.
  2. Step 2: Evaluate other components

    Route reflectors (A) scale better with hierarchical design; monitoring systems (C) can be scaled horizontally; client devices (D) are downstream and less critical for routing stability.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Edge routers' CPU overload causes first failure at 10x traffic [check]
Hint: Edge routers hit CPU limits first at massive scale [check]
Common Mistakes:
5. At 10x scale of concurrent users, which component in a typeahead autocomplete system using Elasticsearch and Trie is most likely to become the bottleneck first, and why?
hard
A. The Trie servers, because in-memory Tries are stateful and cannot be easily sharded or distributed across nodes
B. The client-side UI, because rendering large autocomplete result sets slows down user experience
C. The prefix hash map, because storing all prefixes for billions of entries exceeds memory limits quickly
D. The Elasticsearch cluster, because fuzzy queries require heavy CPU and memory, causing query latency spikes

Solution

  1. Step 1: Analyze statefulness and scalability

    Trie servers hold large in-memory state and are difficult to shard due to pointer-based node structures, limiting horizontal scaling.
  2. Step 2: Compare other components

    Elasticsearch scales horizontally with shards; prefix hash map can be partitioned or replaced; client UI is less likely the first bottleneck at backend scale.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Trie statefulness limits sharding -> bottleneck at scale [check]
Hint: Trie stateful, hard to shard -> first bottleneck at scale [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard