homeproject
blog
search..K
search..K

Navigation

Home
Projects
Writings

Connect

Email
GitHub
Twitter / X
LinkedIn

Latest Writing

04 Articles
01/Deep Learning Foundations: Gradient Descent, Multilayer Backpropagation Calculus & Loss Optimization
02/How Neural Networks Learn: Activation Functions, Weight Initialization & Optimization Dynamics
03/Mermaid Architectural Diagram Studio: Full Design & Color Stress Test
04/Calculus & Geometry: 2D Function Analysis, Tangent Slopes & Interactive Curve Plotting

© 2026 Ayush Kumar.•All rights reserved.

Sitemap•

Built with Next.js & Tailwind

Distributed System Design: High-Throughput Fan-Out Patterns & Event Messaging
Home/Writings/System Design

Distributed System Design: High-Throughput Fan-Out Patterns & Event Messaging

System DesignDistributed SystemsArchitectureMessagingAWS

In distributed architectures, fan-out is the core design pattern used to decouple a single event producer from multiple downstream processing pipelines. Whether you are broadcasting order creation events, handling real-time social feed ingestion, or triggering parallel audit logs, fan-out guarantees that a single write can trigger NNN independent asynchronous operations concurrently.


1. System Topology: SNS to SQS Distributed Fan-Out

Rendering Mermaid Architecture Diagram...

2. Architectural Comparison: Fan-Out on Write vs. Fan-Out on Read

Selecting the wrong fan-out strategy is one of the most common causes of cascading database failures under traffic spikes.

Fan-Out on Write (Push Model)

When an event occurs, the producer (or dispatcher) immediately broadcasts the payload to every subscriber's queue. Each worker materializes the result into localized storage.

  • Pros: Read requests are near-instant (O(1)O(1)O(1) lookup time) because data is pre-computed.
  • Cons: Write amplification (O(N)O(N)O(N) writes for NNN subscribers). High-cardinality producers (e.g. users with millions of followers) create extreme write spikes.

Fan-Out on Read (Pull Model)

Events are recorded into a centralized append-only log. Downstream services fetch and aggregate data only when a read request is received.

  • Pros: Write phase is extremely fast (O(1)O(1)O(1) append).
  • Cons: High read latency (O(K)O(K)O(K) query cost to aggregate KKK sources at query time).
Metric / DimensionFan-Out on Write (Push)Fan-Out on Read (Pull)
Write ComplexityO(N)O(N)O(N) write amplificationO(1)O(1)O(1) single append
Read Latency⚡ p99<5msp99 < 5\text{ms}p99<5ms (Pre-computed)🐢 p99>150msp99 > 150\text{ms}p99>150ms (On-demand joins)
Storage OverheadHigh (Duplicated per consumer)Low (Single log record)
Failure IsolationHigh (Isolated consumer queues)Medium (Shared read bottleneck)
Best ForE-commerce orders, Billing, NotificationsHigh-fanout social feeds (Celebrity problem)

3. Mathematical Model of Buffer Capacity & Consumer Scale

To prevent message loss during burst traffic, queue depth Q(t)Q(t)Q(t) is governed by the rate of producer emission λ(t)\lambda(t)λ(t) minus total worker consumption capacity:

Q(t)=∫0t(λ(τ)−μ⋅W)dτQ(t) = \int_{0}^{t} \left( \lambda(\tau) - \mu \cdot W \right) d\tauQ(t)=∫0t​(λ(τ)−μ⋅W)dτ

Where:

  • λ(t)\lambda(t)λ(t) is the incoming message rate per second.
  • μ\muμ is the processing capacity of a single worker instance (msgs/sec\text{msgs/sec}msgs/sec).
  • WWW is the current auto-scaled worker count.

If λ(t)>μ⋅W\lambda(t) > \mu \cdot Wλ(t)>μ⋅W, the queue buffers messages without dropping requests. To prevent infinite memory growth, visibility timeouts and Dead Letter Queues (DLQs) isolate poison-pill messages after KKK failed retries.


4. Implementing Idempotent Fan-Out Dispatchers

Because message queues guarantee at-least-once delivery, workers MUST be strictly idempotent. Below are production implementations in TypeScript, Python, and Go:

1import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
2import { SQSClient, ReceiveMessageCommand, DeleteMessageCommand } from "@aws-sdk/client-sqs";
3import { Redis } from "ioredis";
4
5const sns = new SNSClient({ region: "us-east-1" });
6const redis = new Redis(process.env.REDIS_URL!);
7
8export interface OrderEvent {
9 eventId: string;
10 orderId: string;
11 amount: number;
12 currency: string;
13 timestamp: string;
14}
15
16// 1. Publish Event to Fan-Out Topic
17export async function publishOrderEvent(event: OrderEvent, topicArn: string): Promise<string> {
18 const command = new PublishCommand({
19 TopicArn: topicArn,
20 Message: JSON.stringify(event),
21 MessageDeduplicationId: event.eventId,
22 MessageGroupId: event.orderId,
23 });
24
25 const response = await sns.send(command);
26 return response.MessageId!;
27}
28
29// 2. Idempotent Consumer Worker with Redis Deduplication
30export async function processBillingQueueMessage(message: { Body?: string; ReceiptHandle?: string }): Promise<void> {
31 if (!message.Body) return;
32
33 const event: OrderEvent = JSON.parse(message.Body);
34 const lockKey = `idempotency:billing:${event.eventId}`;
35
36 // Atomic SETNX (Set if Not Exists) with 24h TTL
37 const acquired = await redis.set(lockKey, "PROCESSING", "EX", 86400, "NX");
38
39 if (!acquired) {
40 console.log(`[Idempotency] Event ${event.eventId} already processed or in-flight. Skipping.`);
41 return;
42 }
43
44 try {
45 // Process payment transaction
46 await executePaymentCharge(event);
47 await redis.set(lockKey, "COMPLETED", "EX", 86400);
48 } catch (err) {
49 await redis.del(lockKey); // Release lock for retry
50 throw err;
51 }
52}
53
54async function executePaymentCharge(event: OrderEvent): Promise<void> {
55 // Payment gateway logic...
56}

5. Key Resilience Principles

  1. Dead Letter Queue (DLQ) Isolation: Route poison-pill messages to a DLQ after K=3K=3K=3 consecutive failures to prevent blocking worker pools.
  2. Exponential Backoff with Jitter: Avoid thundering herd problems on downstream databases when recovering from an outage: Tsleep=min⁡(Tmax,  Tbase×2attempt)+rand(0,jitter)T_{\text{sleep}} = \min\left(T_{\text{max}}, \; T_{\text{base}} \times 2^{\text{attempt}}\right) + \text{rand}(0, \text{jitter})Tsleep​=min(Tmax​,Tbase​×2attempt)+rand(0,jitter)
  3. Idempotency Key Enforcement: Store processed message IDs in Redis or Postgres with TTL to prevent duplicate execution during network retries.
Recommended Reading

Hand-picked related technical articles

Mermaid Architectural Diagram Studio: Full Design & Color Stress Test
MermaidArchitecture
Mermaid Architectural Diagram Studio: Full Design & Color Stress Test

An intensive architectural showcase featuring 10 custom-colored Mermaid diagrams—from microservice topology and database ER schemas to concurrent WebRTC audio pipelines and state machines.

Aug 16, 2026
Read Article
Open Knowledge Format (OKF): The Universal Protocol for AI Agent Memory & Documentation
AI AgentsKnowledge Systems
Open Knowledge Format (OKF): The Universal Protocol for AI Agent Memory & Documentation

A comprehensive architectural guide to OKF—bridging human documentation, deterministic AI agent graph navigation, and the future of context assembly beyond naive RAG.

Jun 28, 2026
Read Article
How Neural Networks Learn: Activation Functions, Weight Initialization & Optimization Dynamics
Machine LearningNeural Networks
How Neural Networks Learn: Activation Functions, Weight Initialization & Optimization Dynamics

An in-depth, mathematical and interactive guide into how neural networks learn—exploring activation non-linearities (Sigmoid, ReLU, Tanh), Xavier/He weight initialization, learning rate schedules, and optimization dynamics.

Aug 16, 2026
Read Article
Multivariable Calculus: 3D Quadric Surfaces, Implicit Equations & Interactive WebGL Geometry
3DGeometry
Multivariable Calculus: 3D Quadric Surfaces, Implicit Equations & Interactive WebGL Geometry

An architectural and mathematical deep dive into 3D implicit surfaces—exploring spheres, paraboloids, hyperboloids, and tori using interactive Three.js WebGL visualizations.

Aug 12, 2026
Read Article