<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Shashank’s Substack]]></title><description><![CDATA[My personal Substack]]></description><link>https://programmingappliedai.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png</url><title>Shashank’s Substack</title><link>https://programmingappliedai.substack.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 03 Sep 2026 16:20:55 GMT</lastBuildDate><atom:link href="/__u/programmingappliedai.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Shashank Mishra]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[programmingappliedai@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[programmingappliedai@substack.com]]></itunes:email><itunes:name><![CDATA[Shashank Mishra]]></itunes:name></itunes:owner><itunes:author><![CDATA[Shashank Mishra]]></itunes:author><googleplay:owner><![CDATA[programmingappliedai@substack.com]]></googleplay:owner><googleplay:email><![CDATA[programmingappliedai@substack.com]]></googleplay:email><googleplay:author><![CDATA[Shashank Mishra]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[HLD: Design an AI Gateway for multiple LLM providers (OpenAI, Anthropic, Gemini, open-source). Explain model routing, fallback strategy, rate limiting, cost-aware scheduling, retries, and h monitoring]]></title><description><![CDATA[Below is an interview-ready HLD for an AI Gateway supporting multiple LLM providers such as OpenAI, Anthropic, Gemini, and self-hosted/open-source models]]></description><link>https://programmingappliedai.substack.com/p/hld-design-an-ai-gateway-for-multiple</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-an-ai-gateway-for-multiple</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 01 Sep 2026 16:27:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on Low-Level Design (LLD)&#8212;especially Multithreading and Concurrency&#8212;along with High-Level Design (HLD), Data Structures &amp; Algorithms (DSA), System Design, LLM/Generative AI systems, and research paper discussions, feel free to reach out.</p><p>The mentorship is tailored for interview preparation, backend engineering, distributed systems, AI infrastructure, and building a strong systems-thinking foundation.</p><p><span>&#128233; Contact: </span><a href="mailto:programmingappliedai@gmail.com">programmingappliedai@gmail.com</a></p><h1>1. Functional Requirements</h1><ol><li><p><strong>Unified LLM API</strong></p><ul><li><p>Provide a common API interface for all LLM providers.</p></li><li><p>Client should not need to know whether the request goes to OpenAI, Anthropic, Gemini, or an open-source model.</p></li></ul></li><li><p><strong>Intelligent Model Routing</strong></p><ul><li><p>Route requests based on:</p><ul><li><p>Model capability</p></li><li><p>Latency</p></li><li><p>Cost</p></li><li><p>Provider availability</p></li><li><p>Context-window requirements</p></li><li><p>Tenant preferences</p></li></ul></li><li><p>Example: route simple queries to a cheaper model and complex queries to a stronger model.</p></li></ul></li><li><p><strong>Fallback</strong></p><ul><li><p>If the selected provider/model fails, automatically route to another eligible model/provider.</p></li><li><p>Example:</p></li></ul></li></ol><pre><code><code>OpenAI &#8594; Anthropic &#8594; Gemini &#8594; Self-hosted</code></code></pre><ol><li><p><strong>Rate Limiting &amp; Quotas</strong></p><ul><li><p>Support limits at:</p><ul><li><p>Tenant/user level</p></li><li><p>API-key level</p></li><li><p>Provider level</p></li><li><p>Model level</p></li></ul></li><li><p>Support both RPM and TPM limits.</p></li></ul></li><li><p><strong>Cost-Aware Scheduling</strong></p><ul><li><p>Track input/output tokens and model prices.</p></li><li><p>Prefer the cheapest model satisfying the request&#8217;s latency and quality requirements.</p></li><li><p>Enforce tenant-level budgets.</p></li></ul></li><li><p><strong>Retries</strong></p><ul><li><p>Retry transient failures such as:</p><ul><li><p>HTTP 429</p></li><li><p>500/502/503</p></li><li><p>Connection timeout</p></li></ul></li><li><p>Use exponential backoff with jitter.</p></li><li><p>Avoid retrying permanent errors such as invalid API keys or malformed requests.</p></li></ul></li><li><p><strong>Health Monitoring</strong></p><ul><li><p>Continuously monitor:</p><ul><li><p>Error rate</p></li><li><p>Latency</p></li><li><p>Token throughput</p></li><li><p>Rate-limit responses</p></li><li><p>Provider availability</p></li></ul></li><li><p>Temporarily remove unhealthy models/providers from routing.</p></li></ul></li></ol><div><hr></div><h1>2. Non-Functional Requirements</h1><ol><li><p><strong>High Availability</strong></p><ul><li><p>Gateway should have no single point of failure.</p></li><li><p>Target availability: <strong>99.99%+</strong>.</p></li></ul></li><li><p><strong>Low Latency</strong></p><ul><li><p>Gateway overhead should ideally be <strong>&lt;10&#8211;20 ms</strong> excluding LLM latency.</p></li><li><p>Support streaming responses.</p></li></ul></li><li><p><strong>Scalability</strong></p><ul><li><p>Horizontally scale gateway instances.</p></li><li><p>Support millions of requests/day and thousands of concurrent streaming requests.</p></li></ul></li><li><p><strong>Fault Tolerance</strong></p><ul><li><p>Provider failures should not bring down the gateway.</p></li><li><p>Support retries, circuit breakers, fallback and graceful degradation.</p></li></ul></li><li><p><strong>Security</strong></p><ul><li><p>Encrypt provider API keys.</p></li><li><p>Authentication and authorization for clients.</p></li><li><p>Tenant isolation.</p></li><li><p>Don&#8217;t expose provider credentials to clients.</p></li></ul></li><li><p><strong>Observability</strong></p><ul><li><p>Distributed tracing.</p></li><li><p>Metrics and structured logs.</p></li><li><p>Track latency, cost, tokens, errors and fallback frequency.</p></li></ul></li><li><p><strong>Cost Efficiency</strong></p><ul><li><p>Avoid unnecessary calls to expensive models.</p></li><li><p>Support configurable cost budgets and routing policies.</p></li></ul></li></ol><div><hr></div><h1>3. High-Level Architecture</h1><pre><code><code>                         &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                         &#9474;     Clients      &#9474;
                         &#9474; Apps / Services   &#9474;
                         &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                  &#9474;
                                  &#9660;
                         &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                         &#9474;   API Gateway    &#9474;
                         &#9474; Auth + Validation&#9474;
                         &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                  &#9474;
                                  &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;       AI Gateway         &#9474;
                    &#9474;                          &#9474;
                    &#9474; Request Manager           &#9474;
                    &#9474; Model Router              &#9474;
                    &#9474; Rate Limiter              &#9474;
                    &#9474; Cost Manager              &#9474;
                    &#9474; Retry / Circuit Breaker   &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                 &#9474;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;                         &#9474;
                    &#9660;                         &#9660;
             &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
             &#9474; Model Router &#9474;          &#9474; Health Engine&#9474;
             &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                    &#9474;
       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
       &#9660;            &#9660;             &#9660;             &#9660;
 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488; &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
 &#9474; OpenAI   &#9474; &#9474; Anthropic &#9474; &#9474; Gemini   &#9474; &#9474; Open-source &#9474;
 &#9474; Adapter  &#9474; &#9474; Adapter   &#9474; &#9474; Adapter  &#9474; &#9474; Adapter     &#9474;
 &#9492;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496; &#9492;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496; &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
      &#9474;              &#9474;            &#9474;               &#9474;
      &#9660;              &#9660;            &#9660;               &#9660;
   OpenAI        Anthropic      Gemini       vLLM/TGI</code></code></pre><div><hr></div><h1>4. Microservices Architecture</h1><h3>1. API Gateway</h3><p>Responsibilities:</p><ul><li><p>Authentication</p></li><li><p>API-key validation</p></li><li><p>Request validation</p></li><li><p>Tenant identification</p></li><li><p>Request size limits</p></li><li><p>TLS termination</p></li></ul><pre><code><code>Client
  &#8595;
API Gateway
  &#8595;
AI Gateway</code></code></pre><div><hr></div><h3>2. Request/Inference Service</h3><p>Responsible for:</p><ul><li><p>Normalizing requests</p></li><li><p>Creating request IDs</p></li><li><p>Managing streaming/non-streaming requests</p></li><li><p>Sending request to Model Router</p></li><li><p>Returning normalized response</p></li></ul><div><hr></div><h3>3. Model Router</h3><p>Core component.</p><p>It maintains a list of candidate models:</p><pre><code><code>Request
   &#8595;
Model Router
   &#8595;
Candidate Models

GPT-X
Claude-X
Gemini-X
Llama-X</code></code></pre><p>Routing score can be:</p><pre><code><code>Score =
    capability_score
  - latency_penalty
  - cost_penalty
  - failure_penalty</code></code></pre><p>Example:</p><pre><code><code>GPT      cost = $$
Claude   cost = $
Gemini   cost = $
Llama    cost = very low</code></code></pre><p>For a simple classification request:</p><pre><code><code>Llama &#8594; selected</code></code></pre><p>For complex reasoning:</p><pre><code><code>Claude/GPT &#8594; selected</code></code></pre><div><hr></div><h3>4. Provider Adapter Service</h3><p>Each provider has a standardized adapter.</p><pre><code><code>                 AI Gateway
                     |
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9660;            &#9660;            &#9660;
    OpenAI        Anthropic     Gemini
    Adapter       Adapter       Adapter</code></code></pre><p>Adapters convert the internal format into provider-specific APIs.</p><p>Internal:</p><pre><code><code>{
  "model": "best",
  "messages": [],
  "temperature": 0.2
}</code></code></pre><p>OpenAI adapter converts it into OpenAI&#8217;s format.</p><p>Anthropic adapter converts it into Anthropic&#8217;s format.</p><p>This prevents provider-specific logic from leaking into the core gateway.</p><div><hr></div><h1>5. Rate Limiter</h1><p>Use <strong>Redis</strong> for distributed rate limiting.</p><p>Example:</p><pre><code><code>Tenant A
   &#9474;
   &#9500;&#9472;&#9472; 100 RPM
   &#9500;&#9472;&#9472; 1M TPM
   &#9492;&#9472;&#9472; $100/day

Tenant B
   &#9474;
   &#9500;&#9472;&#9472; 1000 RPM
   &#9500;&#9472;&#9472; 10M TPM
   &#9492;&#9472;&#9472; $1000/day</code></code></pre><p>Use <strong>Token Bucket</strong> or <strong>Leaky Bucket</strong>.</p><p>For LLMs, we need both:</p><pre><code><code>RPM = Requests Per Minute
TPM = Tokens Per Minute</code></code></pre><p>Example:</p><pre><code><code>Request contains 10,000 tokens

Check:
RPM quota
+
TPM quota

If either exceeded &#8594; 429</code></code></pre><div><hr></div><h1>6. Cost-Aware Scheduling</h1><p>Maintain model pricing:</p><pre><code><code>Model       Input       Output
--------------------------------
Model A     $5/M        $15/M
Model B     $1/M        $5/M
Model C     $0.2/M      $0.8/M</code></code></pre><p>For every request:</p><pre><code><code>estimated_cost =
input_tokens &#215; input_price
+
estimated_output_tokens &#215; output_price</code></code></pre><p>Router can use:</p><pre><code><code>Quality requirement
        +
Latency requirement
        +
Cost budget
        &#8595;
Candidate models
        &#8595;
Select cheapest suitable model</code></code></pre><p>Example:</p><pre><code><code>User asks:
"Translate this sentence"

Possible models:

GPT      $0.01
Claude   $0.008
Gemini   $0.004
Llama    $0.001

&#8594; Llama selected</code></code></pre><p>For complex reasoning:</p><pre><code><code>Quality requirement = HIGH

Llama &#10060;
Gemini &#9888;&#65039;
Claude &#9989;

&#8594; Claude selected</code></code></pre><div><hr></div><h1>7. Fallback Strategy</h1><p>Use <strong>priority-based fallback</strong>.</p><pre><code><code>Primary
   &#8595;
OpenAI GPT
   &#8595; failure
Anthropic Claude
   &#8595; failure
Gemini
   &#8595; failure
Self-hosted Llama</code></code></pre><p>But don&#8217;t fallback for every error.</p><h3>Retryable</h3><pre><code><code>429
500
502
503
Timeout
Connection reset</code></code></pre><h3>Non-retryable</h3><pre><code><code>400
Invalid request
Invalid API key
Context too large
Unsupported model</code></code></pre><div><hr></div><h1>8. Circuit Breaker</h1><p>Suppose OpenAI starts returning:</p><pre><code><code>70% requests &#8594; 503</code></code></pre><p>Health service marks it unhealthy.</p><pre><code><code>             OpenAI
               &#9474;
          Circuit OPEN
               &#9474;
               X
               
Requests &#8594; Anthropic</code></code></pre><p>After a cooldown:</p><pre><code><code>OPEN
 &#8595;
HALF-OPEN
 &#8595;
Send few requests
 &#8595;
Healthy &#8594; CLOSED</code></code></pre><p>This prevents sending thousands of failing requests to a broken provider.</p><div><hr></div><h1>9. Retry Strategy</h1><p>Use exponential backoff + jitter.</p><pre><code><code>Attempt 1 &#8594; immediate
Attempt 2 &#8594; 100ms
Attempt 3 &#8594; 300ms
Attempt 4 &#8594; 700ms</code></code></pre><p>With jitter:</p><pre><code><code>delay = base &#215; 2^attempt + random()</code></code></pre><p>Also enforce:</p><pre><code><code>max_retries = 2 or 3</code></code></pre><p>Important: <strong>don&#8217;t retry blindly</strong>, especially for streaming requests or requests that may have already been processed.</p><p>Use an idempotency key where supported.</p><div><hr></div><h1>10. Health Monitoring</h1><p>Create a <strong>Health Service</strong>.</p><p>Monitor every provider/model:</p><pre><code><code>Provider
 &#9500;&#9472;&#9472; Availability
 &#9500;&#9472;&#9472; P50 latency
 &#9500;&#9472;&#9472; P95 latency
 &#9500;&#9472;&#9472; P99 latency
 &#9500;&#9472;&#9472; Error rate
 &#9500;&#9472;&#9472; 429 rate
 &#9500;&#9472;&#9472; Token throughput
 &#9492;&#9472;&#9472; Cost</code></code></pre><p>Example:</p><pre><code><code>OpenAI GPT
Error Rate:    2%
P95:           1.2 sec
429 Rate:      0.5%
Status:        HEALTHY

Claude
Error Rate:    35%
P95:           5 sec
Status:        UNHEALTHY</code></code></pre><p>Router then automatically reduces or stops traffic to Claude.</p><div><hr></div><h1>11. API Design</h1><h3>Generate Completion</h3><pre><code><code>POST /v1/chat/completions</code></code></pre><p>Request:</p><pre><code><code>{
  "model": "auto",
  "messages": [
    {
      "role": "user",
      "content": "Explain distributed systems"
    }
  ],
  "temperature": 0.2,
  "max_tokens": 1000,
  "stream": true
}</code></code></pre><p>Response:</p><pre><code><code>{
  "request_id": "req_123",
  "model": "claude-x",
  "provider": "anthropic",
  "usage": {
    "input_tokens": 100,
    "output_tokens": 500
  },
  "cost": 0.004
}</code></code></pre><p>For streaming:</p><pre><code><code>Client
  &#8595;
AI Gateway
  &#8595;
Provider

token &#8594; token &#8594; token &#8594; token
  &#8593;
stream back to client</code></code></pre><div><hr></div><h3>Model Information</h3><pre><code><code>GET /v1/models</code></code></pre><p>Response:</p><pre><code><code>{
  "models": [
    {
      "id": "model-a",
      "provider": "openai",
      "context_window": 128000,
      "input_cost": 5,
      "output_cost": 15,
      "healthy": true
    }
  ]
}</code></code></pre><div><hr></div><h3>Usage</h3><pre><code><code>GET /v1/usage</code></code></pre><p>Response:</p><pre><code><code>{
  "tenant_id": "tenant_123",
  "requests": 120000,
  "input_tokens": 50000000,
  "output_tokens": 10000000,
  "cost": 245.50
}</code></code></pre><div><hr></div><h3>Routing Configuration</h3><pre><code><code>PUT /v1/routing/policy</code></code></pre><p>Request:</p><pre><code><code>{
  "strategy": "cost_optimized",
  "fallback": [
    "anthropic",
    "gemini",
    "self-hosted"
  ],
  "max_cost_per_request": 0.05
}</code></code></pre><div><hr></div><h1>12. Database Choice</h1><p>Use different databases for different workloads.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4b941b01-a662-4a89-ae30-80170d8f640c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Data                    | Database                 | Reason                          |
| ----------------------- | ------------------------ | ------------------------------- |
| Tenant/configuration    | PostgreSQL               | Strong consistency + relational |
| Model/provider metadata | PostgreSQL               | Configuration data              |
| Rate limiting           | Redis                    | Very low latency                |
| Cost/usage events       | Kafka + ClickHouse       | High-volume analytics           |
| Health metrics          | Prometheus               | Time-series metrics             |
| Logs                    | Elasticsearch/OpenSearch | Log search                      |
| Secrets                 | Vault/KMS                | Secure credential storage       |
</code></pre></div><div><hr></div><h1>13. Important DB Schemas</h1><h3>tenants</h3><pre><code><code>tenant_id PK
name
status
monthly_budget
created_at</code></code></pre><h3>models</h3><pre><code><code>model_id PK
provider
model_name
context_window
input_price
output_price
max_rpm
max_tpm
status</code></code></pre><h3>routing_policies</h3><pre><code><code>policy_id PK
tenant_id
strategy
primary_model
fallback_models
max_latency
max_cost</code></code></pre><h3>usage</h3><pre><code><code>request_id PK
tenant_id
model_id
provider
input_tokens
output_tokens
latency
cost
status
created_at</code></code></pre><div><hr></div><h1>14. Kafka Usage</h1><p>Kafka can be used for asynchronous events:</p><pre><code><code>LLM Request
     &#9474;
     &#9660;
AI Gateway
     &#9474;
     &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#8594; Provider
     &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#8594; Kafka
                         &#9474;
             &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
             &#9660;           &#9660;           &#9660;
         Cost Service  Analytics  Monitoring</code></code></pre><p>Events:</p><pre><code><code>LLM_REQUEST_COMPLETED
LLM_REQUEST_FAILED
MODEL_FALLBACK
PROVIDER_RATE_LIMITED
MODEL_HEALTH_CHANGED</code></code></pre><p>This keeps the request path fast.</p><div><hr></div><h1>15. Redis Usage</h1><p>Redis is used for:</p><pre><code><code>1. Rate limiting
2. Provider health state
3. Circuit breaker state
4. Model routing cache
5. Tenant quotas
6. Short-lived request metadata</code></code></pre><p>Example:</p><pre><code><code>rate_limit:{tenant_id}
quota:{tenant_id}
health:{provider}:{model}
circuit:{provider}</code></code></pre><div><hr></div><h1>16. Complete Request Flow</h1><pre><code><code>Client
  &#9474;
  &#9660;
API Gateway
  &#9474;
  &#9500;&#9472;&#9472; Authentication
  &#9500;&#9472;&#9472; Authorization
  &#9492;&#9472;&#9472; Request validation
  &#9474;
  &#9660;
Rate Limiter
  &#9474;
  &#9500;&#9472;&#9472; RPM check
  &#9492;&#9472;&#9472; TPM check
  &#9474;
  &#9660;
Request Service
  &#9474;
  &#9660;
Model Router
  &#9474;
  &#9500;&#9472;&#9472; Cost
  &#9500;&#9472;&#9472; Quality
  &#9500;&#9472;&#9472; Latency
  &#9500;&#9472;&#9472; Health
  &#9492;&#9472;&#9472; Tenant policy
  &#9474;
  &#9660;
Provider Adapter
  &#9474;
  &#9660;
OpenAI / Anthropic / Gemini / vLLM
  &#9474;
  &#9660;
Response
  &#9474;
  &#9500;&#9472;&#9472; Token usage
  &#9500;&#9472;&#9472; Cost calculation
  &#9500;&#9472;&#9472; Latency
  &#9492;&#9472;&#9472; Provider status
  &#9474;
  &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#8594; Kafka &#8594; Analytics
  &#9474;
  &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#8594; Client</code></code></pre><div><hr></div><h1>17. Key Interview Design Decisions</h1><p><strong>Why adapters?</strong></p><p>To isolate provider-specific APIs and allow adding a new provider without modifying routing logic.</p><p><strong>Why Redis for rate limiting?</strong></p><p>Rate limiting is on the hot path and requires low-latency atomic operations across multiple gateway instances.</p><p><strong>Why Kafka for usage?</strong></p><p>Usage events can be extremely high volume. Kafka decouples request processing from analytics, billing and monitoring.</p><p><strong>Why PostgreSQL?</strong></p><p>Tenant, model and routing configurations require transactions and strong consistency.</p><p><strong>Why Prometheus?</strong></p><p>Health and latency metrics are naturally time-series data and need efficient aggregation.</p><p><strong>How do we avoid one provider outage affecting the entire system?</strong></p><pre><code><code>Health checks
+
Circuit breaker
+
Retries
+
Fallback
+
Multi-provider routing</code></code></pre><p><strong>How do we minimize cost?</strong></p><pre><code><code>Cost-aware router
+
Model capability classification
+
Tenant budgets
+
Token estimation
+
Usage tracking</code></code></pre><p>The core idea is to make the gateway <strong>provider-agnostic</strong>: clients talk to one API, while the gateway dynamically decides <strong>which model, which provider, and whether to retry/fallback</strong>, based on <strong>cost + quality + latency + health + tenant policy</strong>.</p>]]></content:encoded></item><item><title><![CDATA[HLD: Design a Vector Database Infrastructure storing 10 billion embeddings with real-time updates. ]]></title><description><![CDATA[Explain sharding, indexing (HNSW/IVF-PQ), replication, filtering, metadata storage, and disaster recovery.]]></description><link>https://programmingappliedai.substack.com/p/hld-design-a-vector-database-infrastructure</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-a-vector-database-infrastructure</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 18 Aug 2026 16:56:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on Low-Level Design (LLD)&#8212;especially Multithreading and Concurrency&#8212;along with High-Level Design (HLD), Data Structures &amp; Algorithms (DSA), System Design, LLM/Generative AI systems, and research paper discussions, feel free to reach out.</p><p>The mentorship is tailored for interview preparation, backend engineering, distributed systems, AI infrastructure, and building a strong systems-thinking foundation.</p><p><span>&#128233; Contact: </span><a href="mailto:programmingappliedai@gmail.com">programmingappliedai@gmail.com</a></p><h2></h2><h3>1. Requirements</h3><p><strong>Functional</strong></p><ul><li><p>Store and search <strong>10B+ embeddings</strong> with configurable dimensions such as 768/1536.</p></li><li><p>Support <strong>real-time insert, update and delete</strong> of vectors.</p></li><li><p>Support approximate nearest-neighbor search using <strong>HNSW / IVF-PQ</strong>.</p></li><li><p>Support metadata filtering such as <code>tenant_id</code>, <code>category</code>, <code>timestamp</code>, etc.</p></li><li><p>Support top-K similarity search with optional filters.</p></li><li><p>Provide replication, backup and disaster recovery.</p></li></ul><p><strong>Non-functional</strong></p><ul><li><p>Search latency: <strong>&lt;100 ms p95</strong> for normal workloads.</p></li><li><p>High availability: <strong>99.99%+</strong>.</p></li><li><p>Horizontally scalable by adding nodes.</p></li><li><p>No data loss for acknowledged writes; target <strong>RPO &#8776; 0</strong> with synchronous/replicated WAL depending on deployment.</p></li><li><p>Support tenant isolation and predictable performance under noisy-neighbor workloads.</p></li></ul><div><hr></div><h1>2. High-Level Architecture</h1><pre><code><code>                        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                        &#9474;   Client / Apps  &#9474;
                        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                 &#9474;
                                 &#9660;
                       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                       &#9474;   API Gateway     &#9474;
                       &#9474; Auth / Rate Limit &#9474;
                       &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                 &#9474;
                 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                 &#9660;                                &#9660;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;              &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474; Query Coordinator&#9474;              &#9474;  Write Service  &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;              &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                 &#9474;                                &#9474;
                 &#9660;                                &#9660;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;              &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474; Query Planner   &#9474;              &#9474; WAL / Log       &#9474;
        &#9474; + Filter Engine &#9474;              &#9474; Kafka           &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;              &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                 &#9474;                                &#9474;
                 &#9660;                                &#9660;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474;              Shard Router / Metadata             &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                        &#9474;
             &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
             &#9660;          &#9660;          &#9660;
          Shard 1    Shard 2     Shard N
          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
          &#9474;Index&#9474;    &#9474;Index&#9474;     &#9474;Index&#9474;
          &#9474;HNSW &#9474;    &#9474;IVF-PQ&#9474;    &#9474;HNSW &#9474;
          &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;     &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
          &#9474;Vector&#9474;   &#9474;Vector&#9474;    &#9474;Vector&#9474;
          &#9474;Store &#9474;   &#9474;Store &#9474;    &#9474;Store &#9474;
          &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;     &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
          &#9474;Meta  &#9474;    &#9474;Meta  &#9474;    &#9474;Meta  &#9474;
          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
             &#9474;          &#9474;           &#9474;
             &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                        &#9660;
                Object Storage
               Backups / Snapshots</code></code></pre><div><hr></div><h1>3. Data Model</h1><p>A vector record can look like:</p><pre><code><code>Vector {
    vector_id
    tenant_id
    embedding
    dimension
    metadata
    created_at
    updated_at
    version
    deleted
}</code></code></pre><p>Example metadata:</p><pre><code><code>{
  "tenant_id": "tenant_123",
  "category": "electronics",
  "language": "en",
  "timestamp": 1755000000
}</code></code></pre><p>Separate vector and metadata storage is useful because metadata filtering and vector similarity have very different access patterns.</p><div><hr></div><h1>4. Sharding</h1><p>At <strong>10B vectors</strong>, a single machine is impossible.</p><p>Assume:</p><pre><code><code>10B vectors
1536 dimensions
FP32 = 4 bytes</code></code></pre><p>Raw vector storage:</p><pre><code><code>10B &#215; 1536 &#215; 4
&#8776; 61.4 TB</code></code></pre><p>And this excludes:</p><ul><li><p>HNSW index</p></li><li><p>metadata</p></li><li><p>replication</p></li><li><p>WAL</p></li><li><p>operating-system overhead</p></li><li><p>temporary indexing memory</p></li></ul><p>With 3&#215; replication, raw vector data alone becomes roughly:</p><pre><code><code>61.4 TB &#215; 3 &#8776; 184 TB</code></code></pre><p>Therefore we horizontally shard the dataset.</p><h3>Sharding strategy</h3><p>Use <strong>consistent hashing / hash-based partitioning</strong>:</p><pre><code><code>hash(tenant_id + vector_id) &#8594; shard</code></code></pre><p>For very large tenants, use:</p><pre><code><code>hash(vector_id) &#8594; shard</code></code></pre><p>rather than putting an entire tenant on one shard.</p><p>A logical partition could be:</p><pre><code><code>Partition P1 &#8594; Shard 17
Partition P2 &#8594; Shard 42
Partition P3 &#8594; Shard 83
...</code></code></pre><p>Use <strong>virtual shards</strong> so that physical nodes can be added or removed without massive data movement.</p><div><hr></div><h1>5. Query Flow</h1><p>For:</p><pre><code><code>Top K similar vectors
where category = "phone"</code></code></pre><p>the flow is:</p><pre><code><code>Client
  &#8595;
API Gateway
  &#8595;
Query Coordinator
  &#8595;
Metadata / Filter Planner
  &#8595;
Determine relevant shards
  &#8595;
Parallel ANN search
  &#8595;
Shard 1 &#8594; top K
Shard 2 &#8594; top K
Shard 3 &#8594; top K
...
  &#8595;
Merge candidates
  &#8595;
Optional exact distance calculation
  &#8595;
Global Top K
  &#8595;
Client</code></code></pre><p>If searching 100 shards and requesting <code>K=10</code>, each shard may return:</p><pre><code><code>local_top_k = 50</code></code></pre><p>Then the coordinator merges:</p><pre><code><code>100 &#215; 50 = 5000 candidates</code></code></pre><p>and performs exact distance computation on those candidates.</p><p>This gives better recall than directly returning each shard&#8217;s top 10.</p><div><hr></div><h1>6. Indexing &#8212; HNSW</h1><p><strong>HNSW</strong> creates a graph of vectors.</p><pre><code><code>        A -------- B
       /            \
      C ---- D ------ E
       \             /
        F -----------G</code></code></pre><p>Each vector is connected to nearby vectors.</p><p>Search starts from an entry point and traverses the graph toward increasingly similar vectors.</p><h3>Advantages</h3><ul><li><p>Excellent recall.</p></li><li><p>Very low query latency.</p></li><li><p>Good for relatively dynamic workloads.</p></li></ul><h3>Disadvantages</h3><ul><li><p>High memory consumption.</p></li><li><p>Expensive updates.</p></li><li><p>Large graph at 10B vectors.</p></li></ul><p>Therefore, we generally don&#8217;t maintain one gigantic HNSW graph.</p><p>Instead:</p><pre><code><code>Shard
 &#9500;&#9472;&#9472; Segment 1 &#8594; HNSW
 &#9500;&#9472;&#9472; Segment 2 &#8594; HNSW
 &#9500;&#9472;&#9472; Segment 3 &#8594; HNSW
 &#9492;&#9472;&#9472; ...</code></code></pre><div><hr></div><h1>7. Indexing &#8212; IVF-PQ</h1><p>For extremely large datasets, <strong>IVF-PQ</strong> is attractive because it substantially reduces memory/storage requirements.</p><h3>IVF</h3><p>First cluster vectors:</p><pre><code><code>             Vector Space

        C1        C2

              C3

    C4                 C5</code></code></pre><p>During search:</p><pre><code><code>Query
  &#8595;
Find nearest clusters
  &#8595;
Search only those clusters</code></code></pre><p>Instead of searching 10B vectors, we may search only vectors belonging to the closest few clusters.</p><h3>PQ</h3><p><strong>Product Quantization</strong> compresses vectors into compact codes.</p><p>For example:</p><pre><code><code>1536-dimensional vector
        &#8595;
Split into sub-vectors
        &#8595;
Quantize each sub-vector
        &#8595;
Compact code</code></code></pre><p>This significantly reduces memory requirements.</p><h3>HNSW vs IVF-PQ</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;8e86e9ec-cb68-40fd-9da3-778e0216b3a3&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Feature   | HNSW             | IVF-PQ           |
| --------- | ---------------- | ---------------- |
| Recall    | Very high        | High, tunable    |
| Latency   | Very low         | Low              |
| Memory    | High             | Much lower       |
| Updates   | Easier           | More complex     |
| 10B scale | Expensive        | More suitable    |
| Best use  | Hot/dynamic data | Massive datasets |
</code></pre></div><p>A practical architecture can use <strong>HNSW for recent/hot segments</strong> and <strong>IVF-PQ for large historical segments</strong>.</p><div><hr></div><h1>8. Real-Time Updates</h1><p>This is one of the hardest parts.</p><p>Building a huge ANN index after every write is impossible.</p><p>Use a <strong>mutable + immutable segment architecture</strong>.</p><pre><code><code>                    Incoming writes
                          &#9474;
                          &#9660;
                     WAL / Kafka
                          &#9474;
                          &#9660;
                  Mutable Memtable
                          &#9474;
                 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                 &#9660;                 &#9660;
             HNSW index       Metadata index
                 &#9474;
                 &#9660;
           Periodic flush
                 &#9474;
                 &#9660;
          Immutable Segment
                 &#9474;
                 &#9660;
         Background compaction</code></code></pre><h3>Write path</h3><pre><code><code>Client
  &#8595;
Write API
  &#8595;
WAL
  &#8595;
Replicas
  &#8595;
Memtable
  &#8595;
Realtime HNSW</code></code></pre><p>Once a segment reaches a threshold:</p><pre><code><code>Memtable &#8594; Immutable segment</code></code></pre><p>Background workers then build/optimize IVF-PQ indexes.</p><p>This gives low write latency without continuously rebuilding the entire index.</p><div><hr></div><h1>9. Updates and Deletes</h1><p>Never physically modify a huge immutable segment immediately.</p><p>For an update:</p><pre><code><code>vector_id = 123
version = 7</code></code></pre><p>write:</p><pre><code><code>version = 8</code></code></pre><p>and mark version 7 obsolete.</p><p>For delete:</p><pre><code><code>tombstone(vector_id)</code></code></pre><p>During query:</p><pre><code><code>candidate
   &#8595;
metadata/version check
   &#8595;
if deleted/old &#8594; discard</code></code></pre><p>Later, compaction removes obsolete vectors and tombstones.</p><p>This is similar to an <strong>LSM-tree style architecture</strong>.</p><div><hr></div><h1>10. Metadata Storage</h1><p>Do not store large metadata blobs inside the ANN index.</p><p>Use a separate metadata store:</p><pre><code><code>Vector ID
   &#9474;
   &#9500;&#9472;&#9472; ANN index
   &#9474;
   &#9492;&#9472;&#9472; Metadata Store
          &#9500;&#9472;&#9472; tenant_id
          &#9500;&#9472;&#9472; category
          &#9500;&#9472;&#9472; timestamp
          &#9500;&#9472;&#9472; language
          &#9492;&#9472;&#9472; attributes</code></code></pre><p>Depending on requirements:</p><ul><li><p><strong>RocksDB</strong> &#8594; local metadata/index state.</p></li><li><p><strong>PostgreSQL</strong> &#8594; transactional metadata with moderate scale.</p></li><li><p><strong>Cassandra/ScyllaDB</strong> &#8594; massive distributed metadata.</p></li><li><p><strong>Object storage</strong> &#8594; immutable historical metadata/segments.</p></li></ul><p>For 10B-scale infrastructure, I would favor a distributed KV store for metadata that needs horizontal scaling.</p><div><hr></div><h1>11. Filtering</h1><p>Filtering is tricky because:</p><pre><code><code>similarity search
+
metadata filtering</code></code></pre><p>must be performed efficiently.</p><p>Example:</p><pre><code><code>Find 20 nearest vectors
WHERE
    tenant_id = 123
    AND category = "car"
    AND language = "en"</code></code></pre><h3>Approach 1 &#8212; Pre-filter</h3><p>First identify matching IDs:</p><pre><code><code>Metadata Index
      &#8595;
1M matching vectors
      &#8595;
ANN search</code></code></pre><p>Good when filters are highly selective.</p><h3>Approach 2 &#8212; Post-filter</h3><pre><code><code>ANN search
   &#8595;
1000 candidates
   &#8595;
metadata filter
   &#8595;
20 results</code></code></pre><p>Good when filter selectivity is low.</p><h3>Better approach</h3><p>Use an adaptive planner:</p><pre><code><code>Estimate filter selectivity
        &#8595;
Highly selective?
   /           \
 Yes            No
 &#8595;               &#8595;
Pre-filter     ANN first</code></code></pre><p>For frequently used fields, maintain bitmap/inverted indexes.</p><div><hr></div><h1>12. Replication</h1><p>Each shard has multiple replicas:</p><pre><code><code>Shard 17

Replica A &#8594; Node 1
Replica B &#8594; Node 8
Replica C &#8594; Node 21</code></code></pre><p>Use <strong>3 replicas</strong> across different failure domains.</p><pre><code><code>        Shard Leader
        /     |     \
       /      |      \
 Replica 1  Replica 2  Replica 3
 Zone A      Zone B      Zone C</code></code></pre><h3>Writes</h3><pre><code><code>Client
  &#8595;
Leader
  &#8595;
WAL
  &#8595;
Replicas
  &#8595;
Quorum ACK</code></code></pre><p>For stronger durability:</p><pre><code><code>W + R &gt; N</code></code></pre><p>For example:</p><pre><code><code>N = 3
W = 2
R = 2</code></code></pre><p>A leader failure triggers leader election.</p><div><hr></div><h1>13. Read Scaling</h1><p>ANN queries are generally read-heavy.</p><p>Therefore:</p><pre><code><code>               Query Coordinator
                 /    |    \
                /     |     \
             Replica Replica Replica</code></code></pre><p>Queries can be distributed across replicas.</p><p>Use:</p><ul><li><p>replica-aware routing</p></li><li><p>load-based routing</p></li><li><p>cache-aware routing</p></li><li><p>tenant-aware routing</p></li></ul><p>Avoid sending every query to the leader.</p><div><hr></div><h1>14. Hot/Cold Architecture</h1><p>10B embeddings may not have uniform access patterns.</p><p>Use:</p><pre><code><code>HOT
 &#8595;
RAM + HNSW
 &#8595;
Warm
 &#8595;
SSD + IVF
 &#8595;
COLD
 &#8595;
Object Storage + IVF-PQ</code></code></pre><p>For example:</p><pre><code><code>Recent 100M vectors &#8594; HNSW
Older 9.9B vectors &#8594; IVF-PQ</code></code></pre><p>Search both and merge results.</p><p>This significantly reduces RAM requirements.</p><div><hr></div><h1>15. Disaster Recovery</h1><p>Use multiple layers.</p><h3>WAL</h3><p>Every mutation goes into durable WAL:</p><pre><code><code>Write
 &#8595;
WAL
 &#8595;
Vector Store</code></code></pre><p>Kafka/object storage can retain the mutation stream.</p><h3>Snapshots</h3><p>Periodically create:</p><pre><code><code>Shard snapshot
+
ANN index
+
Metadata
+
WAL checkpoint</code></code></pre><p>Store snapshots in durable object storage.</p><p>Example:</p><pre><code><code>Object Storage

bucket/
 &#9500;&#9472;&#9472; shard-001/
 &#9474;    &#9500;&#9472;&#9472; snapshot-100
 &#9474;    &#9500;&#9472;&#9472; snapshot-200
 &#9474;    &#9492;&#9472;&#9472; WAL-offset
 &#9500;&#9472;&#9472; shard-002/
 &#9492;&#9472;&#9472; ...</code></code></pre><h3>Recovery</h3><pre><code><code>Latest snapshot
      &#8595;
Restore
      &#8595;
Replay WAL
      &#8595;
Rebuild missing indexes
      &#8595;
Replica synchronization
      &#8595;
Shard becomes healthy</code></code></pre><p>For regional disaster recovery:</p><pre><code><code>Region A
  &#8595; async replication
Region B</code></code></pre><p>For critical workloads, keep a warm standby cluster.</p><div><hr></div><h1>16. Failure Handling</h1><h3>Node failure</h3><pre><code><code>Node dies
   &#8595;
Shard coordinator detects failure
   &#8595;
Route traffic to replica
   &#8595;
Create replacement replica
   &#8595;
Stream missing data</code></code></pre><h3>Replica failure</h3><p>Rebuild from:</p><pre><code><code>healthy replica
+
WAL</code></code></pre><h3>Corrupted index</h3><p>Don&#8217;t treat the ANN index as the source of truth.</p><p>The source of truth should be:</p><pre><code><code>WAL + durable vector segments</code></code></pre><p>The ANN index is a <strong>derived structure</strong>.</p><p>Therefore:</p><pre><code><code>Corrupted HNSW
      &#8595;
Delete index
      &#8595;
Rebuild from vector segments</code></code></pre><div><hr></div><h1>17. Microservices</h1><pre><code><code>API Gateway
   &#9474;
   &#9500;&#9472;&#9472; Auth / Rate Limiting
   &#9474;
   &#9660;
Query Service
   &#9474;
   &#9500;&#9472;&#9472; Query Planner
   &#9500;&#9472;&#9472; Filter Engine
   &#9492;&#9472;&#9472; Shard Router
          &#9474;
          &#9660;
      Vector Nodes
       &#9500;&#9472;&#9472; ANN Engine
       &#9500;&#9472;&#9472; Vector Store
       &#9500;&#9472;&#9472; Metadata Store
       &#9492;&#9472;&#9472; WAL Consumer

Write Service
   &#9474;
   &#9500;&#9472;&#9472; Validation
   &#9500;&#9472;&#9472; WAL Producer
   &#9492;&#9472;&#9472; Partition Router

Index Service
   &#9500;&#9472;&#9472; HNSW Builder
   &#9500;&#9472;&#9472; IVF Builder
   &#9500;&#9472;&#9472; PQ Compressor
   &#9492;&#9472;&#9472; Compaction

Metadata Service
   &#9492;&#9472;&#9472; Distributed KV Store

Snapshot Service
   &#9500;&#9472;&#9472; Checkpoint
   &#9492;&#9472;&#9472; Object Storage

Cluster Manager
   &#9500;&#9472;&#9472; Membership
   &#9500;&#9472;&#9472; Leader Election
   &#9500;&#9472;&#9472; Rebalancing
   &#9492;&#9472;&#9472; Health Checks</code></code></pre><div><hr></div><h1>18. Important APIs</h1><h3>Insert</h3><pre><code><code>POST /v1/vectors</code></code></pre><pre><code><code>{
  "id": "vec_123",
  "tenant_id": "tenant_1",
  "embedding": [0.12, 0.43, "..."],
  "metadata": {
    "category": "car",
    "language": "en"
  }
}</code></code></pre><p>Response:</p><pre><code><code>{
  "id": "vec_123",
  "version": 7,
  "status": "accepted"
}</code></code></pre><h3>Search</h3><pre><code><code>POST /v1/search</code></code></pre><pre><code><code>{
  "tenant_id": "tenant_1",
  "query_vector": [0.12, 0.43, "..."],
  "top_k": 20,
  "filter": {
    "category": "car",
    "language": "en"
  }
}</code></code></pre><p>Response:</p><pre><code><code>{
  "results": [
    {
      "id": "vec_892",
      "score": 0.94,
      "metadata": {
        "category": "car"
      }
    }
  ]
}</code></code></pre><h3>Delete</h3><pre><code><code>DELETE /v1/vectors/{id}</code></code></pre><p>Response:</p><pre><code><code>{
  "id": "vec_123",
  "status": "deleted"
}</code></code></pre><div><hr></div><h1>19. Database / Storage Choices</h1><pre><code><code>Vector data
     &#8594; SSD/Object Storage

ANN index
     &#8594; Local NVMe SSD + RAM

Metadata
     &#8594; Cassandra/ScyllaDB or distributed KV

WAL
     &#8594; Kafka

Snapshots
     &#8594; S3/GCS/Object Storage

Cluster metadata
     &#8594; etcd</code></code></pre><p>The important architectural principle is:</p><blockquote><p><strong>Don&#8217;t make the ANN index your source of truth.</strong></p></blockquote><p>Treat vectors + WAL + durable segments as the source of truth and make HNSW/IVF-PQ <strong>rebuildable derived indexes</strong>.</p><div><hr></div><h1>20. Final Architecture</h1><pre><code><code>                         Clients
                            &#9474;
                            &#9660;
                     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                     &#9474; API Gateway &#9474;
                     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                            &#9474;
                 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                 &#9660;                     &#9660;
          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
          &#9474; Query Svc   &#9474;       &#9474; Write Svc   &#9474;
          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;       &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                 &#9474;                     &#9474;
                 &#9660;                     &#9660;
          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
          &#9474;Query Planner&#9474;          &#9474;  WAL   &#9474;
          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;          &#9474; Kafka  &#9474;
                 &#9474;                 &#9492;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;
                 &#9474;                     &#9474;
                 &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                            &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474; Shard Router  &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                            &#9474;
          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
          &#9660;                 &#9660;                 &#9660;
       Shard 1           Shard 2           Shard N
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;       &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; HNSW    &#9474;       &#9474; IVF-PQ  &#9474;       &#9474; HNSW    &#9474;
     &#9474; Index   &#9474;       &#9474; Index   &#9474;       &#9474; Index   &#9474;
     &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;       &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;       &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
     &#9474;Vectors  &#9474;       &#9474;Vectors  &#9474;       &#9474;Vectors  &#9474;
     &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;       &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;       &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
     &#9474;Metadata &#9474;       &#9474;Metadata &#9474;       &#9474;Metadata &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;       &#9492;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;       &#9492;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;
          &#9474;                 &#9474;                 &#9474;
          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                            &#9660;
                     Object Storage
                    Snapshots / Backup</code></code></pre><h3>Key design decisions</h3><ol><li><p><strong>Virtual sharding</strong> enables horizontal scaling to 10B+ vectors.</p></li><li><p><strong>HNSW</strong> is used for hot/recent data where low latency and high recall matter.</p></li><li><p><strong>IVF-PQ</strong> is used for massive cold datasets to reduce memory/storage.</p></li><li><p><strong>Mutable HNSW + immutable segments</strong> enables real-time updates without rebuilding huge indexes.</p></li><li><p><strong>Metadata indexes + adaptive filtering</strong> handle vector + structured queries efficiently.</p></li><li><p><strong>3-way replication across AZs</strong> provides high availability.</p></li><li><p><strong>WAL + snapshots + replay</strong> provides disaster recovery.</p></li><li><p><strong>ANN indexes are derived data</strong>, allowing them to be rebuilt after corruption or failure.</p></li><li><p><strong>Query fan-out + local Top-K + global merge</strong> enables distributed ANN search.</p></li><li><p><strong>Hot/warm/cold tiers</strong> keep the frequently accessed vectors in RAM while cheaply storing billions of older vectors.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[HLD:Design a Multi-Agent Orchestration Platform where planner, researcher, coder, and reviewer agents collaborate. ]]></title><description><![CDATA[Explain workflow scheduling, shared memory, task routing, retries, deadlock prevention, and observability.]]></description><link>https://programmingappliedai.substack.com/p/hlddesign-a-multi-agent-orchestration</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hlddesign-a-multi-agent-orchestration</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Mon, 10 Aug 2026 17:30:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Below is an interview-ready HLD for a <strong>Multi-Agent Orchestration Platform</strong> where Planner, Researcher, Coder, and Reviewer agents collaborate.</p><p>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on Low-Level Design (LLD)&#8212;especially Multithreading and Concurrency&#8212;along with High-Level Design (HLD), Data Structures &amp; Algorithms (DSA), System Design, LLM/Generative AI systems, and research paper discussions, feel free to reach out.</p><p>The mentorship is tailored for interview preparation, backend engineering, distributed systems, AI infrastructure, and building a strong systems-thinking foundation.</p><p><span>&#128233; Contact: </span><a href="mailto:programmingappliedai@gmail.com">programmingappliedai@gmail.com</a></p><h2>1. Functional Requirements &#8212; 5 points</h2><ol><li><p><strong>Task Creation</strong></p><ul><li><p>User should be able to submit a high-level task.</p></li><li><p>Example: <em>&#8220;Build a Python service that analyzes customer transactions.&#8221;</em></p></li></ul></li><li><p><strong>Task Planning</strong></p><ul><li><p>Planner Agent decomposes the task into smaller executable subtasks.</p></li><li><p>Creates dependencies between subtasks.</p></li></ul></li><li><p><strong>Multi-Agent Collaboration</strong></p><ul><li><p>Route subtasks to appropriate agents such as Researcher, Coder, Reviewer, etc.</p></li><li><p>Agents should be able to consume outputs generated by other agents.</p></li></ul></li><li><p><strong>Workflow Execution</strong></p><ul><li><p>Execute independent tasks in parallel and dependent tasks sequentially.</p></li><li><p>Support retries, timeouts, cancellation, and failure handling.</p></li></ul></li><li><p><strong>Monitoring &amp; Results</strong></p><ul><li><p>Track task/agent status, execution history, token usage, latency, failures, and final output.</p></li><li><p>User should be able to query workflow progress and retrieve results.</p></li></ul></li></ol><div><hr></div><h2>2. Non-Functional Requirements &#8212; 5 points</h2><ol><li><p><strong>Scalability</strong></p><ul><li><p>Support thousands/millions of workflows with dynamically scalable agent workers.</p></li></ul></li><li><p><strong>Availability</strong></p><ul><li><p>Target 99.9%+ availability.</p></li><li><p>Agent/workflow failures should not cause loss of workflow state.</p></li></ul></li><li><p><strong>Low Latency</strong></p><ul><li><p>Task scheduling/routing should ideally add &lt;50&#8211;100 ms overhead.</p></li><li><p>Independent agent tasks should execute concurrently.</p></li></ul></li><li><p><strong>Reliability</strong></p><ul><li><p>At-least-once task execution with idempotent workers.</p></li><li><p>Retry transient failures using exponential backoff.</p></li></ul></li><li><p><strong>Observability &amp; Security</strong></p><ul><li><p>Distributed tracing, metrics, logs, token/cost tracking.</p></li><li><p>Tenant-level isolation and authorization for shared memory.</p></li></ul></li></ol><div><hr></div><h1>3. High-Level Architecture</h1><pre><code><code>                         &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                         &#9474;      Client      &#9474;
                         &#9474; Web / API / SDK  &#9474;
                         &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                  &#9474;
                                  &#9660;
                         &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                         &#9474;    API Gateway   &#9474;
                         &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                  &#9474;
                                  &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;   Workflow Service      &#9474;
                    &#9474;                         &#9474;
                    &#9474; Create / Pause / Resume &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                &#9474;
                                &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;   Planner Agent         &#9474;
                    &#9474;                         &#9474;
                    &#9474; Task &#8594; DAG of subtasks &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                                &#9474;
                                &#9660;
                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                  &#9474;      Task Scheduler          &#9474;
                  &#9474;                              &#9474;
                  &#9474; DAG + dependency management  &#9474;
                  &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                               &#9474;
                  &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                  &#9660;            &#9660;             &#9660;
             &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;   &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;   &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
             &#9474;Research&#9474;   &#9474; Coder  &#9474;   &#9474;Reviewer&#9474;
             &#9474; Agent  &#9474;   &#9474; Agent  &#9474;   &#9474; Agent  &#9474;
             &#9492;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;   &#9492;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;   &#9492;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9496;
                 &#9474;            &#9474;             &#9474;
                 &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                              &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;   Shared Memory    &#9474;
                    &#9474;                    &#9474;
                    &#9474; Context / Artifacts&#9474;
                    &#9474; Agent Outputs      &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;

                              &#9474;
                              &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474;   Event Bus        &#9474;
                    &#9474; Kafka / SQS        &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;

                              &#9474;
                              &#9660;
                    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                    &#9474; Observability      &#9474;
                    &#9474; Metrics / Logs /   &#9474;
                    &#9474; Traces / Cost      &#9474;
                    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
</code></code></pre><div><hr></div><h1>4. Core Workflow</h1><p>Suppose the user asks:</p><blockquote><p>&#8220;Build a REST API for analyzing transactions.&#8221;</p></blockquote><p>Planner creates:</p><pre><code><code>                Root Task
                   &#9474;
          &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
          &#9660;                 &#9660;
   Research APIs       Research DB
          &#9474;                 &#9474;
          &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                   &#9660;
              Write Code
                   &#9474;
                   &#9660;
             Run Tests
                   &#9474;
                   &#9660;
                Review
                   &#9474;
             &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
             &#9474;           &#9474;
           PASS         FAIL
             &#9474;           &#9474;
             &#9660;           &#9660;
           Done       Fix Code
                         &#9474;
                         &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#8594; Review
</code></code></pre><p>The workflow is represented as a <strong>DAG</strong>.</p><p>Each node contains:</p><pre><code><code>Task {
    task_id
    workflow_id
    agent_type
    input
    dependencies[]
    status
    retry_count
    timeout
}
</code></code></pre><div><hr></div><h1>5. Task Scheduling</h1><p>The <strong>Task Scheduler</strong> maintains the workflow DAG.</p><h3>Task lifecycle</h3><pre><code><code>PENDING
   &#8595;
READY
   &#8595;
RUNNING
   &#8595;
SUCCESS
</code></code></pre><p>Failure:</p><pre><code><code>RUNNING
   &#8595;
FAILED
   &#8595;
RETRY
   &#8595;
READY
</code></code></pre><p>After maximum retries:</p><pre><code><code>FAILED &#8594; DEAD_LETTER
</code></code></pre><h3>Scheduling algorithm</h3><p>For every completed task:</p><pre><code><code>1. Mark task SUCCESS
2. Find dependent tasks
3. Check whether all dependencies are SUCCESS
4. If yes &#8594; mark dependent task READY
5. Push task to appropriate agent queue
</code></code></pre><p>Independent tasks can therefore execute concurrently.</p><div><hr></div><h1>6. Task Routing</h1><p>Use an <strong>Agent Registry</strong>.</p><pre><code><code>Agent Registry

researcher &#8594; researcher_queue
coder      &#8594; coder_queue
reviewer   &#8594; reviewer_queue
planner    &#8594; planner_queue
</code></code></pre><p>Scheduler determines:</p><pre><code><code>task.agent_type = CODER
</code></code></pre><p>and publishes:</p><pre><code><code>Kafka:
    topic = agent.coder.tasks
</code></code></pre><p>Coder workers consume from this topic.</p><p>For dynamic routing, maintain agent metadata:</p><pre><code><code>Agent {
    agent_id
    type
    capabilities[]
    current_load
    max_concurrency
    health
}
</code></code></pre><p>Example:</p><pre><code><code>"Search latest Kafka documentation"
            &#8595;
Researcher
            &#8595;
Researcher-3
</code></code></pre><p>Routing can consider:</p><ul><li><p>capability</p></li><li><p>current load</p></li><li><p>priority</p></li><li><p>model availability</p></li><li><p>cost</p></li><li><p>region</p></li></ul><div><hr></div><h1>7. Shared Memory</h1><p>Agents shouldn&#8217;t directly depend on each other&#8217;s local memory.</p><p>Use a centralized <strong>Shared Memory Service</strong>.</p><pre><code><code>                     Shared Memory
                          &#9474;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474;                 &#9474;                 &#9474;
    Task Context       Artifacts        Agent Outputs
        &#9474;                 &#9474;                 &#9474;
    Redis/Postgres    Object Storage    Vector DB
</code></code></pre><h3>Types of memory</h3><p><strong>Short-term memory</strong></p><p>Current workflow context.</p><pre><code><code>Redis
</code></code></pre><p><strong>Durable state</strong></p><p>Workflow/task state.</p><pre><code><code>PostgreSQL
</code></code></pre><p><strong>Large artifacts</strong></p><p>Code, documents, datasets.</p><pre><code><code>S3 / Object Storage
</code></code></pre><p><strong>Semantic memory</strong></p><p>Research findings, previous knowledge.</p><pre><code><code>Vector DB
</code></code></pre><p>Agents access memory using:</p><pre><code><code>GET /workflows/{workflow_id}/context
</code></code></pre><p>and:</p><pre><code><code>POST /workflows/{workflow_id}/memory
</code></code></pre><div><hr></div><h1>8. Retry Strategy</h1><p>Not every failure should be retried.</p><h3>Retryable</h3><pre><code><code>LLM timeout
Network failure
Rate limit
Temporary DB failure
Temporary service unavailable
</code></code></pre><h3>Non-retryable</h3><pre><code><code>Invalid prompt
Invalid tool arguments
Permission denied
Invalid workflow
</code></code></pre><p>Use exponential backoff:</p><pre><code><code>retry 1 &#8594; 1 sec
retry 2 &#8594; 2 sec
retry 3 &#8594; 4 sec
retry 4 &#8594; 8 sec
</code></code></pre><p>with jitter.</p><p>Each task has:</p><pre><code><code>max_retries = 3
</code></code></pre><p>After that:</p><pre><code><code>Dead Letter Queue
</code></code></pre><div><hr></div><h1>9. Deadlock Prevention</h1><p>Since workflows are DAG-based, the system should <strong>reject cyclic dependencies</strong>.</p><p>Example invalid workflow:</p><pre><code><code>A &#8594; B
B &#8594; C
C &#8594; A
</code></code></pre><p>When creating the DAG, perform cycle detection using:</p><pre><code><code>DFS / Topological Sort
</code></code></pre><p>If:</p><pre><code><code>number_of_processed_nodes != total_nodes
</code></code></pre><p>then a cycle exists.</p><p>Return:</p><pre><code><code>400 INVALID_WORKFLOW
</code></code></pre><h3>Runtime deadlock prevention</h3><p>Also use:</p><ul><li><p>Task timeout</p></li><li><p>Workflow timeout</p></li><li><p>Lease expiration</p></li><li><p>Heartbeats</p></li><li><p>Maximum dependency depth</p></li><li><p>Maximum task execution time</p></li><li><p>Cancellation propagation</p></li></ul><p>Example:</p><pre><code><code>Worker takes task
      &#8595;
Lease = 5 minutes
      &#8595;
Worker sends heartbeat
      &#8595;
Worker crashes
      &#8595;
Lease expires
      &#8595;
Scheduler requeues task
</code></code></pre><div><hr></div><h1>10. APIs</h1><h2>Create Workflow</h2><pre><code><code>POST /v1/workflows
</code></code></pre><h3>Request</h3><pre><code><code>{
  "task": "Build a REST API for analyzing customer transactions",
  "priority": "HIGH",
  "max_retries": 3,
  "metadata": {
    "language": "python"
  }
}
</code></code></pre><h3>Response</h3><pre><code><code>{
  "workflow_id": "wf_12345",
  "status": "PLANNING",
  "created_at": "2026-08-10T17:00:00Z"
}
</code></code></pre><div><hr></div><h2>Get Workflow Status</h2><pre><code><code>GET /v1/workflows/{workflow_id}
</code></code></pre><h3>Response</h3><pre><code><code>{
  "workflow_id": "wf_12345",
  "status": "RUNNING",
  "progress": 65,
  "tasks": [
    {
      "task_id": "t1",
      "agent": "researcher",
      "status": "SUCCESS"
    },
    {
      "task_id": "t2",
      "agent": "coder",
      "status": "RUNNING"
    },
    {
      "task_id": "t3",
      "agent": "reviewer",
      "status": "PENDING"
    }
  ]
}
</code></code></pre><div><hr></div><h2>Get Workflow Result</h2><pre><code><code>GET /v1/workflows/{workflow_id}/result
</code></code></pre><h3>Response</h3><pre><code><code>{
  "workflow_id": "wf_12345",
  "status": "COMPLETED",
  "result": {
    "code_artifact": "s3://bucket/code.zip",
    "review": "Approved",
    "summary": "REST API implemented successfully"
  }
}
</code></code></pre><div><hr></div><h2>Cancel Workflow</h2><pre><code><code>POST /v1/workflows/{workflow_id}/cancel
</code></code></pre><h3>Response</h3><pre><code><code>{
  "workflow_id": "wf_12345",
  "status": "CANCELLED"
}
</code></code></pre><div><hr></div><h2>Get Shared Memory</h2><pre><code><code>GET /v1/workflows/{workflow_id}/memory
</code></code></pre><h3>Response</h3><pre><code><code>{
  "workflow_id": "wf_12345",
  "memory": [
    {
      "task_id": "t1",
      "type": "RESEARCH_RESULT",
      "content": "PostgreSQL is selected as the primary database"
    },
    {
      "task_id": "t2",
      "type": "CODE_ARTIFACT",
      "uri": "s3://bucket/code.zip"
    }
  ]
}
</code></code></pre><div><hr></div><h1>11. Microservices Architecture</h1><h3>1. API Gateway</h3><p>Responsibilities:</p><pre><code><code>Authentication
Authorization
Rate limiting
Request validation
Routing
</code></code></pre><div><hr></div><h3>2. Workflow Service</h3><p>Responsible for:</p><pre><code><code>Create workflow
Pause/resume
Cancel workflow
Workflow state
</code></code></pre><div><hr></div><h3>3. Planner Service</h3><p>Converts:</p><pre><code><code>User Goal
   &#8595;
Task DAG
</code></code></pre><p>Example:</p><pre><code><code>Research &#8594; Code &#8594; Test &#8594; Review
</code></code></pre><div><hr></div><h3>4. Scheduler Service</h3><p>Responsible for:</p><pre><code><code>DAG execution
Dependency resolution
Task prioritization
Retries
Timeouts
Task leases
</code></code></pre><div><hr></div><h3>5. Agent Router</h3><p>Routes tasks based on:</p><pre><code><code>Agent type
Capability
Load
Cost
Model
Availability
</code></code></pre><div><hr></div><h3>6. Agent Workers</h3><p>Separate worker pools:</p><pre><code><code>Researcher Workers
Coder Workers
Reviewer Workers
Planner Workers
</code></code></pre><p>Each worker can independently scale.</p><div><hr></div><h3>7. Memory Service</h3><p>Provides:</p><pre><code><code>Read context
Write context
Semantic search
Artifact references
Versioning
</code></code></pre><div><hr></div><h3>8. Artifact Service</h3><p>Stores:</p><pre><code><code>Source code
Documents
Research reports
Images
Large outputs
</code></code></pre><p>Object storage such as S3 is appropriate.</p><div><hr></div><h3>9. Event Bus</h3><p>Kafka/SQS handles:</p><pre><code><code>Task created
Task completed
Task failed
Retry task
Workflow completed
Agent events
</code></code></pre><div><hr></div><h3>10. Observability Service</h3><p>Collect:</p><pre><code><code>Metrics
Logs
Distributed traces
LLM token usage
LLM cost
Agent latency
Task retry count
Workflow success rate
</code></code></pre><div><hr></div><h1>12. Database Choice</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;21f28340-c702-4b27-beda-079ca23a9f7a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Data                | Database                 | Why                                    |
| ------------------- | ------------------------ | -------------------------------------- |
| Workflow/Task state | PostgreSQL               | Transactions + relational DAG metadata |
| Hot workflow state  | Redis                    | Low-latency reads/writes               |
| Agent queues/events | Kafka                    | Durable asynchronous processing        |
| Large artifacts     | S3/Object Storage        | Cheap, scalable blob storage           |
| Semantic memory     | Vector DB                | Similarity search                      |
| Logs                | ClickHouse/Elasticsearch | High-volume analytics/search           |
</code></pre></div><h3>PostgreSQL Schema</h3><pre><code><code>workflows
---------
workflow_id PK
tenant_id
status
priority
input
created_at
updated_at


tasks
-----
task_id PK
workflow_id FK
agent_type
status
input
output
retry_count
max_retries
timeout
created_at
updated_at


task_dependencies
-----------------
task_id
depends_on_task_id
PRIMARY KEY(task_id, depends_on_task_id)


agent_executions
----------------
execution_id PK
task_id
agent_id
started_at
completed_at
status
error
token_usage
cost
</code></code></pre><div><hr></div><h1>13. Important Design Decision: DB + Kafka</h1><p>Don&#8217;t use Kafka as the source of truth for workflow state.</p><p>Use:</p><pre><code><code>PostgreSQL = Source of Truth
Kafka      = Event/Task Transport
Redis      = Cache
</code></code></pre><p>For example:</p><pre><code><code>Task completed
     &#9474;
     &#9500;&#9472;&#9472; UPDATE PostgreSQL
     &#9474;
     &#9492;&#9472;&#9472; Publish TaskCompleted event &#8594; Kafka
</code></code></pre><p>For reliable DB &#8594; Kafka publishing, use the <strong>Transactional Outbox Pattern</strong>:</p><pre><code><code>                    PostgreSQL
                 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                 &#9474; task update &#9474;
                 &#9474; outbox event&#9474;
                 &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                        &#9474;
                  Outbox Worker
                        &#9474;
                        &#9660;
                      Kafka
</code></code></pre><p>This prevents the situation where the DB update succeeds but the Kafka event is lost.</p><div><hr></div><h1>14. End-to-End Flow</h1><pre><code><code>User
 &#9474;
 &#9660;
API Gateway
 &#9474;
 &#9660;
Workflow Service
 &#9474;
 &#9660;
Planner Agent
 &#9474;
 &#9474; Creates DAG
 &#9660;
Task Scheduler
 &#9474;
 &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
 &#9660;              &#9660;
Researcher     Researcher
 &#9474;              &#9474;
 &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
        &#9660;
      Coder
        &#9474;
        &#9660;
      Tests
        &#9474;
        &#9660;
     Reviewer
        &#9474;
    &#9484;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9488;
    &#9474;       &#9474;
  PASS     FAIL
    &#9474;       &#9474;
    &#9660;       &#9660;
  Done    Coder
            &#9474;
            &#9492;&#9472;&#9472;&#9472;&#9472;&#8594; Reviewer
</code></code></pre><p>Every agent interaction is recorded in:</p><pre><code><code>PostgreSQL &#8594; workflow/task state
Redis      &#8594; hot context
Kafka      &#8594; events/tasks
S3        &#8594; artifacts
Vector DB  &#8594; semantic memory
</code></code></pre><p>And monitored through:</p><pre><code><code>OpenTelemetry
      &#8595;
Metrics + Logs + Traces
      &#8595;
Grafana / Alerting
</code></code></pre><p><strong>Key interview point:</strong> The heart of this system is a <strong>persistent DAG-based workflow engine + asynchronous task queues + shared memory layer</strong>. The agents themselves remain stateless workers, which makes them independently scalable and allows the scheduler to handle retries, failures, timeouts, and recovery centrally.</p>]]></content:encoded></item><item><title><![CDATA[ [HLD]: Distributed Prompt Cache for LLM Cost Optimization]]></title><description><![CDATA[Multiple applications (chatbots, support assistants, coding assistants, search copilots, etc.) send repeated or similar prompts to LLM providers. Since LLM inference is expensive .]]></description><link>https://programmingappliedai.substack.com/p/hld-distributed-prompt-cache-for</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-distributed-prompt-cache-for</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 04 Aug 2026 15:11:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. Problem Statement</h2><p>Multiple applications (chatbots, support assistants, coding assistants, search copilots, etc.) send repeated or similar prompts to LLM providers. Since LLM inference is expensive and introduces latency, we need a <strong>Distributed Prompt Cache</strong> that:</p><ul><li><p>Reduces LLM API costs</p></li><li><p>Reduces response latency</p></li><li><p>Supports multiple applications and tenants</p></li><li><p>Handles exact and semantic prompt matching</p></li><li><p>Preserves privacy and security</p></li><li><p>Scales horizontally</p></li></ul><div><hr></div><h1>2. Functional Requirements</h1><h3>Core Features</h3><ul><li><p>Cache LLM responses for repeated prompts</p></li><li><p>Support exact-match lookup</p></li><li><p>Support semantic similarity lookup</p></li><li><p>Configurable TTL policies</p></li><li><p>Cache invalidation support</p></li><li><p>Multi-tenant isolation</p></li><li><p>Cache warming/pre-population</p></li><li><p>Distributed deployment</p></li></ul><h3>Non-Functional Requirements</h3><ul><li><p>High availability (99.9%+)</p></li><li><p>Low latency (&lt;20 ms cache lookup)</p></li><li><p>Horizontally scalable</p></li><li><p>Secure tenant isolation</p></li><li><p>Cost-efficient storage</p></li></ul><div><hr></div><h1>3. High-Level Architecture</h1><pre><code><code>                +----------------+
                | Applications   |
                | (Multi-tenant) |
                +-------+--------+
                        |
                        v
           +-------------------------+
           | Prompt Cache Gateway    |
           +-----------+-------------+
                       |
         +-------------+--------------+
         |                            |
         v                            v

+----------------+        +---------------------+
| Exact Cache    |        | Semantic Cache      |
| (Redis)        |        | (Vector DB)         |
+--------+-------+        +----------+----------+
         |                           |
         +------------+--------------+
                      |
                      v
            +------------------+
            | Cache Decision   |
            | Service          |
            +--------+---------+
                     |
          Cache Miss |
                     v
             +---------------+
             | LLM Provider  |
             | (GPT/Claude)  |
             +-------+-------+
                     |
                     v
             +---------------+
             | Cache Writer  |
             +---------------+
</code></code></pre><div><hr></div><h1>4. Request Flow</h1><h3>Exact Match Hit</h3><pre><code><code>User Request
      |
      v
Generate Cache Key
      |
      v
Redis Lookup
      |
      +---- HIT ----&gt; Return Response
</code></code></pre><h3>Cache Miss</h3><pre><code><code>User Request
      |
      v
Exact Match Lookup
      |
      +---- MISS
               |
               v
       Semantic Search
               |
         Similarity &gt; Threshold?
             /        \
           Yes        No
            |          |
            v          v
      Return Cached   Call LLM
       Response         |
                         v
                  Store in Cache
</code></code></pre><div><hr></div><h1>5. Cache Key Design</h1><p>The cache key must uniquely identify prompts that should produce identical responses.</p><h3>Key Structure</h3><pre><code><code>hash(
    tenant_id +
    model_name +
    model_version +
    system_prompt +
    user_prompt +
    temperature +
    top_p
)
</code></code></pre><h3>Example</h3><pre><code><code>tenantA:gpt-4o:v2:
SHA256(normalized_prompt)
</code></code></pre><h3>Why Include These Fields?</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;cfd61b0c-8a35-44f7-b204-f2e86d7eacbe&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Field         | Reason                                     |
| ------------- | ------------------------------------------ |
| Tenant ID     | Prevent data leakage                       |
| Model Name    | Different models produce different outputs |
| Model Version | Responses change after upgrades            |
| Temperature   | Affects output randomness                  |
| System Prompt | Changes behavior                           |
| User Prompt   | Main query                                 |
</code></pre></div><div><hr></div><h1>6. Prompt Normalization</h1><p>Before generating cache keys:</p><h3>Transformations</h3><pre><code><code>" What is Kubernetes? "
"What is Kubernetes?"
</code></code></pre><p>Normalize:</p><ul><li><p>Trim whitespace</p></li><li><p>Lowercase (optional)</p></li><li><p>Remove repeated spaces</p></li><li><p>Canonicalize formatting</p></li></ul><p>Example:</p><pre><code><code>"What  is Kubernetes?"
</code></code></pre><p>&#8595;</p><pre><code><code>"what is kubernetes?"
</code></code></pre><p>This improves cache hit rates.</p><div><hr></div><h1>7. Semantic Similarity Matching</h1><p>Exact matching misses logically equivalent prompts.</p><h3>Examples</h3><p>Prompt A:</p><pre><code><code>What is Kubernetes?
</code></code></pre><p>Prompt B:</p><pre><code><code>Explain Kubernetes.
</code></code></pre><p>Both should reuse the same response.</p><div><hr></div><h2>Semantic Cache Architecture</h2><h3>Step 1: Generate Embedding</h3><pre><code><code>Prompt
   |
Embedding Model
   |
Vector (1536 dimensions)
</code></code></pre><h3>Step 2: Store in Vector DB</h3><p>Possible technologies:</p><ul><li><p>Pinecone</p></li><li><p>Weaviate</p></li><li><p>Milvus</p></li><li><p>pgvector</p></li><li><p>OpenSearch Vector Search</p></li></ul><p>Store:</p><pre><code><code>{
  "tenant":"A",
  "embedding":[...],
  "response":"...",
  "ttl":"..."
}
</code></code></pre><div><hr></div><h2>Lookup</h2><pre><code><code>New Prompt
      |
Generate Embedding
      |
Vector Search
      |
Top K Results
      |
Similarity Score
</code></code></pre><h3>Decision Rule</h3><pre><code><code>similarity &gt;= 0.92
</code></code></pre><p>&#8594; Cache Hit</p><p>Else</p><p>&#8594; LLM Call</p><h3>Similarity Metrics</h3><ul><li><p>Cosine similarity</p></li><li><p>Euclidean distance</p></li><li><p>Dot product</p></li></ul><p>Cosine similarity is most common.</p><div><hr></div><h1>8. Cache Storage Design</h1><h2>L1 Cache</h2><p>Redis</p><p>Purpose:</p><ul><li><p>Ultra-fast exact lookup</p></li><li><p>Millisecond latency</p></li></ul><p>Stores:</p><pre><code><code>key -&gt; response
</code></code></pre><div><hr></div><h2>L2 Cache</h2><p>Vector Database</p><p>Purpose:</p><ul><li><p>Semantic retrieval</p></li></ul><p>Stores:</p><pre><code><code>embedding -&gt; response
</code></code></pre><div><hr></div><h1>9. TTL Strategy</h1><p>Not all prompts age equally.</p><h3>Dynamic TTL</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;0b13e4c2-4cba-43f7-95eb-2b3131a47e7a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Prompt Type  | TTL     |
| ------------ | ------- |
| Math         | 30 days |
| Coding Help  | 7 days  |
| News         | 1 hour  |
| Weather      | 15 mins |
| Stock Prices | 5 mins  |
</code></pre></div><div><hr></div><h3>TTL Formula</h3><pre><code><code>TTL =
baseTTL *
accessFrequencyMultiplier *
confidenceMultiplier
</code></code></pre><p>Frequently reused prompts stay longer.</p><div><hr></div><h1>10. Cache Invalidation</h1><p>One of the hardest problems.</p><h2>Trigger 1: Model Upgrade</h2><pre><code><code>GPT-4o-v1
      &#8595;
GPT-4o-v2
</code></code></pre><p>Invalidate entries tied to old version.</p><div><hr></div><h2>Trigger 2: Prompt Template Change</h2><pre><code><code>System Prompt Changed
</code></code></pre><p>Invalidate matching namespace.</p><div><hr></div><h2>Trigger 3: Knowledge Refresh</h2><p>Example:</p><pre><code><code>Company policy updated
</code></code></pre><p>Invalidate related cache entries.</p><div><hr></div><h2>Trigger 4: Manual Purge</h2><p>Admin API:</p><pre><code><code>DELETE /cache/{tenant}
DELETE /cache/key/{id}
</code></code></pre><div><hr></div><h1>11. Privacy Isolation</h1><p>Critical in enterprise environments.</p><h2>Tenant Isolation</h2><p>Every cache entry contains:</p><pre><code><code>tenant_id
</code></code></pre><p>Lookup only within same tenant.</p><pre><code><code>tenantA &#8800; tenantB
</code></code></pre><p>No cross-tenant reuse.</p><div><hr></div><h2>Namespace Isolation</h2><pre><code><code>tenantA/app1
tenantA/app2
tenantB/app1
</code></code></pre><p>Separate cache namespaces.</p><div><hr></div><h2>Encryption</h2><p>At Rest:</p><ul><li><p>AES-256</p></li></ul><p>In Transit:</p><ul><li><p>TLS</p></li></ul><div><hr></div><h2>Sensitive Data Protection</h2><p>Before caching:</p><pre><code><code>Prompt
   |
PII Detector
   |
Sensitive?
</code></code></pre><p>If sensitive:</p><pre><code><code>Do Not Cache
</code></code></pre><p>Examples:</p><ul><li><p>Credit card numbers</p></li><li><p>SSN</p></li><li><p>Passwords</p></li><li><p>Medical records</p></li></ul><div><hr></div><h1>12. Cache Warming</h1><p>Pre-populate cache before traffic arrives.</p><h2>Method 1: Historical Analysis</h2><p>Use top prompts from logs.</p><pre><code><code>Top 10,000 prompts
      |
Generate Responses
      |
Populate Cache
</code></code></pre><div><hr></div><h2>Method 2: Product Launch Warmup</h2><p>Example:</p><pre><code><code>New HR Bot
</code></code></pre><p>Preload:</p><ul><li><p>Leave policy</p></li><li><p>Benefits</p></li><li><p>Payroll FAQ</p></li></ul><div><hr></div><h2>Method 3: Scheduled Refresh</h2><p>Nightly job:</p><pre><code><code>Refresh frequently used entries
</code></code></pre><p>before expiry.</p><div><hr></div><h1>13. Scalability Design</h1><h3>Redis Cluster</h3><pre><code><code>Redis Shard 1
Redis Shard 2
Redis Shard 3
</code></code></pre><p>Partition by:</p><pre><code><code>hash(cache_key)
</code></code></pre><div><hr></div><h3>Vector DB Cluster</h3><pre><code><code>Embedding Space
      |
Partition/Sharding
      |
Multiple Nodes
</code></code></pre><p>Supports billions of vectors.</p><div><hr></div><h1>14. APIs</h1><h3>Lookup</h3><pre><code><code>POST /cache/lookup
</code></code></pre><p>Request:</p><pre><code><code>{
  "tenant":"A",
  "prompt":"What is Kubernetes?"
}
</code></code></pre><p>Response:</p><pre><code><code>{
  "hit": true,
  "response":"..."
}
</code></code></pre><div><hr></div><h3>Insert</h3><pre><code><code>POST /cache/store
</code></code></pre><div><hr></div><h3>Invalidate</h3><pre><code><code>DELETE /cache/key/{id}
</code></code></pre><div><hr></div><h1>15. Metrics &amp; Monitoring</h1><p>Track:</p><h3>Cache Metrics</h3><pre><code><code>Exact Hit Rate
Semantic Hit Rate
Miss Rate
</code></code></pre><h3>Cost Metrics</h3><pre><code><code>Tokens Saved
LLM Calls Avoided
Dollar Savings
</code></code></pre><h3>Performance Metrics</h3><pre><code><code>P95 Latency
P99 Latency
Redis Latency
Vector Search Latency
</code></code></pre><div><hr></div><h1>16. Design Decisions Summary</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;40f5e8b2-3498-488f-b734-96a1f5713e6c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Component         | Choice                                 |
| ----------------- | -------------------------------------- |
| L1 Cache          | Redis Cluster                          |
| L2 Semantic Cache | Vector DB (Milvus/Pinecone/pgvector)   |
| Cache Key         | Hash(tenant + model + prompt config)   |
| Similarity Metric | Cosine Similarity                      |
| Threshold         | 0.90&#8211;0.95                              |
| TTL               | Dynamic by content type                |
| Invalidation      | Versioning + Event-driven purge        |
| Privacy           | Tenant namespaces + PII filtering      |
| Warming           | Historical prompts + scheduled refresh |
</code></pre></div><h2>Final Design</h2><p>A <strong>two-level distributed prompt cache</strong> consists of:</p><ol><li><p><strong>L1 Redis exact-match cache</strong> for sub-millisecond retrieval.</p></li><li><p><strong>L2 Vector semantic cache</strong> for similar prompts.</p></li><li><p><strong>Tenant-aware cache keys</strong> for privacy.</p></li><li><p><strong>Dynamic TTL and invalidation policies</strong> to maintain freshness.</p></li><li><p><strong>Cache warming pipelines</strong> to maximize hit rates.</p></li><li><p><strong>Horizontal scaling via Redis Cluster and distributed vector databases</strong>.</p></li></ol><p>This architecture can typically reduce <strong>30&#8211;70% of LLM calls</strong>, significantly lowering inference costs and improving response latency across multiple applications.</p>]]></content:encoded></item><item><title><![CDATA[Design a Voice AI Agent supporting 10 million concurrent users with <300ms latency. ]]></title><description><![CDATA[Will discuss streaming ASR, LLM inference, TTS, session management, interruption handling (barge-in), autoscaling, and GPU utilization.]]></description><link>https://programmingappliedai.substack.com/p/design-a-voice-ai-agent-supporting</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/design-a-voice-ai-agent-supporting</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Fri, 31 Jul 2026 16:17:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><p>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on Low-Level Design (LLD)&#8212;especially Multithreading and Concurrency&#8212;along with High-Level Design (HLD), Data Structures &amp; Algorithms (DSA), System Design, LLM/Generative AI systems, and research paper discussions, feel free to reach out.</p><p>The mentorship is tailored for interview preparation, backend engineering, distributed systems, AI infrastructure, and building a strong systems-thinking foundation.</p><p>&#128233; Contact: <a href="mailto:programmingappliedai@gmail.com">programmingappliedai@gmail.com</a></p><h1>Functional Requirements (FR)</h1><ul><li><p>Users should be able to interact with the AI agent using voice in real time.</p></li><li><p>System should convert speech to text (ASR), generate responses using an LLM, and convert responses back to speech (TTS).</p></li><li><p>System should support full-duplex conversations where users can interrupt the AI while it is speaking (barge-in).</p></li><li><p>System should maintain conversational context and session history across multiple turns.</p></li><li><p>System should support multilingual conversations and voice personalization.</p></li></ul><div><hr></div><h1>Non-Functional Requirements (NFR)</h1><ul><li><p>Support up to <strong>10 million concurrent users</strong> globally.</p></li><li><p>End-to-end voice response latency should be <strong>less than 300 ms</strong>.</p></li><li><p>Achieve <strong>99.99% availability</strong> with no single point of failure.</p></li><li><p>Scale horizontally across regions with automatic failover.</p></li><li><p>Optimize GPU utilization to maximize throughput and minimize inference costs.</p></li></ul><div><hr></div><h1>Capacity Estimation</h1><p>Assumptions:</p><ul><li><p>10M concurrent users.</p></li><li><p>Average audio packet every 100 ms.</p></li><li><p>Average audio chunk size = 3 KB.</p></li></ul><p>Incoming traffic:</p><pre><code><code>10M &#215; 10 chunks/sec
=
100M audio chunks/sec
</code></code></pre><p>Bandwidth:</p><pre><code><code>100M &#215; 3 KB
=
300 GB/sec
</code></code></pre><p>This requires a globally distributed architecture with edge processing.</p><div><hr></div><h1>Core APIs</h1><h2>Start Session</h2><h3>Request</h3><pre><code><code>POST /v1/session/start
</code></code></pre><pre><code><code>{
  "userId": "u123",
  "language": "en",
  "voice": "female_1"
}
</code></code></pre><h3>Response</h3><pre><code><code>{
  "sessionId": "sess_789",
  "websocketUrl": "wss://voice.company.com/session/sess_789"
}
</code></code></pre><div><hr></div><h2>Streaming Audio API</h2><h3>WebSocket</h3><pre><code><code>wss://voice.company.com/session/{sessionId}
</code></code></pre><p>Client continuously sends audio chunks.</p><pre><code><code>{
  "sequence": 1,
  "audioChunk": "&lt;binary&gt;"
}
</code></code></pre><div><hr></div><h2>Session End API</h2><pre><code><code>POST /v1/session/end
</code></code></pre><pre><code><code>{
  "sessionId": "sess_789"
}
</code></code></pre><div><hr></div><h2>Health API</h2><pre><code><code>GET /v1/health
</code></code></pre><div><hr></div><h1>High-Level Components / Microservices</h1><ul><li><p>API Gateway</p></li><li><p>WebSocket Gateway</p></li><li><p>Session Management Service</p></li><li><p>Streaming ASR Service</p></li><li><p>Conversation Orchestrator</p></li><li><p>Context/Memory Service</p></li><li><p>LLM Inference Service</p></li><li><p>TTS Service</p></li><li><p>Barge-In Detection Service</p></li><li><p>GPU Scheduler</p></li><li><p>Model Serving Platform</p></li><li><p>Redis Session Cache</p></li><li><p>Kafka/Pulsar Event Bus</p></li><li><p>Monitoring &amp; Analytics Service</p></li></ul><div><hr></div><h1>Database Schema</h1><h2>Session Table</h2><pre><code><code>CREATE TABLE sessions (
    session_id VARCHAR(128) PRIMARY KEY,
    user_id VARCHAR(128),
    status VARCHAR(32),
    started_at TIMESTAMP,
    last_activity TIMESTAMP
);
</code></code></pre><div><hr></div><h2>Conversation History</h2><pre><code><code>CREATE TABLE conversations (
    id BIGSERIAL PRIMARY KEY,
    session_id VARCHAR(128),
    role VARCHAR(16),
    message TEXT,
    created_at TIMESTAMP
);
</code></code></pre><div><hr></div><h2>User Voice Preferences</h2><pre><code><code>CREATE TABLE voice_profiles (
    user_id VARCHAR(128) PRIMARY KEY,
    language VARCHAR(32),
    preferred_voice VARCHAR(64)
);
</code></code></pre><div><hr></div><h1>Microservices Interaction</h1><h2>Step 1: User Starts Conversation</h2><p>User opens application.</p><p>Request reaches API Gateway.</p><p>API Gateway forwards request to Session Service.</p><p>Session Service:</p><ul><li><p>Creates session.</p></li><li><p>Allocates region.</p></li><li><p>Stores metadata in Redis.</p></li></ul><p>Returns WebSocket endpoint.</p><div><hr></div><h2>Step 2: User Starts Speaking</h2><p>Audio stream arrives through WebSocket Gateway.</p><p>Gateway forwards chunks to Streaming ASR Service.</p><p>Example:</p><pre><code><code>User:
"Book me a flight to London"
</code></code></pre><p>Audio is streamed continuously.</p><div><hr></div><h2>Step 3: Streaming ASR</h2><p>Instead of waiting for complete speech:</p><p>Traditional ASR:</p><pre><code><code>User speaks
     &#8595;
Speech ends
     &#8595;
ASR starts
</code></code></pre><p>High latency.</p><div><hr></div><p>Streaming ASR:</p><pre><code><code>Audio Chunk 1
Audio Chunk 2
Audio Chunk 3
</code></code></pre><p>ASR continuously emits partial transcripts.</p><p>Example:</p><pre><code><code>"Book"
"Book me"
"Book me a flight"
"Book me a flight to London"
</code></code></pre><p>This saves hundreds of milliseconds.</p><div><hr></div><h2>Step 4: Conversation Orchestrator</h2><p>Receives partial transcript.</p><p>Maintains conversation state.</p><p>Fetches:</p><ul><li><p>User profile</p></li><li><p>Conversation memory</p></li><li><p>Previous messages</p></li></ul><p>Builds prompt.</p><div><hr></div><h2>Step 5: LLM Inference Service</h2><p>Prompt sent to LLM.</p><p>Example:</p><pre><code><code>User:
Book me a flight to London

Context:
User prefers economy seats.
</code></code></pre><p>LLM begins generating tokens immediately.</p><p>Streaming output:</p><pre><code><code>Sure
Sure, I
Sure, I can
Sure, I can help
</code></code></pre><p>No need to wait for complete answer.</p><div><hr></div><h2>Step 6: TTS Service</h2><p>As soon as first tokens arrive:</p><pre><code><code>Sure,
</code></code></pre><p>TTS starts synthesis.</p><p>Produces audio stream immediately.</p><p>Pipeline:</p><pre><code><code>LLM Tokens
    &#8595;
TTS
    &#8595;
Audio Chunks
    &#8595;
User
</code></code></pre><p>This overlap is critical for achieving &lt;300 ms latency.</p><div><hr></div><h1>End-to-End Streaming Pipeline</h1><pre><code><code>User Speech
      &#8595;
Streaming ASR
      &#8595;
Partial Transcript
      &#8595;
LLM Streaming
      &#8595;
Partial Tokens
      &#8595;
Streaming TTS
      &#8595;
Audio Response
</code></code></pre><p>All stages run simultaneously.</p><div><hr></div><h1>Barge-In (Interruption Handling)</h1><h2>Problem</h2><p>AI is speaking:</p><pre><code><code>AI:
"Sure, I can help you book..."
</code></code></pre><p>User interrupts:</p><pre><code><code>"No, I meant Paris."
</code></code></pre><p>System must stop speaking immediately.</p><div><hr></div><h2>Barge-In Flow</h2><p>User audio detected.</p><p>Barge-In Service receives voice activity event.</p><pre><code><code>User Voice Detected
       &#8595;
Stop Current TTS
       &#8595;
Cancel Current LLM Generation
       &#8595;
Start New ASR Stream
</code></code></pre><div><hr></div><p>Conversation becomes:</p><pre><code><code>AI:
Sure I can help...

User:
No, I meant Paris.

AI:
Understood. You want Paris.
</code></code></pre><div><hr></div><h1>Session Management</h1><p>Session Service maintains:</p><ul><li><p>Session ID</p></li><li><p>User preferences</p></li><li><p>Current conversation state</p></li><li><p>Active model</p></li><li><p>Current TTS stream</p></li><li><p>Current ASR stream</p></li></ul><p>Hot session state stored in Redis.</p><pre><code><code>Session
      &#8595;
Redis
</code></code></pre><p>Access latency:</p><pre><code><code>&lt; 5 ms
</code></code></pre><p>Long-term history stored in distributed database.</p><div><hr></div><h1>Autoscaling Strategy</h1><h2>ASR Autoscaling</h2><p>Scale based on:</p><pre><code><code>Active Audio Streams
</code></code></pre><p>Metric:</p><pre><code><code>Streams per GPU
</code></code></pre><div><hr></div><h2>LLM Autoscaling</h2><p>Scale based on:</p><pre><code><code>Waiting Requests
Token Throughput
GPU Queue Length
</code></code></pre><div><hr></div><h2>TTS Autoscaling</h2><p>Scale based on:</p><pre><code><code>Concurrent Audio Synthesis Requests
</code></code></pre><div><hr></div><p>Kubernetes HPA scales services independently.</p><div><hr></div><h1>GPU Utilization Optimization</h1><p>Running one request per GPU wastes resources.</p><p>Bad:</p><pre><code><code>GPU
 &#9492;&#9472; Request A
</code></code></pre><p>Utilization:</p><pre><code><code>15%
</code></code></pre><div><hr></div><p>Use Continuous Batching.</p><p>Good:</p><pre><code><code>GPU
 &#9500;&#9472; Req A
 &#9500;&#9472; Req B
 &#9500;&#9472; Req C
 &#9500;&#9472; Req D
 &#9492;&#9472; Req E
</code></code></pre><p>Utilization:</p><pre><code><code>80-95%
</code></code></pre><div><hr></div><h1>GPU Scheduler</h1><p>Responsibilities:</p><ul><li><p>Assign requests to GPUs.</p></li><li><p>Perform dynamic batching.</p></li><li><p>Route to least loaded GPU.</p></li><li><p>Handle model placement.</p></li><li><p>Manage KV cache memory.</p></li></ul><div><hr></div><h1>Latency Breakdown (&lt;300 ms Target)</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7670167e-1584-4281-9a91-5dc1f7c8bc56&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Component       | Latency |
| --------------- | ------- |
| Network         | 20 ms   |
| Streaming ASR   | 50 ms   |
| Prompt Building | 10 ms   |
| LLM First Token | 80 ms   |
| Streaming TTS   | 80 ms   |
| Buffering       | 20 ms   |
</code></pre></div><p>Total:</p><pre><code><code>&#8776; 260 ms
</code></code></pre><div><hr></div><h1>High-Level Architecture</h1><pre><code><code>Client
   |
WebSocket Gateway
   |
Session Service
   |
Conversation Orchestrator
   |
   +----------------+
   |                |
Streaming ASR   Memory Service
   |                |
   +-------+--------+
           |
           v
      LLM Service
           |
           v
       TTS Service
           |
           v
      Audio Stream
           |
         Client
</code></code></pre><h3>Key Design Decisions</h3><ul><li><p>Streaming ASR instead of batch ASR.</p></li><li><p>Streaming token generation from LLM.</p></li><li><p>Streaming TTS synthesis.</p></li><li><p>Redis-backed session state.</p></li><li><p>Immediate barge-in cancellation.</p></li><li><p>Dynamic GPU batching.</p></li><li><p>Regional deployment with edge WebSocket gateways.</p></li><li><p>Stateless services with Kubernetes autoscaling.</p></li><li><p>Event-driven communication via Kafka/Pulsar.</p></li><li><p>Continuous GPU utilization monitoring and scheduling.</p></li></ul>]]></content:encoded></item><item><title><![CDATA[HLD: Design a Knowledge Base (KB) Cache for a RAG system serving 100M+ queries/day. Explain cache hierarchy (embedding, retrieval, LLM response), invalidation, freshness, semantic cache hits.]]></title><description><![CDATA[Functional Requirements (FR)]]></description><link>https://programmingappliedai.substack.com/p/hld-design-a-knowledge-base-kb-cache</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-a-knowledge-base-kb-cache</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Thu, 23 Jul 2026 14:43:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Functional Requirements (FR)</h2><ul><li><p>Users should be able to submit natural language questions to the RAG system.</p></li><li><p>System should retrieve the most relevant documents/chunks from the knowledge base.</p></li><li><p>System should generate answers using retrieved context and an LLM.</p></li><li><p>System should cache query embeddings to avoid repeated embedding generation.</p></li><li><p>System should cache retrieval results to avoid repeated vector searches.</p></li><li><p>System should cache final LLM responses for repeated or semantically similar queries.</p></li><li><p>System should support semantic cache lookup based on embedding similarity.</p></li><li><p>System should allow ingestion, update, and deletion of knowledge base documents.</p></li><li><p>System should invalidate stale cache entries when underlying documents change.</p></li><li><p>System should provide source citations/metadata used for answer generation.</p></li><li><p>System should support multi-tenant isolation (different organizations/knowledge bases).</p></li><li><p>System should expose cache hit/miss metrics for monitoring and analytics.</p></li></ul><div><hr></div><h2>Non-Functional Requirements (NFR)</h2><ul><li><p>Support 100M+ queries per day.</p></li><li><p>Handle peak traffic of 10K&#8211;50K QPS.</p></li><li><p>Achieve P95 query latency below 500 ms for cached requests.</p></li><li><p>Achieve P99 latency below 2 seconds for uncached requests.</p></li><li><p>Maintain 99.99% service availability.</p></li><li><p>Scale horizontally without downtime.</p></li><li><p>Ensure fault tolerance with no single point of failure.</p></li><li><p>Support eventual consistency for distributed cache invalidation.</p></li><li><p>Minimize LLM and vector search costs through high cache hit ratios.</p></li><li><p>Maintain cache freshness after KB updates.</p></li><li><p>Support multi-region deployments with local cache access.</p></li><li><p>Ensure tenant-level security and data isolation.</p></li><li><p>Enable observability through metrics, logs, and distributed tracing.</p></li><li><p>Support rolling deployments and zero-downtime upgrades.</p></li><li><p>Provide disaster recovery and backup mechanisms.</p></li></ul><div><hr></div><h2>Core APIs</h2><h3>Query API</h3><pre><code><code>POST /v1/query
</code></code></pre><p>Request</p><pre><code><code>{
  "query": "What is GPT-5?",
  "tenantId": "org123",
  "userId": "user456"
}
</code></code></pre><p>Response</p><pre><code><code>{
  "answer": "GPT-5 is...",
  "sources": ["doc1", "doc2"],
  "cacheHit": "response_cache",
  "latencyMs": 45
}
</code></code></pre><div><hr></div><h3>Document Ingestion API</h3><pre><code><code>POST /v1/documents
</code></code></pre><p>Request</p><pre><code><code>{
  "documentId": "doc123",
  "content": "document content",
  "metadata": {
    "category": "AI"
  }
}
</code></code></pre><p>Response</p><pre><code><code>{
  "status": "success"
}
</code></code></pre><div><hr></div><h3>Document Update API</h3><pre><code><code>PUT /v1/documents/{documentId}
</code></code></pre><p>Request</p><pre><code><code>{
  "content": "updated content",
  "version": 5
}
</code></code></pre><p>Response</p><pre><code><code>{
  "status": "updated"
}
</code></code></pre><div><hr></div><h3>Cache Invalidation API</h3><pre><code><code>POST /v1/cache/invalidate
</code></code></pre><p>Request</p><pre><code><code>{
  "documentId": "doc123"
}
</code></code></pre><p>Response</p><pre><code><code>{
  "status": "invalidated"
}
</code></code></pre><div><hr></div><h2>Database Schema</h2><h3>Documents</h3><pre><code><code>CREATE TABLE documents (
    document_id VARCHAR(64) PRIMARY KEY,
    content TEXT,
    version BIGINT,
    metadata JSONB,
    updated_at TIMESTAMP
);
</code></code></pre><h3>Embeddings</h3><pre><code><code>CREATE TABLE embeddings (
    embedding_id BIGSERIAL PRIMARY KEY,
    document_id VARCHAR(64),
    embedding VECTOR(1536),
    version BIGINT
);
</code></code></pre><h3>Response Cache Metadata</h3><pre><code><code>CREATE TABLE response_cache (
    cache_key VARCHAR(255) PRIMARY KEY,
    answer TEXT,
    kb_version BIGINT,
    created_at TIMESTAMP,
    expires_at TIMESTAMP
);
</code></code></pre><h3>Retrieval Cache Metadata</h3><pre><code><code>CREATE TABLE retrieval_cache (
    query_hash VARCHAR(255) PRIMARY KEY,
    document_ids JSONB,
    kb_version BIGINT,
    created_at TIMESTAMP
);
</code></code></pre><div><hr></div><h2>Microservices</h2><ul><li><p>API Gateway</p></li><li><p>Query Orchestrator Service</p></li><li><p>Embedding Service</p></li><li><p>Embedding Cache Service</p></li><li><p>Retrieval Cache Service</p></li><li><p>Vector Search Service</p></li><li><p>Response Cache Service</p></li><li><p>LLM Service</p></li><li><p>Knowledge Base Service</p></li><li><p>Cache Invalidation Service</p></li><li><p>Metadata Service</p></li><li><p>Monitoring &amp; Analytics Service</p></li><li><p>Kafka/Pulsar Event Bus</p></li></ul><div><hr></div><h2>High-Level Request Flow</h2><pre><code><code>Client
   |
API Gateway
   |
Query Orchestrator
   |
   +--&gt; Response Cache
   |        |
   |        +--&gt; Hit --&gt; Return Answer
   |
   +--&gt; Embedding Cache
   |        |
   |        +--&gt; Miss --&gt; Embedding Service
   |
   +--&gt; Retrieval Cache
   |        |
   |        +--&gt; Miss --&gt; Vector Search
   |
   +--&gt; LLM Service
   |
Return Answer
</code></code></pre><h2>Microservices Interaction (Request Flow)</h2><h3>1. Client &#8594; API Gateway</h3><ul><li><p>User sends a query such as <em>&#8220;What is GPT-5?&#8221;</em></p></li><li><p>API Gateway performs authentication, rate limiting, request validation, and routing.</p></li><li><p>Request is forwarded to the Query Orchestrator Service.</p></li></ul><div><hr></div><h3>2. Query Orchestrator &#8594; Response Cache Service</h3><ul><li><p>Query Orchestrator first checks whether the final answer is already available in the Response Cache.</p></li><li><p>Cache lookup can happen in two ways:</p><ul><li><p>Exact match lookup using query hash.</p></li><li><p>Semantic lookup using query embedding similarity.</p></li></ul></li><li><p>If a valid cache entry exists, the response is returned immediately.</p></li><li><p>This is the fastest path and avoids all downstream processing.</p></li></ul><p><strong>Example</strong></p><pre><code><code>"What is GPT-5?"
</code></code></pre><p>already exists in cache.</p><p>Response is returned in ~10-50 ms.</p><div><hr></div><h3>3. Query Orchestrator &#8594; Embedding Cache Service</h3><p>If response cache misses:</p><ul><li><p>System needs query embedding.</p></li><li><p>Query Orchestrator checks Embedding Cache.</p></li></ul><p><strong>Cache Hit</strong></p><ul><li><p>Cached embedding vector is returned.</p></li></ul><p><strong>Cache Miss</strong></p><ul><li><p>Request goes to Embedding Service.</p></li><li><p>Embedding model generates vector.</p></li><li><p>Generated vector is stored in Embedding Cache for future use.</p></li></ul><p>Example:</p><pre><code><code>"What is GPT-5?"
</code></code></pre><p>&#8595;</p><pre><code><code>[0.12, 0.45, 0.98 ...]
</code></code></pre><div><hr></div><h3>4. Query Orchestrator &#8594; Retrieval Cache Service</h3><p>Once query embedding is available:</p><ul><li><p>System checks Retrieval Cache.</p></li><li><p>Retrieval Cache stores previously retrieved document IDs for similar queries.</p></li></ul><p><strong>Cache Hit</strong></p><pre><code><code>Query Embedding
       &#8595;
[Doc1, Doc7, Doc9]
</code></code></pre><p>Documents are returned directly.</p><p><strong>Cache Miss</strong></p><p>System performs vector search.</p><div><hr></div><h3>5. Query Orchestrator &#8594; Vector Search Service</h3><ul><li><p>Vector Search Service receives query embedding.</p></li><li><p>Searches Vector Database using Approximate Nearest Neighbor (ANN) algorithms such as HNSW or IVF.</p></li><li><p>Retrieves Top-K relevant chunks/documents.</p></li></ul><p>Example:</p><pre><code><code>Query:
"What is GPT-5?"
</code></code></pre><p>Retrieved:</p><pre><code><code>Doc12
Doc19
Doc42
</code></code></pre><p>Results are stored in Retrieval Cache.</p><div><hr></div><h3>6. Query Orchestrator &#8594; Knowledge Base Service</h3><ul><li><p>Query Orchestrator requests full content for retrieved document IDs.</p></li><li><p>KB Service fetches chunk text and metadata.</p></li></ul><p>Example:</p><pre><code><code>Doc12 &#8594; GPT-5 architecture
Doc19 &#8594; GPT-5 capabilities
Doc42 &#8594; GPT-5 release information
</code></code></pre><p>These chunks form the context.</p><div><hr></div><h3>7. Query Orchestrator &#8594; LLM Service</h3><ul><li><p>Query and retrieved context are sent to the LLM Service.</p></li><li><p>LLM Service constructs prompt.</p></li></ul><p>Example:</p><pre><code><code>System Prompt

Retrieved Context:
[Doc12]
[Doc19]
[Doc42]

User Query:
What is GPT-5?
</code></code></pre><ul><li><p>LLM generates final answer.</p></li></ul><div><hr></div><h3>8. Query Orchestrator &#8594; Response Cache Service</h3><p>Before returning answer:</p><ul><li><p>Generated response is stored in Response Cache.</p></li><li><p>Metadata is stored:</p><ul><li><p>Query hash</p></li><li><p>Embedding hash</p></li><li><p>Retrieved document IDs</p></li><li><p>KB version</p></li><li><p>TTL</p></li></ul></li></ul><p>This allows future requests to avoid LLM generation.</p><div><hr></div><h3>9. Query Orchestrator &#8594; Client</h3><p>Final response is returned.</p><pre><code><code>{
  "answer": "GPT-5 is...",
  "sources": ["Doc12", "Doc19", "Doc42"],
  "cacheHit": false
}
</code></code></pre><div><hr></div><h1>Document Update Flow</h1><p>When knowledge base content changes:</p><h3>1. Admin &#8594; KB Service</h3><p>Document update request arrives.</p><pre><code><code>Doc19 Updated
</code></code></pre><div><hr></div><h3>2. KB Service &#8594; Vector Search Service</h3><ul><li><p>New document embedding is generated.</p></li><li><p>Old vector is replaced in Vector DB.</p></li></ul><div><hr></div><h3>3. KB Service &#8594; Kafka/Event Bus</h3><p>Publish event:</p><pre><code><code>DocumentUpdated
{
   docId: 19,
   version: 22
}
</code></code></pre><div><hr></div><h3>4. Event Bus &#8594; Cache Invalidation Service</h3><p>Cache Invalidation Service consumes update event.</p><div><hr></div><h3>5. Cache Invalidation Service &#8594; Retrieval Cache</h3><p>Invalidate retrieval entries containing Doc19.</p><pre><code><code>QueryA &#8594; [Doc19, Doc22]
QueryB &#8594; [Doc7, Doc19]
</code></code></pre><p>Both entries removed.</p><div><hr></div><h3>6. Cache Invalidation Service &#8594; Response Cache</h3><p>Invalidate responses generated using Doc19.</p><pre><code><code>ResponseX
ResponseY
ResponseZ
</code></code></pre><p>All removed.</p><div><hr></div><h3>7. Fresh Requests Use New Data</h3><p>Future queries:</p><pre><code><code>Query
  &#8595;
Vector Search
  &#8595;
Updated Doc19
  &#8595;
LLM
</code></code></pre><p>Users receive fresh answers.</p><div><hr></div><h1>End-to-End Summary</h1><pre><code><code>User Query
    &#8595;
API Gateway
    &#8595;
Query Orchestrator
    &#8595;
Response Cache ?
    &#8595; miss
Embedding Cache ?
    &#8595; miss
Embedding Service
    &#8595;
Retrieval Cache ?
    &#8595; miss
Vector Search
    &#8595;
Knowledge Base
    &#8595;
LLM Service
    &#8595;
Response Cache Update
    &#8595;
User
</code></code></pre><p>The <strong>Query Orchestrator Service</strong> is the central coordinator. All other services (cache, embedding, vector search, KB, LLM) are specialized services that it calls in sequence to answer the query efficiently.</p>]]></content:encoded></item><item><title><![CDATA[HLD: Design Device backup and scheduler]]></title><description><![CDATA[Let's design]]></description><link>https://programmingappliedai.substack.com/p/hld-design-device-backup-and-scheduler</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-device-backup-and-scheduler</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Wed, 08 Jul 2026 17:44:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>FR:</strong></p><ol><li><p>Schedule device backups.</p></li><li><p>Trigger automatic backups as per schedule.</p></li><li><p>View backup status and history.</p></li><li><p>Restore device data from selected backup.</p></li><li><p>Send backup/restore success or failure notifications.</p></li></ol><p><strong>NFR:</strong></p><ol><li><p>High availability of backup and restore services.</p></li><li><p>Secure data storage and transmission through encryption.</p></li><li><p>Scalable to support multiple devices concurrently.</p></li><li><p>Minimal impact on device performance during backup.</p></li><li><p>Maintain backup data integrity and reliability.</p></li></ol><p><strong>API&#8217;s with Request and Response</strong></p><h3>1. Create Backup Schedule</h3><p><strong>API:</strong> <code>POST /api/v1/backup/schedules</code></p><p><strong>Request</strong></p><pre><code><code>{
  "deviceId": "DEV001",
  "frequency": "DAILY",
  "time": "02:00"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "scheduleId": "SCH001",
  "status": "CREATED",
  "message": "Backup schedule created successfully"
}
</code></code></pre><div><hr></div><h3>2. Trigger Backup</h3><p><strong>API:</strong> <code>POST /api/v1/backups</code></p><p><strong>Request</strong></p><pre><code><code>{
  "deviceId": "DEV001",
  "backupType": "FULL"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "backupId": "BKP001",
  "status": "IN_PROGRESS",
  "message": "Backup initiated successfully"
}
</code></code></pre><div><hr></div><h3>3. Get Backup Status</h3><p><strong>API:</strong> <code>GET /api/v1/backups/{backupId}</code></p><p><strong>Request</strong></p><pre><code><code>{
  "backupId": "BKP001"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "backupId": "BKP001",
  "deviceId": "DEV001",
  "status": "COMPLETED",
  "backupTime": "2026-07-08T02:00:00Z"
}
</code></code></pre><div><hr></div><h3>4. Get Available Backups for Restore</h3><p><strong>API:</strong> <code>GET /api/v1/devices/{deviceId}/backups</code></p><p><strong>Request</strong></p><pre><code><code>{
  "deviceId": "DEV001"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "backups": [
    {
      "backupId": "BKP001",
      "createdAt": "2026-07-08T02:00:00Z"
    },
    {
      "backupId": "BKP002",
      "createdAt": "2026-07-07T02:00:00Z"
    }
  ]
}
</code></code></pre><div><hr></div><h3>5. Restore Backup</h3><p><strong>API:</strong> <code>POST /api/v1/restores</code></p><p><strong>Request</strong></p><pre><code><code>{
  "deviceId": "DEV001",
  "backupId": "BKP001"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "restoreId": "RST001",
  "status": "IN_PROGRESS",
  "message": "Restore initiated successfully"
}
</code></code></pre><div><hr></div><h3>6. Get Restore Status</h3><p><strong>API:</strong> <code>GET /api/v1/restores/{restoreId}</code></p><p><strong>Request</strong></p><pre><code><code>{
  "restoreId": "RST001"
}
</code></code></pre><p><strong>Response</strong></p><pre><code><code>{
  "restoreId": "RST001",
  "deviceId": "DEV001",
  "status": "COMPLETED",
  "restoredAt": "2026-07-08T05:00:00Z"
}</code></code></pre><p><strong>Databases and Schema</strong></p><p><strong>Database Choice</strong></p><ul><li><p>PostgreSQL &#8211; Backup schedules, backup metadata, restore jobs, notifications, audit logs</p></li><li><p>Redis &#8211; Caching and job scheduling</p></li><li><p>Object Storage (S3 compatible) &#8211; Backup file storage</p></li><li><p>Elasticsearch/OpenSearch (Optional) &#8211; Log search and analytics</p></li></ul><p><strong>Tables</strong></p><p><strong>Device</strong></p><ul><li><p>device_id (PK, UUID)</p></li><li><p>device_name (VARCHAR)</p></li><li><p>device_type (VARCHAR)</p></li><li><p>owner_id (VARCHAR)</p></li><li><p>status (VARCHAR)</p></li><li><p>created_at (TIMESTAMP)</p></li></ul><p><strong>Backup_Schedule</strong></p><ul><li><p>schedule_id (PK, UUID)</p></li><li><p>device_id (FK, UUID)</p></li><li><p>frequency (VARCHAR)</p></li><li><p>backup_time (TIME)</p></li><li><p>is_active (BOOLEAN)</p></li><li><p>created_at (TIMESTAMP)</p></li><li><p>updated_at (TIMESTAMP)</p></li></ul><p><strong>Backup_Job</strong></p><ul><li><p>backup_id (PK, UUID)</p></li><li><p>device_id (FK, UUID)</p></li><li><p>schedule_id (FK, UUID)</p></li><li><p>backup_type (VARCHAR)</p></li><li><p>status (VARCHAR)</p></li><li><p>file_size (BIGINT)</p></li><li><p>storage_path (VARCHAR)</p></li><li><p>started_at (TIMESTAMP)</p></li><li><p>completed_at (TIMESTAMP)</p></li></ul><p><strong>Backup_Version</strong></p><ul><li><p>version_id (PK, UUID)</p></li><li><p>backup_id (FK, UUID)</p></li><li><p>version_number (INT)</p></li><li><p>checksum (VARCHAR)</p></li><li><p>retention_days (INT)</p></li><li><p>created_at (TIMESTAMP)</p></li></ul><p><strong>Restore_Job</strong></p><ul><li><p>restore_id (PK, UUID)</p></li><li><p>device_id (FK, UUID)</p></li><li><p>backup_id (FK, UUID)</p></li><li><p>status (VARCHAR)</p></li><li><p>initiated_by (VARCHAR)</p></li><li><p>started_at (TIMESTAMP)</p></li><li><p>completed_at (TIMESTAMP)</p></li></ul><p><strong>Notification</strong></p><ul><li><p>notification_id (PK, UUID)</p></li><li><p>device_id (FK, UUID)</p></li><li><p>event_type (VARCHAR)</p></li><li><p>recipient (VARCHAR)</p></li><li><p>status (VARCHAR)</p></li><li><p>sent_at (TIMESTAMP)</p></li></ul><p><strong>Audit_Log</strong></p><ul><li><p>audit_id (PK, UUID)</p></li><li><p>entity_type (VARCHAR)</p></li><li><p>entity_id (UUID)</p></li><li><p>action (VARCHAR)</p></li><li><p>performed_by (VARCHAR)</p></li><li><p>timestamp (TIMESTAMP)</p></li><li><p>remarks (TEXT)</p></li></ul><p><strong>Relationships</strong></p><ul><li><p>Device &#8594; Backup_Schedule (1:N)</p></li><li><p>Device &#8594; Backup_Job (1:N)</p></li><li><p>Backup_Job &#8594; Backup_Version (1:N)</p></li><li><p>Device &#8594; Restore_Job (1:N)</p></li><li><p>Backup_Job &#8594; Restore_Job (1:N)</p></li><li><p>Device &#8594; Notification (1:N)</p></li><li><p>All entities &#8594; Audit_Log (1:N)</p></li></ul><p><strong>Microservices Architecture &#8211; Device Backup Scheduler &amp; Restore</strong></p><ol><li><p><strong>API Gateway</strong></p><ul><li><p>Single entry point for all client requests</p></li><li><p>Authentication, authorization, routing, rate limiting</p></li></ul></li><li><p><strong>Device Management Service</strong></p><ul><li><p>Manages device registration and device metadata</p></li><li><p>Provides device details to backup and restore services</p></li></ul></li><li><p><strong>Backup Scheduler Service</strong></p><ul><li><p>Creates and manages backup schedules</p></li><li><p>Triggers backup jobs based on configured frequency</p></li></ul></li><li><p><strong>Backup Service</strong></p><ul><li><p>Executes backup operations</p></li><li><p>Stores backup metadata and uploads backup files to object storage</p></li></ul></li><li><p><strong>Restore Service</strong></p><ul><li><p>Retrieves backup data</p></li><li><p>Initiates and monitors restore operations</p></li></ul></li><li><p><strong>Notification Service</strong></p><ul><li><p>Sends email/SMS/in-app notifications for backup and restore events</p></li></ul></li><li><p><strong>Audit &amp; Logging Service</strong></p><ul><li><p>Records user actions and system events</p></li><li><p>Provides audit trail for compliance and troubleshooting</p></li></ul></li><li><p><strong>Storage Service</strong></p><ul><li><p>Manages backup file storage and retrieval from object storage</p></li></ul></li><li><p><strong>Auth Service</strong></p><ul><li><p>User authentication and authorization</p></li><li><p>Issues and validates JWT/OAuth tokens</p></li></ul></li></ol><div><hr></div><p><strong>Service Interaction Flow</strong></p><p><strong>Backup Scheduling</strong></p><ol><li><p>Client &#8594; API Gateway</p></li><li><p>API Gateway &#8594; Auth Service (token validation)</p></li><li><p>API Gateway &#8594; Backup Scheduler Service</p></li><li><p>Backup Scheduler Service &#8594; Device Management Service (validate device)</p></li><li><p>Backup Scheduler Service &#8594; PostgreSQL (save schedule)</p></li></ol><p><strong>Backup Execution</strong></p><ol><li><p>Scheduler triggers Backup Service</p></li><li><p>Backup Service &#8594; Device Management Service (device details)</p></li><li><p>Backup Service &#8594; Storage Service (store backup file)</p></li><li><p>Backup Service &#8594; PostgreSQL (save metadata)</p></li><li><p>Backup Service &#8594; Notification Service (backup status)</p></li><li><p>Notification Service &#8594; User</p></li></ol><p><strong>Restore Execution</strong></p><ol><li><p>Client &#8594; API Gateway</p></li><li><p>API Gateway &#8594; Restore Service</p></li><li><p>Restore Service &#8594; Backup Service (backup metadata)</p></li><li><p>Restore Service &#8594; Storage Service (retrieve backup file)</p></li><li><p>Restore Service &#8594; Device Management Service (device validation)</p></li><li><p>Restore Service &#8594; PostgreSQL (update restore status)</p></li><li><p>Restore Service &#8594; Notification Service (restore status)</p></li></ol><p><strong>Audit Flow</strong></p><ol><li><p>Every service publishes events</p></li><li><p>Audit &amp; Logging Service consumes events</p></li><li><p>Audit records stored in Audit_Log table</p></li></ol><p><strong>Communication Pattern</strong></p><ul><li><p>Synchronous: REST APIs (API Gateway &#8596; Services)</p></li><li><p>Asynchronous: Kafka/RabbitMQ events for Backup Trigger, Restore Trigger, Notifications, Audit Logging</p></li><li><p>Database per service pattern</p></li><li><p>Object Storage for backup files</p></li><li><p>Redis for caching and scheduled job execution</p></li></ul><p><strong>High-Level Flow</strong><br>Client &#8594; API Gateway &#8594; Auth Service &#8594; Backup Scheduler Service &#8594; Backup Service &#8594; Storage Service &#8594; Restore Service &#8594; Notification Service &#8594; Audit Service &#8594; Databases/Object Storage/Event Bus.</p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[HLD: Design Container Management System (Manage / Move / Deploy Containers Across Networks)]]></title><description><![CDATA[Think of this as a simplified version of Kubernetes + Cluster Federation, where containers can be deployed, migrated, monitored, and managed across multiple data centers, cloud providers, and networks]]></description><link>https://programmingappliedai.substack.com/p/hld-design-container-management-system</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-container-management-system</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Mon, 08 Jun 2026 17:49:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Functional Requirements</h3><ol><li><p>Deploy containers on available compute nodes using Docker/OCI compliant images.</p></li><li><p>Migrate running containers across nodes or clusters while preserving application state and network connectivity.</p></li><li><p>Manage container lifecycle operations including start, stop, restart, update, and scaling.</p></li><li><p>Create and manage virtual networks, service discovery, and cross-network communication between containers.</p></li><li><p>Continuously monitor container and node health, collect metrics, detect failures, and trigger automatic recovery actions.</p></li></ol><div><hr></div><h3>Non-Functional Requirements</h3><ol><li><p>Ensure high availability with a target uptime of at least 99.99%.</p></li><li><p>Scale to support up to 100,000 nodes and 1 million running containers.</p></li><li><p>Achieve container deployment and scheduling latency of less than 5 seconds.</p></li><li><p>Provide fault tolerance such that node, network, or service failures do not cause application downtime.</p></li><li><p>Enforce enterprise-grade security through RBAC, TLS-encrypted communication, image signing, verification, and audit logging.</p></li></ol><div><hr></div><h1>Core APIs</h1><div><hr></div><h2>Deploy Container</h2><pre><code></code></pre><pre><code><code>POST /v1/containers</code></code></pre><p>Request</p><pre><code></code></pre><pre><code><code>{
  "image":"nginx:latest",
  "cpu":"2",
  "memory":"4GB",
  "network_id":"net-123",
  "replicas":3
}</code></code></pre><p>Response</p><pre><code></code></pre><pre><code><code>{
  "container_id":"ctr-123",
  "status":"DEPLOYING"
}</code></code></pre><div><hr></div><h2>Get Container</h2><pre><code></code></pre><pre><code><code>GET /v1/containers/{containerId}</code></code></pre><p>Response</p><pre><code></code></pre><pre><code><code>{
  "container_id":"ctr-123",
  "status":"RUNNING",
  "node_id":"node-45",
  "ip":"10.0.1.20"
}</code></code></pre><div><hr></div><h2>Migrate Container</h2><pre><code></code></pre><pre><code><code>POST /v1/containers/{containerId}/migrate</code></code></pre><p>Request</p><pre><code></code></pre><pre><code><code>{
  "target_node":"node-99"
}</code></code></pre><p>Response</p><pre><code></code></pre><pre><code><code>{
  "migration_id":"mig-111",
  "status":"IN_PROGRESS"
}</code></code></pre><div><hr></div><h2>Scale Container</h2><pre><code></code></pre><pre><code><code>POST /v1/containers/{containerId}/scale</code></code></pre><p>Request</p><pre><code></code></pre><pre><code><code>{
  "replicas":20
}</code></code></pre><p>Response</p><pre><code></code></pre><pre><code><code>{
  "status":"SCALING"
}</code></code></pre><div><hr></div><h2>Create Network</h2><pre><code></code></pre><pre><code><code>POST /v1/networks</code></code></pre><p>Request</p><pre><code></code></pre><pre><code><code>{
  "name":"payment-network",
  "cidr":"10.10.0.0/16"
}</code></code></pre><p>Response</p><pre><code></code></pre><pre><code><code>{
  "network_id":"net-123"
}</code></code></pre><div><hr></div><h1>Database Choice</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7956f0d5-f05c-4a3e-a5b9-c7a8e42b027e&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Component          | DB            |
| ------------------ | ------------- |
| Container Metadata | PostgreSQL    |
| Cluster State      | etcd          |
| Metrics            | Cassandra     |
| Logs               | Elasticsearch |
| Cache              | Redis         |
</code></pre></div><div><hr></div><h1>Database Schemas</h1><h2>Container</h2><pre><code></code></pre><pre><code><code>{
  "container_id":"ctr-123",
  "image":"nginx:latest",
  "status":"RUNNING",
  "node_id":"node-45",
  "network_id":"net-123",
  "cpu":"2",
  "memory":"4GB",
  "created_at":"timestamp"
}</code></code></pre><div><hr></div><h2>Node</h2><pre><code></code></pre><pre><code><code>{
  "node_id":"node-45",
  "hostname":"worker-1",
  "ip":"192.168.1.10",
  "cpu_total":"64",
  "cpu_available":"20",
  "memory_total":"256GB",
  "memory_available":"120GB",
  "status":"HEALTHY"
}</code></code></pre><div><hr></div><h2>Cluster</h2><pre><code></code></pre><pre><code><code>{
  "cluster_id":"cluster-1",
  "name":"us-east-cluster",
  "region":"us-east",
  "status":"ACTIVE"
}</code></code></pre><div><hr></div><h2>Network</h2><pre><code></code></pre><pre><code><code>{
  "network_id":"net-123",
  "name":"payment-network",
  "cidr":"10.10.0.0/16",
  "gateway":"10.10.0.1"
}</code></code></pre><div><hr></div><h2>Migration Job</h2><pre><code></code></pre><pre><code><code>{
  "migration_id":"mig-111",
  "container_id":"ctr-123",
  "source_node":"node-45",
  "target_node":"node-99",
  "status":"IN_PROGRESS",
  "created_at":"timestamp"
}</code></code></pre><div><hr></div><h1>High Level Components</h1><pre><code></code></pre><pre><code><code>                    +------------------+
                    |      User        |
                    +---------+--------+
                              |
                              v
                    +------------------+
                    |    API Gateway   |
                    +---------+--------+
                              |
          -----------------------------------------
          |              |            |           |
          v              v            v           v

+----------------+ +--------------+ +---------------+
| Deployment     | | Migration    | | Network       |
| Service        | | Service      | | Service       |
+-------+--------+ +------+-------+ +-------+-------+
        |                 |                 |
        |                 |                 |
        v                 v                 v

+--------------------------------------------------+
|              Scheduler Service                   |
+--------------------------------------------------+
                        |
                        v

+--------------------------------------------------+
|              Cluster Manager                     |
+--------------------------------------------------+
                        |
        -----------------------------------
        |                |               |
        v                v               v

+------------+ +-------------+ +-------------+
| Node Agent | | Node Agent  | | Node Agent  |
| Node-1     | | Node-2      | | Node-N      |
+------------+ +-------------+ +-------------+</code></code></pre><div><hr></div><h1>Container Deployment Flow</h1><pre><code></code></pre><pre><code><code>User
 |
 | Deploy Container
 v

API Gateway
 |
 v

Deployment Service
 |
 v

Scheduler
 |
 | Find best node
 v

Cluster Manager
 |
 v

Node Agent
 |
 | Pull Image
 | Create Container
 v

Container Runtime
 |
 v

Container Running</code></code></pre><div><hr></div><h1>Container Migration Flow</h1><pre><code></code></pre><pre><code><code>User
 |
 | Migrate Container
 v

Migration Service
 |
 v

Scheduler
 |
 | Select Target Node
 v

Checkpoint Service
 |
 | Save Container State
 v

Target Node Agent
 |
 | Restore State
 v

Network Service
 |
 | Update Routing
 v

Container Running on New Node</code></code></pre><div><hr></div><h1>Microservices</h1><h3>1. API Gateway</h3><ul><li><p>Authentication<br></p></li><li><p>Rate limiting<br></p></li><li><p>Routing<br></p></li></ul><h3>2. Deployment Service</h3><ul><li><p>Container deployment<br></p></li><li><p>Scaling requests<br></p></li></ul><h3>3. Scheduler Service</h3><ul><li><p>Node selection<br></p></li><li><p>Resource allocation<br></p></li></ul><h3>4. Migration Service</h3><ul><li><p>Container relocation<br></p></li><li><p>State transfer<br></p></li></ul><h3>5. Network Service</h3><ul><li><p>Overlay networking<br></p></li><li><p>Service discovery<br></p></li></ul><h3>6. Cluster Manager</h3><ul><li><p>Cluster state management<br></p></li><li><p>Node registration<br></p></li></ul><h3>7. Health Monitoring Service</h3><ul><li><p>Metrics collection<br></p></li><li><p>Alerting<br></p></li></ul><h3>8. Auto-Healing Service</h3><ul><li><p>Restart failed containers<br></p></li><li><p>Reschedule workloads<br></p></li></ul><h3>9. Image Registry Service</h3><ul><li><p>Image storage<br></p></li><li><p>Image versioning<br></p></li></ul><h3>10. Audit &amp; Security Service</h3><ul><li><p>RBAC<br></p></li><li><p>Secrets management<br></p></li><li><p>Compliance logs<br></p></li></ul><div><hr></div><h1>Microservice Interaction</h1><pre><code></code></pre><pre><code><code>                 +----------------+
                 | API Gateway    |
                 +-------+--------+
                         |
     ------------------------------------------------
     |              |              |                |
     v              v              v                v

Deployment   Migration      Network         Monitoring
 Service      Service       Service           Service
     |              |             |                |
     ------------------------------------------------
                         |
                         v

                  Scheduler
                         |
                         v

                 Cluster Manager
                         |
         ---------------------------------
         |               |               |
         v               v               v

      Node Agent     Node Agent      Node Agent
         |               |               |
         ---------------------------------
                         |
                         v

                Container Runtime
             (containerd / Docker)</code></code></pre><div><hr></div><h1>Bottlenecks &amp; Scaling</h1><h3>Scheduler Bottleneck</h3><ul><li><p>Use sharded schedulers.<br></p></li><li><p>Leader election via etcd.<br></p></li></ul><h3>Metrics Explosion</h3><ul><li><p>Store metrics in Cassandra.<br></p></li><li><p>Aggregate before persistence.<br></p></li></ul><h3>Container Migration</h3><ul><li><p>Use incremental checkpoints.<br></p></li><li><p>Transfer only changed memory pages.<br></p></li></ul><h3>Multi-Region Networking</h3><ul><li><p>Overlay network (VXLAN/WireGuard).<br></p></li><li><p>Global service discovery.<br></p></li></ul><h3>Cluster State</h3><ul><li><p>Store in etcd with Raft consensus.<br></p></li><li><p>Multiple replicas for HA.<br></p></li></ul><p>This design is very close to how modern orchestration platforms such as Kubernetes, Nomad, and Docker Swarm manage large-scale container deployments across clusters and networks.</p>]]></content:encoded></item><item><title><![CDATA[HLD: TrackGen -Design a tracking if (TrackGen) product]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/hld-trackgen-design-a-tracking-if</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-trackgen-design-a-tracking-if</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Mon, 08 Jun 2026 17:22:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><h2>Functional Requirements (FR)</h2><h3>1. Asset Tracking</h3><ul><li><p>System should track assets (packages, vehicles, devices, orders) in real-time.</p></li><li><p>Support GPS coordinate updates.</p></li></ul><h3>2. Location History</h3><ul><li><p>Store and retrieve complete location history of tracked entities.</p></li><li><p>Allow querying historical movement.</p></li></ul><h3>3. Geofence Management</h3><ul><li><p>Create geofences around specific locations.</p></li><li><p>Trigger events when tracked entities enter or exit geofences.</p></li></ul><h3>4. Alerts &amp; Notifications</h3><ul><li><p>Generate alerts for:</p><ul><li><p>Geofence breach</p></li><li><p>Device offline</p></li><li><p>Route deviation</p></li><li><p>Low battery</p></li></ul></li></ul><h3>5. Tracking Dashboard</h3><ul><li><p>Display current location, status, speed, route, and historical trails.</p></li><li><p>Support filtering and search.</p></li></ul><div><hr></div><h1>Non-Functional Requirements (NFR)</h1><h3>1. High Availability</h3><ul><li><p>99.99% uptime.</p></li></ul><h3>2. Scalability</h3><ul><li><p>Support 10M+ tracked devices.</p></li><li><p>Support 100K location updates/sec.</p></li></ul><h3>3. Low Latency</h3><ul><li><p>Location updates visible within 2-3 seconds.</p></li></ul><h3>4. Durability</h3><ul><li><p>No loss of tracking events.</p></li></ul><h3>5. Security</h3><ul><li><p>OAuth/JWT authentication.</p></li><li><p>Encrypted data in transit and at rest.</p></li></ul><div><hr></div><h1>APIs</h1><div><hr></div><h2>1. Register Tracking Device</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>POST /api/v1/devices</code></code></pre><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "assetType": "VEHICLE",
  "assetId": "CAR123"
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "status": "REGISTERED"
}</code></code></pre><div><hr></div><h2>2. Update Location</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>POST /api/v1/location/update</code></code></pre><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "latitude": 12.9716,
  "longitude": 77.5946,
  "speed": 45,
  "timestamp": 1745000000
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "status": "SUCCESS"
}</code></code></pre><div><hr></div><h2>3. Get Current Location</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>GET /api/v1/location/current/{deviceId}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "latitude": 12.9716,
  "longitude": 77.5946,
  "speed": 45,
  "timestamp": 1745000000
}</code></code></pre><div><hr></div><h2>4. Get Location History</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>GET /api/v1/location/history</code></code></pre><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "startTime": 1745000000,
  "endTime": 1746000000
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "locations": [
    {
      "latitude": 12.9716,
      "longitude": 77.5946,
      "timestamp": 1745000000
    }
  ]
}</code></code></pre><div><hr></div><h2>5. Create Geofence</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>POST /api/v1/geofence</code></code></pre><pre><code></code></pre><pre><code><code>{
  "geofenceId": "GF123",
  "name": "Warehouse",
  "centerLatitude": 12.9716,
  "centerLongitude": 77.5946,
  "radiusMeters": 500
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "status": "CREATED"
}</code></code></pre><div><hr></div><h2>6. Get Alerts</h2><h3>Request</h3><pre><code></code></pre><pre><code><code>GET /api/v1/alerts/{deviceId}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "alerts": [
    {
      "alertType": "GEOFENCE_EXIT",
      "timestamp": 1745000000
    }
  ]
}</code></code></pre><div><hr></div><h1>Database Design</h1><h2>Device Table</h2><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "assetId": "CAR123",
  "assetType": "VEHICLE",
  "status": "ACTIVE",
  "registeredAt": "2026-01-01T10:00:00Z"
}</code></code></pre><p>Partition Key:</p><pre><code></code></pre><pre><code><code>deviceId</code></code></pre><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h2>Current Location Table</h2><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "latitude": 12.9716,
  "longitude": 77.5946,
  "speed": 45,
  "lastUpdatedAt": "2026-01-01T10:10:00Z"
}</code></code></pre><p>Partition Key:</p><pre><code></code></pre><pre><code><code>deviceId</code></code></pre><p>Database:</p><pre><code></code></pre><pre><code><code>Redis</code></code></pre><div><hr></div><h2>Location History Table</h2><pre><code></code></pre><pre><code><code>{
  "deviceId": "DEV123",
  "timestamp": 1745000000,
  "latitude": 12.9716,
  "longitude": 77.5946,
  "speed": 45
}</code></code></pre><p>Partition Key:</p><pre><code></code></pre><pre><code><code>deviceId</code></code></pre><p>Sort Key:</p><pre><code></code></pre><pre><code><code>timestamp</code></code></pre><p>Database:</p><pre><code></code></pre><pre><code><code>Cassandra</code></code></pre><div><hr></div><h2>Geofence Table</h2><pre><code></code></pre><pre><code><code>{
  "geofenceId": "GF123",
  "name": "Warehouse",
  "centerLatitude": 12.9716,
  "centerLongitude": 77.5946,
  "radiusMeters": 500,
  "createdAt": "2026-01-01T10:00:00Z"
}</code></code></pre><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h2>Alert Table</h2><pre><code></code></pre><pre><code><code>{
  "alertId": "ALT123",
  "deviceId": "DEV123",
  "alertType": "GEOFENCE_EXIT",
  "message": "Vehicle left warehouse zone",
  "createdAt": "2026-01-01T10:15:00Z"
}</code></code></pre><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h1>High Level Architecture</h1><pre><code></code></pre><pre><code><code>                +----------------+
                | Mobile Device  |
                | GPS Tracker    |
                +--------+-------+
                         |
                         v
                +----------------+
                | API Gateway    |
                +--------+-------+
                         |
                         v
                +----------------+
                | Tracking       |
                | Service        |
                +--------+-------+
                         |
          +--------------+--------------+
          |                             |
          v                             v

 +----------------+         +-------------------+
 | Redis Current  |         | Kafka             |
 | Location Cache |         | Location Stream   |
 +----------------+         +---------+---------+
                                      |
                                      |
             +------------------------+------------------+
             |                                           |
             v                                           v

   +-------------------+                     +------------------+
   | Location History  |                     | Geofence Engine  |
   | Service           |                     | Service          |
   +--------+----------+                     +--------+---------+
            |                                         |
            v                                         v

      +------------+                          +--------------+
      | Cassandra  |                          | Alert Service|
      +------------+                          +------+-------+
                                                      |
                                                      v
                                            +------------------+
                                            | Notification     |
                                            | Service          |
                                            +------------------+</code></code></pre><div><hr></div><h1>Microservices</h1><h2>1. Device Service</h2><p>Responsibilities:</p><ul><li><p>Device registration<br></p></li><li><p>Device lifecycle management<br></p></li><li><p>Device metadata storage<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h2>2. Tracking Service</h2><p>Responsibilities:</p><ul><li><p>Receive GPS updates<br></p></li><li><p>Validate payload<br></p></li><li><p>Publish events to Kafka<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>Redis</code></code></pre><div><hr></div><h2>3. Location History Service</h2><p>Responsibilities:</p><ul><li><p>Persist location updates<br></p></li><li><p>Historical queries<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>Cassandra</code></code></pre><div><hr></div><h2>4. Geofence Service</h2><p>Responsibilities:</p><ul><li><p>Geofence creation<br></p></li><li><p>Entry/exit detection<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h2>5. Alert Service</h2><p>Responsibilities:</p><ul><li><p>Generate alerts<br></p></li><li><p>Store alert history<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>PostgreSQL</code></code></pre><div><hr></div><h2>6. Notification Service</h2><p>Responsibilities:</p><ul><li><p>SMS notifications<br></p></li><li><p>Email notifications<br></p></li><li><p>Push notifications<br></p></li></ul><p>Database:</p><pre><code></code></pre><pre><code><code>None (Stateless)</code></code></pre><div><hr></div><h1>End-to-End Flow</h1><pre><code></code></pre><pre><code><code>1. GPS Device sends location update.

2. API Gateway forwards request to Tracking Service.

3. Tracking Service:
   - Validates request
   - Updates Redis current location
   - Publishes LocationEvent to Kafka

4. Location History Service consumes event.
   - Stores event in Cassandra

5. Geofence Service consumes event.
   - Checks geofence rules

6. If breach detected:
   - Generate Alert Event

7. Alert Service stores alert.

8. Notification Service sends SMS/Email/Push.

9. Dashboard fetches:
   - Current location from Redis
   - Historical route from Cassandra
   - Alerts from PostgreSQL</code></code></pre><h3>Scale Estimation</h3><pre><code></code></pre><pre><code><code>10 Million Devices

Average Update Frequency = 30 seconds

Writes/sec
= 10,000,000 / 30
&#8776; 333,000 writes/sec

Daily Location Records
&#8776; 28 Billion records/day

Storage Choice:
- Redis -&gt; Current State
- Kafka -&gt; Streaming
- Cassandra -&gt; Time Series History
- PostgreSQL -&gt; Metadata &amp; Alerts</code></code></pre><p>This design is suitable for a logistics, fleet-management, package-tracking, or IoT tracking platform operating at internet scale.</p>]]></content:encoded></item><item><title><![CDATA[HLD: Design a distributed search system that indexes 1 million files and supports querying files containing a given word]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/hld-design-a-distributed-search-system</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-a-distributed-search-system</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Mon, 08 Jun 2026 17:16:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><p>Example:</p><p>Search Query: <code>"red"</code><br>Expected Output: List of all file IDs/names containing the word <code>"red"</code>.</p><p>Traffic:</p><ul><li><p>~10 lakh requests/day (~11.5 requests/sec average)</p></li><li><p>Assume:</p><ul><li><p>Exact keyword matching only</p></li><li><p>No typo tolerance</p></li><li><p>Words contain only <code>a-z</code></p></li><li><p>Files can be added/updated periodically</p></li></ul></li></ul><div><hr></div><h1>Functional Requirements (FR)</h1><h3>FR1. File Ingestion</h3><p>System should accept and process files for indexing.</p><div><hr></div><h3>FR2. Word Extraction &amp; Tokenization</h3><p>System should parse files and extract normalized words (<code>a-z</code> only).</p><div><hr></div><h3>FR3. Inverted Index Creation</h3><p>System should maintain an inverted index mapping:</p><pre><code></code></pre><pre><code><code>word &#8594; list of file_ids</code></code></pre><p>Example:</p><pre><code></code></pre><pre><code><code>red &#8594; [file1, file8, file20]</code></code></pre><div><hr></div><h3>FR4. Search API</h3><p>User should be able to search for a word and retrieve all matching files.</p><div><hr></div><h3>FR5. Incremental Updates</h3><p>System should support:</p><ul><li><p>New file addition<br></p></li><li><p>File modification<br></p></li><li><p>File deletion<br><br>without rebuilding the complete index.<br></p></li></ul><div><hr></div><h1>Non-Functional Requirements (NFR)</h1><h3>NFR1. Low Latency</h3><p>Search response time should be under 100ms.</p><div><hr></div><h3>NFR2. High Availability</h3><p>Search service should remain available during node failures.</p><div><hr></div><h3>NFR3. Scalability</h3><p>System should scale horizontally as:</p><ul><li><p>Number of files increases<br></p></li><li><p>Query traffic increases<br></p></li></ul><div><hr></div><h3>NFR4. Durability</h3><p>Indexed metadata and file mappings should not be lost.</p><div><hr></div><h3>NFR5. Efficient Storage</h3><p>Index storage should be optimized using compression and deduplication.</p><div><hr></div><h1>High Level Architecture</h1><pre><code></code></pre><pre><code><code>                +------------------+
                |   Client/User    |
                +--------+---------+
                         |
                         v
               +---------+----------+
               |   Search API Layer |
               +---------+----------+
                         |
              +----------+-----------+
              |                      |
              v                      v
     +--------+-------+      +-------+--------+
     |   Query Cache  |      | Search Service |
     |    (Redis)     |      +-------+--------+
     +----------------+              |
                                     v
                          +----------+----------+
                          |   Inverted Index    |
                          |  (ElasticSearch /  |
                          |    Lucene Index)   |
                          +----------+----------+
                                     |
                  +------------------+------------------+
                  |                                     |
                  v                                     v
        +---------+---------+             +-------------+----------+
        | Index Builder     |             | Metadata DB            |
        | Tokenizer Engine  |             | (File Metadata Store)  |
        +---------+---------+             +------------------------+
                  |
                  v
         +--------+--------+
         | Distributed File |
         | Storage (S3/HDFS)|
         +------------------+</code></code></pre><div><hr></div><h1>Core Idea &#8212; Inverted Index</h1><p>Traditional search over 1 million files is expensive:</p><pre><code></code></pre><pre><code><code>For every query:
   Scan all files</code></code></pre><p>Complexity:</p><pre><code></code></pre><pre><code><code>O(number_of_files)</code></code></pre><p>Instead, build an inverted index.</p><div><hr></div><h2>Inverted Index Structure</h2><pre><code></code></pre><pre><code><code>{
   "red"  : [1, 7, 10, 55],
   "blue" : [2, 3, 10],
   "car"  : [5, 6]
}</code></code></pre><p>Search becomes:</p><pre><code></code></pre><pre><code><code>Lookup(word)</code></code></pre><p>Complexity:</p><pre><code></code></pre><pre><code><code>O(1) or O(logN)</code></code></pre><p>depending on storage engine.</p><div><hr></div><h1>Components</h1><h2>1. File Storage Service</h2><p>Stores original files.</p><p>Possible storage:</p><ul><li><p>HDFS<br></p></li><li><p>S3<br></p></li><li><p>Blob storage<br></p></li></ul><p>Each file gets:</p><pre><code></code></pre><pre><code><code>{
  "file_id": "f123",
  "path": "/docs/a.txt",
  "uploaded_at": 1712345678
}</code></code></pre><div><hr></div><h1>2. File Ingestion Service</h1><p>Responsible for:</p><ul><li><p>Accepting files<br></p></li><li><p>Sending indexing jobs to queue<br></p></li></ul><p>Flow:</p><pre><code></code></pre><pre><code><code>Upload File
    &#8595;
Generate file_id
    &#8595;
Push indexing job to Kafka/SQS</code></code></pre><div><hr></div><h1>3. Tokenizer / Parser Service</h1><p>Reads file contents and extracts words.</p><p>Steps:</p><ul><li><p>Lowercase conversion<br></p></li><li><p>Remove punctuation<br></p></li><li><p>Split into words<br></p></li></ul><p>Example:</p><pre><code></code></pre><pre><code><code>"The Red Car"</code></code></pre><p>becomes:</p><pre><code></code></pre><pre><code><code>["the", "red", "car"]</code></code></pre><div><hr></div><h1>4. Index Builder</h1><p>Builds inverted index.</p><p>Example:</p><pre><code></code></pre><pre><code><code>file1 -&gt; ["red", "car"]

Index:
red -&gt; file1
car -&gt; file1</code></code></pre><div><hr></div><h1>5. Search Service</h1><p>Handles user queries.</p><p>Flow:</p><ol><li><p>Receive query <code>"red"</code><br></p></li><li><p>Check Redis cache<br></p></li><li><p>Lookup inverted index<br></p></li><li><p>Return matching files<br></p></li></ol><div><hr></div><h1>Database Design</h1><h2>A. File Metadata Table</h2><pre><code></code></pre><pre><code><code>{
  "file_id": "string",
  "file_name": "string",
  "storage_path": "string",
  "uploaded_at": "timestamp",
  "version": "int",
  "status": "ACTIVE | DELETED"
}</code></code></pre><p>Database:</p><ul><li><p>PostgreSQL<br><br>or<br></p></li><li><p>MySQL<br></p></li></ul><div><hr></div><h2>B. Inverted Index Storage</h2><h3>Logical Schema</h3><pre><code></code></pre><pre><code><code>{
  "word": "red",
  "document_frequency": 1200,
  "posting_list": [
    "file1",
    "file8",
    "file20"
  ]
}</code></code></pre><p>Preferred technologies:</p><ul><li><p>ElasticSearch<br></p></li><li><p>Apache Lucene<br></p></li><li><p>OpenSearch<br></p></li></ul><div><hr></div><h1>Search Flow</h1><pre><code></code></pre><pre><code><code>User Searches "red"
        |
        v
Search API
        |
        v
Redis Cache Check
   |          |
Hit          Miss
 |             |
Return      Query Index
                 |
                 v
        Get Posting List
                 |
                 v
         Fetch Metadata
                 |
                 v
            Return Files</code></code></pre><div><hr></div><h1>File Indexing Flow</h1><pre><code></code></pre><pre><code><code>File Upload
    |
    v
Ingestion Service
    |
    v
Message Queue (Kafka)
    |
    v
Indexer Worker
    |
    v
Tokenizer
    |
    v
Update Inverted Index</code></code></pre><div><hr></div><h1>Scaling Strategy</h1><h2>Read Scaling</h2><p>Search traffic is read-heavy.</p><p>Use:</p><ul><li><p>Multiple search replicas<br></p></li><li><p>Load balancer<br></p></li><li><p>Redis cache<br></p></li></ul><div><hr></div><h2>Index Partitioning (Sharding)</h2><p>Partition words alphabetically:</p><pre><code></code></pre><pre><code><code>a-f  &#8594; shard1
g-l  &#8594; shard2
m-r  &#8594; shard3
s-z  &#8594; shard4</code></code></pre><p>or use:</p><ul><li><p>Consistent hashing<br></p></li></ul><div><hr></div><h1>Caching Strategy</h1><p>Popular searches cached in Redis.</p><p>Example:</p><pre><code></code></pre><pre><code><code>key   = "red"
value = [file1, file2, file8]
TTL   = 10 mins</code></code></pre><p>Reduces repeated index lookups.</p><div><hr></div><h1>Estimation</h1><h2>Requests</h2><pre><code></code></pre><pre><code><code>10 lakh/day
&#8776; 11.5 req/sec average
Peak &#8776; 100-200 req/sec</code></code></pre><p>Very manageable with:</p><ul><li><p>Redis<br></p></li><li><p>ElasticSearch cluster<br></p></li></ul><div><hr></div><h1>Fault Tolerance</h1><h2>Replication</h2><p>Maintain:</p><ul><li><p>Replica index shards<br></p></li><li><p>Multi-node search cluster<br></p></li></ul><div><hr></div><h2>Queue Durability</h2><p>Kafka persists indexing jobs.</p><p>If indexer crashes:</p><ul><li><p>Job replay possible<br></p></li></ul><div><hr></div><h1>Optimizations</h1><h2>1. Compression</h2><p>Store posting lists using:</p><ul><li><p>Delta encoding<br></p></li><li><p>Bitmaps<br></p></li></ul><div><hr></div><h2>2. Skip Lists</h2><p>Improve search traversal for large posting lists.</p><div><hr></div><h2>3. Batch Indexing</h2><p>Instead of updating index per file:</p><ul><li><p>Batch updates every few seconds.<br></p></li></ul><div><hr></div><h1>Bottlenecks</h1><h2>Hot Keywords</h2><p>Words like:</p><pre><code></code></pre><pre><code><code>the, is, and</code></code></pre><p>can have huge posting lists.</p><p>Solution:</p><ul><li><p>Stop-word filtering<br></p></li><li><p>Compressed bitmaps<br></p></li></ul><div><hr></div><h1>Technologies</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;cec65cfa-f84d-4109-bc8d-c965843d5924&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Component     | Technology            |
| ------------- | --------------------- |
| API Layer     | Go / Java Spring Boot |
| Queue         | Kafka                 |
| Cache         | Redis                 |
| Search Engine | ElasticSearch         |
| Metadata DB   | PostgreSQL            |
| Storage       | S3 / HDFS             |
</code></pre></div><div><hr></div><h1>Final Design Summary</h1><p>The system uses an inverted index to efficiently map:</p><pre><code></code></pre><pre><code><code>word &#8594; files</code></code></pre><p>Core benefits:</p><ul><li><p>Fast lookup<br></p></li><li><p>Horizontal scalability<br></p></li><li><p>Incremental indexing<br></p></li><li><p>Low latency search<br></p></li></ul><p>The architecture separates:</p><ul><li><p>File storage<br></p></li><li><p>Index building<br></p></li><li><p>Search serving<br></p></li></ul><p>allowing the system to scale independently for ingestion and querying.</p>]]></content:encoded></item><item><title><![CDATA[HLD: Design a system that levies penalties or taxes on riders/drivers based on constraints like completing a minimum number of rides per month or getting below-average ratings.]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/hld-design-a-system-that-levies-penalties</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-a-system-that-levies-penalties</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 26 May 2026 18:23:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><h2>Functional Requirements (FR)</h2><ol><li><p><strong>Penalty/Tax Rule Management</strong><br>System should allow admins to define and manage dynamic rules for penalties/taxes based on:</p><ul><li><p>Minimum rides completed</p></li><li><p>Cancellation rate</p></li><li><p>Average rider/driver ratings</p></li><li><p>Inactive days</p></li><li><p>Peak-hour participation</p></li><li><p>Fraud signals</p></li></ul></li><li><p><strong>Periodic Evaluation Engine</strong><br>System should periodically evaluate riders/drivers (daily/weekly/monthly) against configured rules and determine applicable penalties or taxes.</p></li><li><p><strong>Penalty Calculation &amp; Ledger Management</strong><br>System should calculate penalty amounts accurately and maintain a financial ledger/history for every deduction, adjustment, refund, or waiver.</p></li><li><p><strong>Notification &amp; Transparency</strong><br>Users should receive notifications explaining:</p><ul><li><p>Why the penalty was applied</p></li><li><p>Rule violated</p></li><li><p>Amount deducted</p></li><li><p>Appeal process</p></li><li><p>Deadline for compliance</p></li></ul></li><li><p><strong>Appeal &amp; Dispute Handling</strong><br>Riders/drivers should be able to raise disputes against penalties, upload proofs, and track appeal status through the platform.</p></li></ol><div><hr></div><h2>Non-Functional Requirements (NFR)</h2><ol><li><p><strong>Scalability</strong><br>System should support millions of riders/drivers and evaluate penalties for large datasets efficiently during monthly batch processing.</p></li><li><p><strong>High Availability</strong><br>Critical services like rule evaluation, deductions, and notifications should maintain high availability (99.9%+) to avoid financial inconsistencies.</p></li><li><p><strong>Consistency &amp; Accuracy</strong><br>Financial calculations and deductions must be strongly consistent to prevent duplicate or incorrect penalties.</p></li><li><p><strong>Extensibility</strong><br>System should support adding new penalty rules and policy types without requiring major architectural changes.</p></li><li><p><strong>Auditability &amp; Compliance</strong><br>Every rule evaluation, deduction, override, and admin action should be fully auditable for regulatory and legal compliance.</p></li></ol><h1>APIs for Penalty/Tax Enforcement System</h1><div><hr></div><h2>1. Create Penalty Rule</h2><h3>API</h3><p><code>POST /api/v1/rules</code></p><h3>Request</h3><pre><code></code></pre><pre><code><code>{
  "ruleName": "Minimum Monthly Ride Rule",
  "entityType": "DRIVER",
  "condition": {
    "metric": "MONTHLY_RIDES",
    "operator": "LESS_THAN",
    "value": 100
  },
  "penalty": {
    "type": "FIXED",
    "amount": 500
  },
  "evaluationFrequency": "MONTHLY",
  "isActive": true
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "ruleId": "RULE_12345",
  "status": "CREATED",
  "createdAt": "2026-05-26T10:00:00Z"
}</code></code></pre><div><hr></div><h2>2. Evaluate User Eligibility for Penalty</h2><h3>API</h3><p><code>POST /api/v1/evaluations/run</code></p><h3>Request</h3><pre><code></code></pre><pre><code><code>{
  "entityType": "DRIVER",
  "entityId": "DRIVER_789",
  "evaluationPeriod": "2026-05"
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "entityId": "DRIVER_789",
  "evaluationPeriod": "2026-05",
  "violations": [
    {
      "ruleId": "RULE_12345",
      "metricValue": 72,
      "expectedValue": 100,
      "penaltyAmount": 500
    }
  ],
  "totalPenalty": 500,
  "status": "PENALTY_APPLIED"
}</code></code></pre><div><hr></div><h2>3. Fetch Penalty History</h2><h3>API</h3><p><code>GET /api/v1/penalties/{entityId}</code></p><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "entityId": "DRIVER_789",
  "penalties": [
    {
      "penaltyId": "PEN_1001",
      "ruleId": "RULE_12345",
      "amount": 500,
      "status": "DEDUCTED",
      "createdAt": "2026-05-26T12:00:00Z"
    },
    {
      "penaltyId": "PEN_1002",
      "ruleId": "RULE_99999",
      "amount": 200,
      "status": "WAIVED",
      "createdAt": "2026-04-26T12:00:00Z"
    }
  ]
}</code></code></pre><div><hr></div><h2>4. Deduct Penalty from Wallet</h2><h3>API</h3><p><code>POST /api/v1/wallets/deduct</code></p><h3>Request</h3><pre><code></code></pre><pre><code><code>{
  "entityId": "DRIVER_789",
  "penaltyId": "PEN_1001",
  "amount": 500,
  "currency": "INR"
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "transactionId": "TXN_56789",
  "walletBalance": 3200,
  "status": "SUCCESS"
}</code></code></pre><div><hr></div><h2>5. Raise Penalty Dispute</h2><h3>API</h3><p><code>POST /api/v1/disputes</code></p><h3>Request</h3><pre><code></code></pre><pre><code><code>{
  "penaltyId": "PEN_1001",
  "entityId": "DRIVER_789",
  "reason": "Ride count calculation incorrect",
  "attachments": [
    "s3://proofs/screenshot1.png"
  ]
}</code></code></pre><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "disputeId": "DISP_4567",
  "status": "UNDER_REVIEW",
  "createdAt": "2026-05-26T13:00:00Z"
}</code></code></pre><div><hr></div><h2>6. Get Evaluation Summary Dashboard</h2><h3>API</h3><p><code>GET /api/v1/reports/summary?period=2026-05</code></p><h3>Response</h3><pre><code></code></pre><pre><code><code>{
  "period": "2026-05",
  "totalDriversEvaluated": 1000000,
  "totalPenaltiesApplied": 125000,
  "totalAmountCollected": 45000000,
  "topViolationReasons": [
    {
      "rule": "MIN_MONTHLY_RIDES",
      "count": 80000
    },
    {
      "rule": "LOW_RATING",
      "count": 45000
    }
  ]
}</code></code></pre><p></p><p><strong>Databases and Schema</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;060d05ef-6574-4d03-b609-c36ef225043b&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">```json
{
  "users": {
    "user_id": "BIGINT",
    "user_type": "ENUM(DRIVER, RIDER)",
    "name": "VARCHAR",
    "avg_rating": "DECIMAL(2,1)",
    "total_rides": "BIGINT",
    "wallet_balance": "DECIMAL",
    "status": "ENUM(ACTIVE, BLOCKED)",
    "created_at": "TIMESTAMP"
  },

  "penalty_rules": {
    "rule_id": "BIGINT",
    "rule_name": "VARCHAR",
    "entity_type": "ENUM(DRIVER, RIDER)",
    "metric": "VARCHAR",
    "operator": "ENUM(LESS_THAN, GREATER_THAN)",
    "threshold_value": "DECIMAL",
    "penalty_type": "ENUM(FIXED, PERCENTAGE)",
    "penalty_amount": "DECIMAL",
    "evaluation_frequency": "ENUM(DAILY, WEEKLY, MONTHLY)",
    "is_active": "BOOLEAN",
    "created_by": "BIGINT",
    "created_at": "TIMESTAMP"
  },

  "user_metrics": {
    "metric_id": "BIGINT",
    "user_id": "BIGINT",
    "month": "VARCHAR",
    "completed_rides": "INT",
    "cancelled_rides": "INT",
    "avg_rating": "DECIMAL(2,1)",
    "online_hours": "INT",
    "last_updated_at": "TIMESTAMP"
  },

  "penalties": {
    "penalty_id": "BIGINT",
    "user_id": "BIGINT",
    "rule_id": "BIGINT",
    "metric_value": "DECIMAL",
    "expected_value": "DECIMAL",
    "penalty_amount": "DECIMAL",
    "status": "ENUM(APPLIED, DEDUCTED, WAIVED)",
    "evaluation_period": "VARCHAR",
    "created_at": "TIMESTAMP"
  },

  "wallet_transactions": {
    "transaction_id": "BIGINT",
    "user_id": "BIGINT",
    "penalty_id": "BIGINT",
    "transaction_type": "ENUM(DEBIT, CREDIT)",
    "amount": "DECIMAL",
    "balance_after_txn": "DECIMAL",
    "transaction_status": "ENUM(SUCCESS, FAILED)",
    "created_at": "TIMESTAMP"
  },

  "disputes": {
    "dispute_id": "BIGINT",
    "penalty_id": "BIGINT",
    "user_id": "BIGINT",
    "reason": "TEXT",
    "attachment_url": "VARCHAR",
    "status": "ENUM(UNDER_REVIEW, APPROVED, REJECTED)",
    "resolved_by": "BIGINT",
    "resolution_notes": "TEXT",
    "created_at": "TIMESTAMP",
    "resolved_at": "TIMESTAMP"
  },

  "audit_logs": {
    "audit_id": "BIGINT",
    "entity_type": "VARCHAR",
    "entity_id": "BIGINT",
    "action": "VARCHAR",
    "performed_by": "BIGINT",
    "old_value": "JSON",
    "new_value": "JSON",
    "created_at": "TIMESTAMP"
  }
}
```

</code></pre></div><p></p><p>HLD</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;9b37668f-f661-40e7-aa85-3212e0f3d38a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">```text
========================================================
HIGH LEVEL DESIGN (HLD)
========================================================

                    +----------------------+
                    |      Admin Panel     |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    |   Rule Management    |
                    |      Service         |
                    +----------+-----------+
                               |
                               v
                    +----------------------+
                    |   Penalty Rules DB   |
                    +----------------------+



+------------+       +----------------------+       +------------------+
| Ride       | ----&gt; |  Event Ingestion     | ----&gt; | Kafka/Event Bus  |
| Service    |       |  Service             |       +--------+---------+
+------------+       +----------------------+                |
                                                             |
+------------+                                               |
| Rating     | ----------------------------------------------+
| Service    |                                               |
+------------+                                               |
                                                             v

                                                +----------------------+
                                                | Metrics Aggregator   |
                                                | Service              |
                                                +----------+-----------+
                                                           |
                                                           v
                                                +----------------------+
                                                | User Metrics DB      |
                                                +----------+-----------+
                                                           |
                                                           v

                                                +----------------------+
                                                | Penalty Evaluation   |
                                                | Engine               |
                                                +----------+-----------+
                                                           |
                                      +--------------------+------------------+
                                      |                                       |
                                      v                                       v

                        +--------------------------+         +------------------------+
                        | Penalty Ledger Service   |         | Notification Service   |
                        +------------+-------------+         +------------+-----------+
                                     |                                     |
                                     v                                     v

                        +--------------------------+         +------------------------+
                        | Penalty DB               |         | Email/SMS/Push         |
                        +------------+-------------+         +------------------------+
                                     |
                                     v

                        +--------------------------+
                        | Wallet Service           |
                        +------------+-------------+
                                     |
                                     v

                        +--------------------------+
                        | Wallet Transactions DB   |
                        +--------------------------+



========================================================
FLOW DIAGRAM - MONTHLY PENALTY EVALUATION
========================================================

1. Ride Completed
        |
        v
2. Ride Service emits event to Kafka
        |
        v
3. Metrics Aggregator consumes events
        |
        v
4. Update monthly metrics in User Metrics DB
        |
        v
5. Monthly Scheduler triggers Evaluation Engine
        |
        v
6. Evaluation Engine fetches:
       - Active Rules
       - User Metrics
        |
        v
7. Rule Validation
       Example:
       completed_rides &lt; 100
        |
        +---- NO ----&gt; No action
        |
        +---- YES ---&gt; Generate penalty
                             |
                             v
8. Store penalty in Penalty DB
                             |
                             v
9. Call Wallet Service
                             |
                             v
10. Deduct amount from wallet
                             |
                             v
11. Store wallet transaction
                             |
                             v
12. Send notification to user



========================================================
FLOW DIAGRAM - DISPUTE HANDLING
========================================================

1. User raises dispute
        |
        v
2. Dispute Service stores dispute
        |
        v
3. Admin reviews dispute
        |
        +---- APPROVED ----+
        |                  |
        |                  v
        |          Refund penalty
        |                  |
        |                  v
        |          Update wallet balance
        |
        +---- REJECTED ----+
                           |
                           v
                    Keep penalty active
                           |
                           v
                    Notify user



========================================================
CORE MICROSERVICES
========================================================

1. Rule Management Service
   - Create/update/delete rules
   - Rule versioning

2. Metrics Aggregator Service
   - Consume ride/rating events
   - Aggregate monthly metrics

3. Penalty Evaluation Engine
   - Execute rule evaluation jobs
   - Generate penalties

4. Penalty Ledger Service
   - Maintain immutable penalty history

5. Wallet Service
   - Deduct/refund money
   - Ensure transactional consistency

6. Notification Service
   - SMS/Push/Email alerts

7. Dispute Service
   - Dispute lifecycle management

8. Audit Service
   - Maintain compliance logs



========================================================
SCALABILITY CONSIDERATIONS
========================================================

1. Kafka partitions by user_id

2. Batch evaluation jobs partitioned by region/user buckets

3. Redis cache for active rules

4. Read replicas for analytics queries

5. Monthly partitioned tables for penalties and transactions

6. Idempotent wallet deduction APIs

7. Retry queues + DLQ for failed deductions
```</code></pre></div><p></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;8b7b5b51-ec36-4bca-8e54-ec609641f1b0&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">========================================================
MICROSERVICES AND INTERACTIONS
========================================================

1. API GATEWAY
--------------------------------------------------------
Responsibilities:
- Entry point for all clients
- Authentication &amp; authorization
- Rate limiting
- Request routing

Interacts With:
- Rule Management Service
- Penalty Service
- Dispute Service
- Wallet Service
- Notification Service



2. RULE MANAGEMENT SERVICE
--------------------------------------------------------
Responsibilities:
- Create/update/delete penalty rules
- Enable/disable rules
- Rule versioning
- Rule validation

Database:
- penalty_rules DB

Publishes Events:
- RULE_CREATED
- RULE_UPDATED
- RULE_DELETED

Interacts With:
- Admin Panel
- Penalty Evaluation Engine
- Redis Cache



3. EVENT INGESTION SERVICE
--------------------------------------------------------
Responsibilities:
- Consume ride/rating/cancellation events
- Standardize incoming events
- Push events to Kafka

Consumes From:
- Ride Service
- Rating Service

Publishes To:
- Kafka Topics



4. METRICS AGGREGATOR SERVICE
--------------------------------------------------------
Responsibilities:
- Consume Kafka events
- Aggregate monthly metrics
- Compute:
   - completed rides
   - cancellation %
   - avg ratings
   - active hours

Database:
- user_metrics DB

Consumes:
- ride_completed events
- rating_updated events
- cancellation events

Publishes:
- METRICS_UPDATED



5. PENALTY EVALUATION ENGINE
--------------------------------------------------------
Responsibilities:
- Run periodic evaluation jobs
- Fetch active rules
- Evaluate user metrics
- Generate penalties

Consumes:
- METRICS_UPDATED
- Scheduler triggers

Reads From:
- penalty_rules DB
- user_metrics DB

Publishes:
- PENALTY_CREATED

Interacts With:
- Penalty Ledger Service
- Wallet Service
- Notification Service



6. PENALTY LEDGER SERVICE
--------------------------------------------------------
Responsibilities:
- Store immutable penalty history
- Maintain audit trail
- Penalty state management

Database:
- penalties DB

Consumes:
- PENALTY_CREATED

Publishes:
- PENALTY_APPLIED
- PENALTY_WAIVED

Interacts With:
- Wallet Service
- Dispute Service
- Audit Service



7. WALLET SERVICE
--------------------------------------------------------
Responsibilities:
- Deduct penalty amount
- Refund amount on dispute approval
- Maintain financial consistency
- Handle retries/idempotency

Database:
- wallet_transactions DB

Consumes:
- PENALTY_APPLIED
- REFUND_REQUESTED

Publishes:
- PAYMENT_SUCCESS
- PAYMENT_FAILED

Interacts With:
- Penalty Service
- Notification Service



8. NOTIFICATION SERVICE
--------------------------------------------------------
Responsibilities:
- Send push/email/SMS notifications
- Notify about:
   - penalties
   - refunds
   - disputes
   - warnings

Consumes:
- PENALTY_CREATED
- PAYMENT_SUCCESS
- DISPUTE_RESOLVED

External Integrations:
- Email provider
- SMS gateway
- Push notification provider



9. DISPUTE SERVICE
--------------------------------------------------------
Responsibilities:
- Create/manage disputes
- Upload proof documents
- Track dispute lifecycle

Database:
- disputes DB

Consumes:
- User dispute requests

Publishes:
- DISPUTE_CREATED
- DISPUTE_APPROVED
- DISPUTE_REJECTED

Interacts With:
- Penalty Ledger Service
- Wallet Service
- Notification Service



10. AUDIT SERVICE
--------------------------------------------------------
Responsibilities:
- Track all admin/system actions
- Maintain compliance logs
- Store immutable audit records

Database:
- audit_logs DB

Consumes:
- RULE_UPDATED
- PENALTY_APPLIED
- DISPUTE_RESOLVED
- WALLET_DEDUCTED



========================================================
SERVICE INTERACTION FLOW
========================================================

Ride Service
     |
     v
Event Ingestion Service
     |
     v
Kafka/Event Bus
     |
     v
Metrics Aggregator Service
     |
     v
User Metrics DB
     |
     v
Penalty Evaluation Engine
     |
     +--------------------+
     |                    |
     v                    v
Penalty Ledger      Notification Service
Service
     |
     v
Wallet Service
     |
     v
Wallet Transactions DB
     |
     v
Notification Service



========================================================
ASYNC COMMUNICATION
========================================================

Kafka Topics:
- ride_completed
- ride_cancelled
- rating_updated
- metrics_updated
- penalty_created
- penalty_applied
- payment_success
- dispute_created
- dispute_resolved



========================================================
WHY MICROSERVICE ARCHITECTURE?
========================================================

1. Independent scaling of evaluation engine

2. Wallet service isolated for strong consistency

3. Rule engine can evolve independently

4. Async event-driven processing reduces coupling

5. Easier fault isolation

6. Supports millions of monthly evaluations</code></pre></div><p></p>]]></content:encoded></item><item><title><![CDATA[HLD: Automated Fault Detection & Prevention System (Router Monitoring Platform)(Asked in Microsoft)]]></title><description><![CDATA[Design a scalable platform that continuously monitors routers/network devices, detects anomalies or failures in real time, predicts potential issues, and automatically triggers preventive/remediation.]]></description><link>https://programmingappliedai.substack.com/p/hld-automated-fault-detection-and</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-automated-fault-detection-and</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 12 May 2026 16:26:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><p>Example:</p><ul><li><p>Detect high CPU spikes on routers</p></li><li><p>Predict link failures</p></li><li><p>Detect packet drops or abnormal latency</p></li><li><p>Restart interfaces automatically</p></li><li><p>Shift traffic to healthy routes</p></li></ul><div><hr></div><h1>2. Functional Requirements (FR)</h1><h3>1. The system should continuously collect router telemetry such as CPU utilization, memory usage, packet drops, interface statistics, link status, temperature, and logs/SNMP traps at configurable intervals.</h3><p>2. The system should detect failures and anomalies like router downtime, link degradation, interface flapping, traffic anomalies, high latency, and packet loss within a few seconds.</p><p>3. The system should automatically execute preventive or corrective actions such as restarting interfaces, switching routes, triggering failover, throttling traffic, or rebooting unhealthy devices based on predefined policies.</p><p>4. The system should generate alerts and incidents through channels like email, Slack, PagerDuty, and SMS for critical network issues and remediation events.</p><p>5. The system should store historical telemetry and fault data to support trend analysis, root cause analysis, capacity planning, and ML/rule-based failure prediction.</p><div><hr></div><h1>3. Non-Functional Requirements (NFR)</h1><h3>NFR1. High Availability</h3><p>Monitoring system should remain operational even during node failures.</p><p>Target: 99.99% availability.</p><div><hr></div><h3>NFR2. Low Detection Latency</h3><p>Faults should be detected within:</p><ul><li><p>2&#8211;5 seconds for critical failures</p></li><li><p>&lt;1 second for heartbeat failures</p></li></ul><div><hr></div><h3>NFR3. Massive Scalability</h3><p>Support:</p><ul><li><p>Millions of telemetry events/sec</p></li><li><p>100K+ routers</p></li><li><p>Multi-region deployments</p></li></ul><div><hr></div><h3>NFR4. Fault Tolerance</h3><p>No data loss during:</p><ul><li><p>Broker failures</p></li><li><p>Service crashes</p></li><li><p>Network partitions</p></li></ul><div><hr></div><h3>NFR5. Extensibility</h3><p>System should support:</p><ul><li><p>New device types</p></li><li><p>New telemetry protocols</p></li><li><p>Custom remediation plugins</p></li></ul><p>without major redesign.</p><div><hr></div><h1>4. High Level Architecture</h1><pre><code></code></pre><pre><code><code>                 +----------------+
                 |   Admin UI     |
                 +--------+-------+
                          |
                          v
                 +----------------+
                 | API Gateway    |
                 +--------+-------+
                          |
      ------------------------------------------------
      |              |               |               |
      v              v               v               v

+------------+ +-------------+ +-------------+ +--------------+
| Device Mgmt| | Alert Svc   | | Policy Svc  | | Analytics Svc|
+------------+ +-------------+ +-------------+ +--------------+

                          |
                          v

                +------------------+
                | Kafka / Pulsar   |
                +--------+---------+
                         |
     ---------------------------------------------------
     |                 |               |               |
     v                 v               v               v

+------------+ +--------------+ +-------------+ +--------------+
| Collectors | | Detection Svc| | ML Engine   | | Remediation  |
+------------+ +--------------+ +-------------+ +--------------+

                         |
                         v

                 +---------------+
                 | Routers       |
                 +---------------+</code></code></pre><div><hr></div><h1>5. Core Components</h1><h2>A. Telemetry Collectors</h2><p>Responsible for:</p><ul><li><p>SNMP polling<br></p></li><li><p>Streaming telemetry<br></p></li><li><p>Syslog ingestion<br></p></li><li><p>NetFlow/sFlow collection<br></p></li></ul><p>Protocols:</p><ul><li><p>SNMP<br></p></li><li><p>gRPC telemetry<br></p></li><li><p>NETCONF<br></p></li><li><p>SSH<br></p></li><li><p>Syslog<br></p></li></ul><div><hr></div><h2>B. Event Streaming Layer</h2><p>Use:</p><ul><li><p>Apache Kafka<br><br>or<br></p></li><li><p>Apache Pulsar<br></p></li></ul><p>Purpose:</p><ul><li><p>Buffer telemetry<br></p></li><li><p>Decouple services<br></p></li><li><p>Enable replay<br></p></li><li><p>Handle burst traffic<br></p></li></ul><p>Topics:</p><pre><code></code></pre><pre><code><code>telemetry.cpu
telemetry.memory
telemetry.interface
alerts
remediation.tasks</code></code></pre><div><hr></div><h2>C. Detection Engine</h2><p>Performs:</p><ul><li><p>Threshold detection<br></p></li><li><p>Pattern detection<br></p></li><li><p>Correlation<br></p></li><li><p>Stateful analysis<br></p></li></ul><p>Examples:</p><ul><li><p>CPU &gt; 90% for 5 mins<br></p></li><li><p>Packet loss &gt; 20%<br></p></li><li><p>Interface flapping &gt; 5 times/min<br></p></li></ul><p>Techniques:</p><ul><li><p>Rule engine<br></p></li><li><p>CEP (Complex Event Processing)<br></p></li></ul><div><hr></div><h2>D. ML Prediction Engine</h2><p>Predicts:</p><ul><li><p>Link failure probability<br></p></li><li><p>Hardware degradation<br></p></li><li><p>Congestion patterns<br></p></li></ul><p>Models:</p><ul><li><p>Time-series forecasting<br></p></li><li><p>Isolation Forest<br></p></li><li><p>LSTM<br></p></li><li><p>ARIMA<br></p></li></ul><div><hr></div><h2>E. Remediation Service</h2><p>Executes automated actions:</p><ul><li><p>Route failover<br></p></li><li><p>Interface reset<br></p></li><li><p>Restart BGP sessions<br></p></li><li><p>Traffic rerouting<br></p></li></ul><p>Must support:</p><ul><li><p>Rollback<br></p></li><li><p>Audit logs<br></p></li><li><p>Approval workflows<br></p></li></ul><div><hr></div><h2>F. Alerting Service</h2><p>Integrations:</p><ul><li><p>PagerDuty<br></p></li><li><p>Slack<br></p></li><li><p>Email/SMS systems<br></p></li></ul><p>Supports:</p><ul><li><p>Deduplication<br></p></li><li><p>Escalation<br></p></li><li><p>Suppression<br></p></li></ul><div><hr></div><h1>6. APIs</h1><h1>A. Register Router API</h1><h2>Request</h2><pre><code></code></pre><pre><code><code>POST /api/v1/routers</code></code></pre><pre><code></code></pre><pre><code><code>{
  "routerId": "RTR-1001",
  "hostname": "blr-edge-1",
  "ip": "10.0.0.5",
  "location": "Bangalore-DC",
  "vendor": "Cisco",
  "model": "ASR-9000"
}</code></code></pre><h2>Response</h2><pre><code></code></pre><pre><code><code>{
  "status": "REGISTERED",
  "routerId": "RTR-1001"
}</code></code></pre><div><hr></div><h1>B. Push Telemetry API</h1><pre><code></code></pre><pre><code><code>POST /api/v1/telemetry</code></code></pre><h2>Request</h2><pre><code></code></pre><pre><code><code>{
  "routerId": "RTR-1001",
  "timestamp": 1710001231,
  "metrics": {
    "cpu": 91,
    "memory": 72,
    "packetLoss": 15,
    "latency": 240
  }
}</code></code></pre><h2>Response</h2><pre><code></code></pre><pre><code><code>{
  "status": "INGESTED"
}</code></code></pre><div><hr></div><h1>C. Create Remediation Policy</h1><pre><code></code></pre><pre><code><code>POST /api/v1/policies</code></code></pre><h2>Request</h2><pre><code></code></pre><pre><code><code>{
  "policyName": "HighCPURecovery",
  "condition": "cpu &gt; 90 for 5m",
  "action": "restart_interface",
  "severity": "HIGH"
}</code></code></pre><h2>Response</h2><pre><code></code></pre><pre><code><code>{
  "policyId": "POL-101",
  "status": "ACTIVE"
}</code></code></pre><div><hr></div><h1>D. Get Active Alerts</h1><pre><code></code></pre><pre><code><code>GET /api/v1/alerts?severity=CRITICAL</code></code></pre><h2>Response</h2><pre><code></code></pre><pre><code><code>[
  {
    "alertId": "ALT-1001",
    "routerId": "RTR-1001",
    "message": "Packet loss exceeded threshold",
    "severity": "CRITICAL",
    "timestamp": 1710009999
  }
]</code></code></pre><div><hr></div><h1>E. Execute Manual Remediation</h1><pre><code></code></pre><pre><code><code>POST /api/v1/remediation/execute</code></code></pre><h2>Request</h2><pre><code></code></pre><pre><code><code>{
  "routerId": "RTR-1001",
  "action": "restart_bgp"
}</code></code></pre><h2>Response</h2><pre><code></code></pre><pre><code><code>{
  "executionId": "REM-1009",
  "status": "IN_PROGRESS"
}</code></code></pre><div><hr></div><h1>7. Database Design</h1><div><hr></div><h1>A. Router Metadata Table</h1><pre><code></code></pre><pre><code><code>CREATE TABLE routers (
    router_id VARCHAR(50) PRIMARY KEY,
    hostname VARCHAR(255),
    ip_address VARCHAR(50),
    vendor VARCHAR(50),
    model VARCHAR(50),
    location VARCHAR(255),
    status VARCHAR(20),
    created_at TIMESTAMP
);</code></code></pre><div><hr></div><h1>B. Telemetry Table (Time-Series DB)</h1><pre><code></code></pre><pre><code><code>CREATE TABLE telemetry_metrics (
    router_id VARCHAR(50),
    metric_name VARCHAR(50),
    metric_value DOUBLE,
    ts TIMESTAMP,
    PRIMARY KEY(router_id, ts, metric_name)
);</code></code></pre><p>Recommended DB:</p><ul><li><p>InfluxDB<br></p></li><li><p>OpenTSDB<br></p></li></ul><div><hr></div><h1>C. Alert Table</h1><pre><code></code></pre><pre><code><code>CREATE TABLE alerts (
    alert_id VARCHAR(50) PRIMARY KEY,
    router_id VARCHAR(50),
    severity VARCHAR(20),
    message TEXT,
    status VARCHAR(20),
    created_at TIMESTAMP
);</code></code></pre><div><hr></div><h1>D. Policy Table</h1><pre><code></code></pre><pre><code><code>CREATE TABLE remediation_policies (
    policy_id VARCHAR(50) PRIMARY KEY,
    policy_name VARCHAR(255),
    condition_expression TEXT,
    action VARCHAR(100),
    severity VARCHAR(20),
    enabled BOOLEAN
);</code></code></pre><div><hr></div><h1>E. Remediation Execution Table</h1><pre><code></code></pre><pre><code><code>CREATE TABLE remediation_execution (
    execution_id VARCHAR(50) PRIMARY KEY,
    router_id VARCHAR(50),
    action VARCHAR(100),
    status VARCHAR(50),
    started_at TIMESTAMP,
    completed_at TIMESTAMP,
    rollback_status VARCHAR(50)
);</code></code></pre><div><hr></div><h1>8. Storage Choices</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;7e32a657-9bc2-4e30-aaa7-0a7885a64fbd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Data Type         | Database             |
| ----------------- | -------------------- |
| Router Metadata   | PostgreSQL           |
| Telemetry Metrics | InfluxDB / Cassandra |
| Logs              | Elasticsearch        |
| Alerts            | PostgreSQL           |
| Event Streaming   | Kafka                |
| ML Features       | S3/HDFS              |
</code></pre></div><div><hr></div><h1>9. Microservices</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4322dce3-faa2-40ab-9a0e-939f39dffb83&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Service                     | Responsibility                |
| --------------------------- | ----------------------------- |
| API Gateway                 | Authentication, routing       |
| Device Service              | Router metadata management    |
| Telemetry Ingestion Service | Accept telemetry              |
| Detection Engine            | Fault detection               |
| Policy Engine               | Evaluate remediation policies |
| Remediation Service         | Execute preventive actions    |
| Alert Service               | Notifications                 |
| Analytics Service           | Dashboards and trends         |
| ML Prediction Service       | Predict future failures       |
</code></pre></div><div><hr></div><h1>10. Microservices Interaction Flow</h1><h2>Scenario:</h2><p>CPU spike detected on router.</p><pre><code></code></pre><pre><code><code>1. Router sends telemetry
2. Collector publishes to Kafka
3. Detection Engine consumes telemetry
4. Rule matched: CPU &gt; 90%
5. Alert generated
6. Policy Engine checks remediation rules
7. Remediation Service restarts interface
8. Result published back to Kafka
9. Alert Service sends PagerDuty alert
10. Analytics Service updates dashboard</code></code></pre><div><hr></div><h1>11. Sequence Flow Diagram</h1><pre><code></code></pre><pre><code><code>Router
   |
   | Telemetry
   v
Collector Service
   |
   | Publish Event
   v
Kafka
   |
   | Consume
   v
Detection Engine
   |
   | Fault Detected
   v
Policy Engine
   |
   | Execute Action
   v
Remediation Service
   |
   | SSH/NETCONF
   v
Router

Detection Engine
   |
   | Create Alert
   v
Alert Service
   |
   | Notify
   v
PagerDuty / Slack / Email</code></code></pre><div><hr></div><h1>12. Scaling Strategy</h1><h2>Horizontal Scaling</h2><ul><li><p>Multiple collectors<br></p></li><li><p>Partitioned Kafka topics<br></p></li><li><p>Stateless detection workers<br></p></li></ul><div><hr></div><h2>Kafka Partitioning</h2><p>Partition by:</p><pre><code></code></pre><pre><code><code>hash(routerId)</code></code></pre><p>Ensures:</p><ul><li><p>Ordering per router<br></p></li><li><p>Balanced processing<br></p></li></ul><div><hr></div><h2>Telemetry Optimization</h2><p>Use:</p><ul><li><p>Compression<br></p></li><li><p>Batch ingestion<br></p></li><li><p>Sampling<br></p></li><li><p>Aggregation windows<br></p></li></ul><div><hr></div><h1>13. Reliability &amp; Fault Tolerance</h1><h2>Retry Mechanisms</h2><ul><li><p>Exponential backoff<br></p></li><li><p>Dead-letter queues<br></p></li></ul><div><hr></div><h2>Exactly Once Processing</h2><p>Use:</p><ul><li><p>Kafka transactions<br></p></li><li><p>Idempotent consumers<br></p></li></ul><div><hr></div><h2>Multi-Region Deployment</h2><p>Deploy:</p><ul><li><p>Active-active clusters<br></p></li><li><p>Geo-replication<br></p></li></ul><div><hr></div><h1>14. Security Considerations</h1><ul><li><p>mTLS between routers and collectors<br></p></li><li><p>RBAC for remediation APIs<br></p></li><li><p>Encrypted telemetry<br></p></li><li><p>Audit logs for all actions<br></p></li><li><p>Secret management using:<br></p><ul><li><p>HashiCorp Vault<br></p></li></ul></li></ul><div><hr></div><h1>15. Bottlenecks &amp; Optimizations</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;892f76d3-e4fe-468e-8ab1-6fa214ec26aa&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Bottleneck            | Optimization        |
| --------------------- | ------------------- |
| High telemetry volume | Kafka batching      |
| Detection lag         | Stream processing   |
| Alert storms          | Alert deduplication |
| Expensive queries     | Pre-aggregation     |
| Large storage         | Tiered retention    |
</code></pre></div><div><hr></div><h1>16. Interview Deep Dive Questions</h1><ol><li><p>How will you detect interface flapping efficiently?<br></p></li><li><p>Why choose Kafka over RabbitMQ?<br></p></li><li><p>How would you avoid alert storms?<br></p></li><li><p>How will rollback work during failed remediation?<br></p></li><li><p>How do you guarantee ordering per router?<br></p></li><li><p>How would ML-based prediction integrate?<br></p></li><li><p>How would the system behave during Kafka outages?<br></p></li><li><p>How do you prevent false positives?<br></p></li><li><p>How would you support millions of routers?<br></p></li><li><p>How would you design multi-region failover?<br></p></li></ol><p></p>]]></content:encoded></item><item><title><![CDATA[Why Your Java Counter Prints Less Than 200000 , A Deep Dive into Race Conditions]]></title><description><![CDATA[Modern backend systems process millions of concurrent operations every second.]]></description><link>https://programmingappliedai.substack.com/p/why-your-java-counter-prints-less</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/why-your-java-counter-prints-less</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Tue, 12 May 2026 16:15:26 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Modern backend systems process millions of concurrent operations every second.<br>Yet, one of the simplest Java programs can expose one of the most important concepts in concurrent programming: <strong>Race Conditions</strong>.</p><p>Consider this code:</p><pre><code></code></pre><pre><code><code>class Counter {
    int count = 0;

    void increment() {
        count++;
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -&gt; {
            for (int i = 0; i &lt; 100000; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -&gt; {
            for (int i = 0; i &lt; 100000; i++) {
                counter.increment();
            }
        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println(counter.count);
    }
}</code></code></pre><p>At first glance, the answer should obviously be:</p><pre><code></code></pre><pre><code><code>200000</code></code></pre><p>Two threads.<br><br>Each increments <code>100000</code> times.</p><p>So why does the output often become:</p><pre><code></code></pre><pre><code><code>173421
189302
196774</code></code></pre><p>and almost never exactly <code>200000</code>?</p><p>Let&#8217;s break it down.</p><div><hr></div><h1>The Real Problem: <code>count++</code> Is NOT Atomic</h1><p>Most developers assume:</p><pre><code></code></pre><pre><code><code>count++;</code></code></pre><p>is a single operation.</p><p>It is not.</p><p>Under the hood, it becomes <strong>three separate CPU operations</strong>:</p><pre><code></code></pre><pre><code><code>1. Read count from memory
2. Increment locally
3. Write updated value back</code></code></pre><p>Equivalent pseudo-operations:</p><pre><code></code></pre><pre><code><code>temp = count;
temp = temp + 1;
count = temp;</code></code></pre><p>Now imagine two threads executing simultaneously.</p><div><hr></div><h1>The Race Condition</h1><p>Suppose:</p><pre><code></code></pre><pre><code><code>count = 5</code></code></pre><p>Now both threads execute <code>count++</code>.</p><div><hr></div><h2>Thread Interleaving</h2><p>StepThread 1Thread 2count1Read 552Read 553Increment to 654Increment to 655Write 666Write 66</p><p>Expected result:</p><pre><code></code></pre><pre><code><code>7</code></code></pre><p>Actual result:</p><pre><code></code></pre><pre><code><code>6</code></code></pre><p>One increment is lost.</p><p>This is called a:</p><h1>&#9888;&#65039; Lost Update Problem</h1><p>And because this happens thousands of times across both threads, the final result becomes unpredictable.</p><div><hr></div><h1>Why Does This Happen?</h1><p>Because:</p><ul><li><p>Threads share the same heap memory<br></p></li><li><p>CPU scheduling is nondeterministic<br></p></li><li><p>Context switching can occur anytime<br></p></li><li><p><code>count++</code> is not thread-safe<br></p></li></ul><p>This entire category of bugs falls under:</p><h1>&#9888;&#65039; Race Conditions</h1><p>A race condition occurs when:</p><blockquote><p>Multiple threads access and modify shared state concurrently without proper synchronization.</p></blockquote><div><hr></div><h1>How to Fix It</h1><p>There are multiple ways.</p><p>Each has different performance and scalability tradeoffs.</p><div><hr></div><h1>1. Using <code>synchronized</code></h1><pre><code></code></pre><pre><code><code>class Counter {
    int count = 0;

    synchronized void increment() {
        count++;
    }
}</code></code></pre><p>Now only one thread can execute <code>increment()</code> at a time.</p><div><hr></div><h2>How It Works</h2><p>Java uses an intrinsic monitor lock.</p><p>Before entering:</p><pre><code></code></pre><pre><code><code>increment()</code></code></pre><p>thread acquires the monitor.</p><p>Other threads wait.</p><div><hr></div><h2>Pros</h2><p>&#10004; Easy to understand<br><br>&#10004; Guarantees correctness<br><br>&#10004; Built into JVM</p><div><hr></div><h2>Cons</h2><p>&#10060; Blocking<br><br>&#10060; Context switching overhead<br><br>&#10060; Poor scalability under heavy contention</p><div><hr></div><h1>2. Using <code>ReentrantLock</code></h1><pre><code></code></pre><pre><code><code>import java.util.concurrent.locks.ReentrantLock;

class Counter {
    int count = 0;

    ReentrantLock lock = new ReentrantLock();

    void increment() {
        lock.lock();

        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}</code></code></pre><div><hr></div><h2>Why Use It?</h2><p>More flexible than <code>synchronized</code>.</p><p>Supports:</p><ul><li><p>Fair locking<br></p></li><li><p>Try lock<br></p></li><li><p>Interruptible lock acquisition<br></p></li><li><p>Timed waits<br></p></li></ul><div><hr></div><h2>Pros</h2><p>&#10004; More control<br><br>&#10004; Better advanced concurrency handling</p><div><hr></div><h2>Cons</h2><p>&#10060; Manual unlock required<br><br>&#10060; Still blocking</p><div><hr></div><h1>3. Using <code>AtomicInteger</code> (Best for Counters)</h1><pre><code></code></pre><pre><code><code>import java.util.concurrent.atomic.AtomicInteger;

class Counter {
    AtomicInteger count = new AtomicInteger();

    void increment() {
        count.incrementAndGet();
    }
}</code></code></pre><div><hr></div><h1>Why This Is Better</h1><p><code>AtomicInteger</code> uses:</p><h1>&#9889; Compare-And-Swap (CAS)</h1><p>instead of locking.</p><div><hr></div><h1>What CAS Does</h1><p>CPU instruction:</p><pre><code></code></pre><pre><code><code>if current_value == expected_value
    update
else
    retry</code></code></pre><p>No thread blocking.</p><p>No monitor locking.</p><p>Extremely efficient.</p><div><hr></div><h1>Internally</h1><pre><code></code></pre><pre><code><code>while(true) {
   int existing = value;
   int next = existing + 1;

   if(CAS(existing, next))
       break;
}</code></code></pre><div><hr></div><h1>Why Modern Systems Prefer Atomic Operations</h1><p>High-performance systems like:</p><ul><li><p>Kafka<br></p></li><li><p>Netty<br></p></li><li><p>Aerospike<br></p></li><li><p>Cassandra<br></p></li><li><p>Redis internals<br></p></li></ul><p>heavily rely on:</p><ul><li><p>Lock-free algorithms<br></p></li><li><p>CAS operations<br></p></li><li><p>Atomic primitives<br></p></li></ul><p>because locks become bottlenecks at scale.</p><div><hr></div><h1>Performance Comparison</h1><p>ApproachThread SafeBlockingScalablePlain int&#10060;&#10060;&#10060;synchronized&#9989;&#9989;MediumReentrantLock&#9989;&#9989;MediumAtomicInteger&#9989;&#10060;High</p><div><hr></div><h1>But AtomicInteger Is Not Always Enough</h1><p>For extremely high contention systems:</p><pre><code></code></pre><pre><code><code>100+ threads
millions of increments/sec</code></code></pre><p>even CAS retries become expensive.</p><p>That&#8217;s why Java introduced:</p><h1>&#9889; LongAdder</h1><p>Used internally in:</p><ul><li><p>ConcurrentHashMap<br></p></li><li><p>Metrics systems<br></p></li><li><p>High throughput counters<br></p></li></ul><p>It reduces contention using striped counters.</p><div><hr></div><h1>Real-World Backend Engineering Insight</h1><p>This tiny example explains why distributed systems are hard.</p><p>Now imagine:</p><ul><li><p>Millions of concurrent users<br></p></li><li><p>Multiple JVMs<br></p></li><li><p>Distributed databases<br></p></li><li><p>Replication<br></p></li><li><p>Network retries<br></p></li></ul><p>The exact same &#8220;lost update&#8221; problem appears everywhere:</p><ul><li><p>Inventory systems<br></p></li><li><p>Banking transactions<br></p></li><li><p>Payment systems<br></p></li><li><p>Distributed counters<br></p></li><li><p>Leaderboards<br></p></li></ul><p>Concurrency bugs scale from a single integer &#8594; to entire distributed architectures.</p><div><hr></div><h1>Final Takeaway</h1><p>The biggest lesson is:</p><blockquote><p>Concurrency problems are rarely visible in code syntax.</p></blockquote><p>The bug is hidden inside:</p><pre><code></code></pre><pre><code><code>count++;</code></code></pre><p>What looks like one operation is actually multiple CPU-level operations racing against each other.</p><p>Understanding this deeply is foundational for:</p><ul><li><p>Multithreading<br></p></li><li><p>JVM internals<br></p></li><li><p>High-performance backend engineering<br></p></li><li><p>Distributed systems design<br></p></li></ul><p>Because at scale:</p><blockquote><p>Correctness is harder than performance.</p></blockquote><p>#Java #Concurrency #Multithreading #BackendEngineering #DistributedSystems #JVM #SystemDesign</p>]]></content:encoded></item><item><title><![CDATA[HLD:Podcast Tracking Service(Asked in Confluent)]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/hldpodcast-tracking-serviceasked</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hldpodcast-tracking-serviceasked</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Fri, 01 May 2026 06:06:50 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><p></p><h1>1. Problem Framing</h1><p>Design a <strong>Podcast Tracking Service</strong> where users can:</p><ul><li><p>Follow podcasts</p></li><li><p>Track listening progress</p></li><li><p>Get updates on new episodes</p></li><li><p>Resume playback across devices</p></li></ul><div><hr></div><h1>&#9989; 2. Functional Requirements (FR)</h1><ol><li><p>User can <strong>search &amp; discover podcasts</strong></p></li><li><p>User can <strong>follow / unfollow podcasts</strong></p></li><li><p>User can <strong>view episodes of a podcast</strong></p></li><li><p>User can <strong>mark episode as played / in-progress</strong></p></li><li><p>Track <strong>listening progress (timestamp-based)</strong></p></li><li><p>Resume playback from last position</p></li><li><p>Notify users on <strong>new episode release</strong></p></li><li><p>Show <strong>user feed (new episodes from followed podcasts)</strong></p></li><li><p>Support <strong>multi-device sync</strong></p></li><li><p>Maintain <strong>listening history</strong></p></li></ol><div><hr></div><h1>&#9881;&#65039; 3. Non-Functional Requirements (NFR)</h1><ol><li><p><strong>High write throughput</strong> (progress updates are frequent)</p></li><li><p><strong>Low latency reads</strong> (resume playback must be instant)</p></li><li><p><strong>High availability</strong> (user data must not be lost)</p></li><li><p><strong>Scalability</strong> (millions of users, podcasts)</p></li><li><p><strong>Eventual consistency acceptable</strong> (for feeds/notifications)</p></li><li><p><strong>Durability of progress tracking</strong></p></li><li><p><strong>Idempotent APIs</strong> (progress updates retry-safe)</p></li></ol><div><hr></div><h1>&#129521; 4. Core Entities</h1><h3>Key Entities:</h3><ul><li><p><strong>User</strong></p></li><li><p><strong>Podcast</strong></p></li><li><p><strong>Episode</strong></p></li><li><p><strong>UserSubscription</strong></p></li><li><p><strong>ListeningProgress</strong></p></li><li><p><strong>ListeningHistory</strong></p></li></ul><div><hr></div><h1>&#128452;&#65039; 5. Database Design</h1><h3>&#128313; 1. User</h3><pre><code>user_id (PK)
name
email
created_at</code></pre><div><hr></div><h3>&#128313; 2. Podcast</h3><pre><code>podcast_id (PK)
title
description
publisher
category
created_at</code></pre><div><hr></div><h3>&#128313; 3. Episode</h3><pre><code>episode_id (PK)
podcast_id (FK)
title
duration
publish_time
audio_url</code></pre><div><hr></div><h3>&#128313; 4. UserSubscription</h3><pre><code>user_id (PK, FK)
podcast_id (PK, FK)
subscribed_at</code></pre><p>&#128073; Composite PK for fast lookup</p><div><hr></div><h3>&#128313; 5. ListeningProgress (HOT PATH)</h3><pre><code>user_id (PK)
episode_id (PK)
progress_seconds
last_updated
status (IN_PROGRESS / COMPLETED)</code></pre><p>&#128073; Stored in <strong>NoSQL (Cassandra/DynamoDB)</strong><br><br>Reason: high write frequency</p><div><hr></div><h3>&#128313; 6. ListeningHistory</h3><pre><code>user_id
episode_id
completed_at</code></pre><p>&#128073; Append-only &#8594; good for analytics</p><div><hr></div><h1>&#128451;&#65039; 6. Database Choices</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;132fb13b-7953-4b87-ab62-b1e8217e38ec&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Use Case               | DB                            |
| ---------------------- | ----------------------------- |
| User, Podcast metadata | MySQL / PostgreSQL            |
| Episodes               | MySQL (or Elastic for search) |
| Listening Progress     | Cassandra / DynamoDB          |
| Feed / Notifications   | Redis + Kafka                 |
| Search                 | Elasticsearch                 |
</code></pre></div><div><hr></div><h1>&#128268; 7. API Design</h1><h3>&#128313; 1. Follow Podcast</h3><pre><code>POST /users/{userId}/follow

Request:
{
  &#8220;podcastId&#8221;: &#8220;p123&#8221;
}</code></pre><div><hr></div><h3>&#128313; 2. Get User Subscriptions</h3><pre><code>GET /users/{userId}/subscriptions</code></pre><div><hr></div><h3>&#128313; 3. Get Episodes of Podcast</h3><pre><code>GET /podcasts/{podcastId}/episodes</code></pre><div><hr></div><h3>&#128313; 4. Update Listening Progress (CRITICAL API)</h3><pre><code>POST /progress

Request:
{
  &#8220;userId&#8221;: &#8220;u1&#8221;,
  &#8220;episodeId&#8221;: &#8220;e1&#8221;,
  &#8220;progressSeconds&#8221;: 120
}</code></pre><p>&#128073; Must be:</p><ul><li><p>Idempotent<br></p></li><li><p>High throughput<br></p></li></ul><div><hr></div><h3>&#128313; 5. Get Resume Playback</h3><pre><code>GET /progress?userId=u1&amp;episodeId=e1</code></pre><div><hr></div><h3>&#128313; 6. Get User Feed</h3><pre><code>GET /users/{userId}/feed</code></pre><div><hr></div><h1>&#129513; 8. High-Level Architecture</h1><pre><code>                &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                &#9474; API Gateway  &#9474;
                &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                       &#9474;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9532;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474;              &#9474;              &#9474;
 User Service   Podcast Service   Progress Service
        &#9474;              &#9474;              &#9474;
        &#9474;              &#9474;              &#9474;
   MySQL DB       MySQL DB       Cassandra
                                      &#9474;
                                  Kafka
                                      &#9474;
                              Notification Service
                                      &#9474;
                                   Redis</code></pre><div><hr></div><h1>&#128260; 9. Microservices Breakdown</h1><h3>&#128313; 1. User Service</h3><ul><li><p>Manage users<br></p></li><li><p>Auth (optional)<br></p></li></ul><div><hr></div><h3>&#128313; 2. Podcast Service</h3><ul><li><p>Podcast metadata<br></p></li><li><p>Episode management<br></p></li></ul><div><hr></div><h3>&#128313; 3. Subscription Service</h3><ul><li><p>Follow/unfollow<br></p></li><li><p>Stores mapping<br></p></li></ul><div><hr></div><h3>&#128313; 4. Progress Service (HOT SERVICE)</h3><ul><li><p>Handles frequent writes<br></p></li><li><p>Writes to Cassandra<br></p></li><li><p>Publishes events to Kafka<br></p></li></ul><div><hr></div><h3>&#128313; 5. Feed Service</h3><ul><li><p>Aggregates new episodes<br></p></li><li><p>Pull vs Push model<br></p></li></ul><div><hr></div><h3>&#128313; 6. Notification Service</h3><ul><li><p>Consumes Kafka events<br></p></li><li><p>Sends push/email notifications<br></p></li></ul><div><hr></div><h1>&#128257; 10. Flow: Update Listening Progress</h1><pre><code>Client &#8594; API Gateway &#8594; Progress Service
        &#8594; Write to Cassandra
        &#8594; Publish event to Kafka
                &#8595;
        Notification / Analytics consumers</code></pre><div><hr></div><h1>&#128257; 11. Flow: New Episode Release</h1><pre><code>Podcast Service
    &#8594; Publish &#8220;New Episode Event&#8221; to Kafka
            &#8595;
    Feed Service
        &#8594; Fan-out to followers (push model)
            &#8595;
    Notification Service</code></pre><div><hr></div><h1>&#9878;&#65039; 12. Key Design Decisions</h1><h3>&#128313; Why Cassandra for Progress?</h3><ul><li><p>High write throughput<br></p></li><li><p>Partition key = user_id &#8594; efficient<br></p></li></ul><div><hr></div><h3>&#128313; Push vs Pull Feed</h3><p>ApproachTradeoffPullSimple but slowPushFast reads, heavy writes</p><p>&#128073; Use <strong>hybrid model</strong></p><div><hr></div><h3>&#128313; Idempotency for Progress API</h3><ul><li><p>Use <code>(user_id, episode_id)</code> as key<br></p></li><li><p>Always overwrite latest progress<br></p></li></ul><div><hr></div><h1>&#128279; 13. Decoupling Strategy (Important for Interview)</h1><ol><li><p>Use <strong>Kafka for async communication</strong><br></p></li><li><p>Services don&#8217;t call each other directly<br></p></li><li><p>Event-driven architecture:<br></p><ul><li><p>Progress updates &#8594; analytics<br></p></li><li><p>New episodes &#8594; feed generation<br></p></li></ul></li></ol><div><hr></div><h1>&#128640; 14. Scaling Considerations</h1><ul><li><p>Partition Cassandra by <code>user_id</code><br></p></li><li><p>Cache feed in Redis<br></p></li><li><p>Use CDN for audio files<br></p></li><li><p>Batch updates for analytics<br></p></li></ul><div><hr></div><h1>&#129504; 15. Follow-Up Questions (They Might Ask)</h1><h3>&#10067; How to handle rewind/skip edge cases?</h3><p>&#8594; Always store latest timestamp</p><h3>&#10067; What if user listens offline?</h3><p>&#8594; Sync on reconnect (client-side buffering)</p><h3>&#10067; How to avoid write overload?</h3><p>&#8594; Throttle updates (every 5&#8211;10 sec instead of every second)</p><h3>&#10067; Multi-device consistency?</h3><p>&#8594; Last write wins (timestamp-based conflict resolution)</p><div><hr></div><p></p><ul><li><p>Deep dive on <strong>Kafka topic design &amp; partitioning</strong><br></p></li><li><p><strong>Cassandra schema optimization (LSM trees, compaction)</strong><br></p></li><li><p>Or <strong>Feed system design (fan-out on write vs read)</strong></p><p><br></p></li></ul><h1>1. Kafka Design (Topics, Partitions, Throughput)</h1><p>You&#8217;re using Kafka as the backbone for decoupling, so design it intentionally&#8212;not vaguely.</p><div><hr></div><h2>&#129525; Key Events</h2><h3>1. Progress Updates</h3><pre><code>topic: listening-progress-events</code></pre><p>Event:</p><pre><code>{
  userId,
  episodeId,
  progressSeconds,
  timestamp
}</code></pre><div><hr></div><h3>2. New Episode Release</h3><pre><code>topic: new-episode-events</code></pre><p>Event:</p><pre><code>{
  podcastId,
  episodeId,
  publishTime
}</code></pre><div><hr></div><h2>&#9881;&#65039; Partitioning Strategy</h2><h3>&#128313; Progress Events</h3><p>&#128073; Partition by <code>userId</code></p><p><strong>Why?</strong></p><ul><li><p>Guarantees ordering per user<br></p></li><li><p>Avoids race conditions in progress updates<br></p></li></ul><div><hr></div><h3>&#128313; New Episode Events</h3><p>&#128073; Partition by <code>podcastId</code></p><p><strong>Why?</strong></p><ul><li><p>All followers of a podcast handled consistently<br></p></li><li><p>Enables batching for fan-out<br></p></li></ul><div><hr></div><h2>&#128202; Throughput Estimation (Back-of-envelope)</h2><p>Let&#8217;s assume:</p><ul><li><p>10M daily active users<br></p></li><li><p>Each sends progress every 10 sec<br></p></li></ul><p>&#128073; Writes/sec:</p><pre><code>10M * (1 update / 10 sec) = 1M events/sec</code></pre><p>&#128073; You <strong>must</strong>:</p><ul><li><p>Use multiple partitions (1000+)<br></p></li><li><p>Use batching producers<br></p></li><li><p>Enable compression<br></p></li></ul><div><hr></div><h2>&#9888;&#65039; Common Mistake</h2><p>Don&#8217;t do:</p><ul><li><p>One partition &#8594; bottleneck<br></p></li><li><p>Random partition &#8594; breaks ordering<br></p></li></ul><div><hr></div><h1>&#129521; 2. Cassandra Schema Deep Dive</h1><p>This is where most answers stay shallow&#8212;you shouldn&#8217;t.</p><div><hr></div><h2>&#128313; Table: Listening Progress</h2><pre><code>PRIMARY KEY ((user_id), episode_id)</code></pre><p>&#128073; Partition key: <code>user_id</code><br><br>&#128073; Clustering key: <code>episode_id</code></p><div><hr></div><h2>&#10071; Problem</h2><p>What if a user listens to <strong>1000+ episodes</strong>?</p><p>&#8594; Partition becomes large</p><div><hr></div><h2>&#9989; Better Design</h2><h3>Option 1: Bucketing</h3><pre><code>PRIMARY KEY ((user_id, bucket), episode_id)</code></pre><p>Where:</p><pre><code>bucket = hash(episode_id) % N</code></pre><p>&#128073; Prevents hot partitions</p><div><hr></div><h3>Option 2: Time-based Bucketing (better for history)</h3><pre><code>PRIMARY KEY ((user_id, month), episode_id)</code></pre><div><hr></div><h2>&#128313; Write Pattern</h2><ul><li><p>Always <strong>upsert</strong><br></p></li><li><p>Last write wins<br></p></li></ul><div><hr></div><h2>&#128313; Read Pattern</h2><ul><li><p>Fetch by <code>(user_id, episode_id)</code> &#8594; fast O(1)<br></p></li></ul><div><hr></div><h2>&#9888;&#65039; Compaction Strategy</h2><p>Use:</p><ul><li><p><strong>Leveled Compaction</strong> &#8594; for read-heavy<br></p></li><li><p><strong>Size-Tiered</strong> &#8594; for write-heavy (better here)<br></p></li></ul><div><hr></div><h1>&#9889; 3. Feed System Design (THE differentiator)</h1><p>This is where interviewers test depth.</p><div><hr></div><h2>&#129513; Problem</h2><p>User follows 100 podcasts.<br><br>Each podcast releases episodes.</p><p>&#128073; How do you build the <strong>user feed</strong>?</p><div><hr></div><h1>&#127386; Approach 1: Fan-out on Read</h1><h3>Flow:</h3><pre><code>User opens app &#8594;
Fetch all followed podcasts &#8594;
Fetch latest episodes &#8594;
Merge + sort</code></pre><div><hr></div><h3>&#10060; Problem:</h3><ul><li><p>Slow<br></p></li><li><p>High read amplification<br></p></li></ul><div><hr></div><h1>&#127386; Approach 2: Fan-out on Write</h1><h3>Flow:</h3><pre><code>New Episode &#8594;
Push to all followers&#8217; feeds</code></pre><div><hr></div><h3>&#10060; Problem:</h3><ul><li><p>If podcast has 10M followers &#8594; explosion<br></p></li></ul><div><hr></div><h1>&#9989; Hybrid Approach (Best Answer)</h1><h3>Strategy:</h3><ul><li><p>Small podcasts &#8594; fan-out on write<br></p></li><li><p>Large podcasts &#8594; fan-out on read<br></p></li></ul><div><hr></div><h2>&#128313; Feed Table (Redis / Cassandra)</h2><pre><code>user_id &#8594; list of episode_ids (sorted by time)</code></pre><div><hr></div><h2>&#128260; Flow: New Episode</h2><pre><code>Podcast Service
    &#8594; Kafka (new-episode-events)
        &#8595;
Feed Service
    &#8594; Fetch followers
    &#8594; If small &#8594; push to feed
    &#8594; If large &#8594; mark for pull</code></pre><div><hr></div><h2>&#9889; Optimization</h2><ul><li><p>Use <strong>Redis Sorted Sets</strong><br></p></li><li><p>Score = timestamp<br></p></li></ul><div><hr></div><h1>&#128257; 4. End-to-End Flow (Putting It All Together)</h1><div><hr></div><h2>&#127911; Flow: User Listening</h2><pre><code>Client
 &#8594; API Gateway
 &#8594; Progress Service
 &#8594; Cassandra (write)
 &#8594; Kafka (event)

Kafka Consumers:
 &#8594; Analytics Service
 &#8594; Recommendation Service</code></pre><div><hr></div><h2>&#127381; Flow: New Episode</h2><pre><code>Podcast Service
 &#8594; Kafka

Feed Service
 &#8594; Fan-out (hybrid)

Notification Service
 &#8594; Push alerts</code></pre><div><hr></div><h1>&#128279; 5. Decoupling Strategy (Strong Signal)</h1><div><hr></div><h2>&#10060; Bad Design</h2><pre><code>Progress Service &#8594; directly calls Feed Service</code></pre><p>&#128073; Tight coupling</p><div><hr></div><h2>&#9989; Good Design</h2><pre><code>Progress Service &#8594; Kafka &#8594; Consumers</code></pre><p>&#128073; Loose coupling<br><br>&#128073; Scalable<br><br>&#128073; Replayable events</p><div><hr></div><h1>&#129504; 6. Advanced Follow-ups (Be Ready)</h1><div><hr></div><h2>&#10067; How do you handle duplicate Kafka events?</h2><p>&#128073; Use:</p><ul><li><p>Idempotent consumers<br></p></li><li><p>Dedup key = <code>(userId, episodeId, timestamp)</code><br></p></li></ul><div><hr></div><h2>&#10067; How do you handle out-of-order updates?</h2><p>&#128073; Use:</p><pre><code>only update if incoming.timestamp &gt; existing.timestamp</code></pre><div><hr></div><h2>&#10067; How do you reduce progress write load?</h2><p>&#128073; Client optimization:</p><ul><li><p>Send updates every 10 sec (not every second)<br></p></li><li><p>Send only if progress changed significantly<br></p></li></ul><div><hr></div><h2>&#10067; How to scale Kafka consumers?</h2><p>&#128073; Increase:</p><ul><li><p>Consumer groups<br></p></li><li><p>Partitions<br></p></li></ul><div><hr></div><h1>&#129504; Final Interview Tip</h1><p>When you explain this, don&#8217;t just describe components&#8212;<strong>justify every decision</strong>:</p><ul><li><p>&#8220;I chose Cassandra because write-heavy workload&#8221;<br></p></li><li><p>&#8220;Kafka ensures decoupling and replayability&#8221;<br></p></li><li><p>&#8220;Hybrid fan-out avoids celebrity problem&#8221;<br></p></li></ul><div><hr></div><p></p>]]></content:encoded></item><item><title><![CDATA[LLD: Implement Unit tail functionality(asked in Confluent)]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/lld-implement-unit-tail-functionalityasked</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/lld-implement-unit-tail-functionalityasked</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Fri, 01 May 2026 05:51:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><h3>Requirements</h3><ul><li><p>Read <strong>last N lines</strong></p></li><li><p>Should work for <strong>large files (GBs)</strong> &#8594; cannot load entire file</p></li><li><p>Efficient (O(file_size) worst case, but optimized by reverse reading)</p></li><li><p>Handle edge cases:</p><ul><li><p>File smaller than N lines</p></li><li><p>Very long lines</p></li><li><p>Different line endings</p></li></ul></li></ul><div><hr></div><h1>&#127959;&#65039; LLD Design</h1><h2>1. Core Components</h2><h3><code>TailService</code></h3><ul><li><p>Main service to fetch last N lines</p></li></ul><h3><code>FileReaderStrategy</code></h3><ul><li><p>Strategy pattern for reading:</p><ul><li><p>ForwardReader (simple, small files)</p></li><li><p>ReverseReader (optimized for large files)</p></li></ul></li></ul><h3><code>LineBuffer</code></h3><ul><li><p>Maintains last N lines using deque</p></li></ul><div><hr></div><h2>2. Approach Options</h2><h3>&#10060; Naive Approach</h3><ul><li><p>Read entire file &#8594; keep last N lines</p></li><li><p>Not scalable</p></li></ul><h3>&#9989; Optimal Approach (Reverse Read)</h3><ul><li><p>Use <code>RandomAccessFile</code></p></li><li><p>Start from <strong>end of file</strong></p></li><li><p>Move backwards byte by byte</p></li><li><p>Count <code>\n</code></p></li><li><p>Stop after N lines</p></li></ul><div><hr></div><h1>&#9881;&#65039; Java Implementation (Efficient)</h1><pre><code>import java.io.*;
import java.util.*;

public class TailService {

    public List&lt;String&gt; tail(String filePath, int n) throws IOException {
        if (n &lt;= 0) return Collections.emptyList();

        RandomAccessFile file = new RandomAccessFile(filePath, &#8220;r&#8221;);
        long fileLength = file.length();

        List&lt;String&gt; result = new LinkedList&lt;&gt;();
        StringBuilder lineBuilder = new StringBuilder();

        int lineCount = 0;
        long pointer = fileLength - 1;

        while (pointer &gt;= 0 &amp;&amp; lineCount &lt; n) {
            file.seek(pointer);
            char c = (char) file.read();

            if (c == &#8216;\n&#8217;) {
                if (lineBuilder.length() &gt; 0) {
                    result.add(0, lineBuilder.reverse().toString());
                    lineBuilder.setLength(0);
                    lineCount++;
                }
            } else {
                lineBuilder.append(c);
            }

            pointer--;
        }

        // Add last line if file doesn&#8217;t end with newline
        if (lineBuilder.length() &gt; 0 &amp;&amp; lineCount &lt; n) {
            result.add(0, lineBuilder.reverse().toString());
        }

        file.close();
        return result;
    }

    public static void main(String[] args) throws IOException {
        TailService service = new TailService();
        List&lt;String&gt; lines = service.tail(&#8221;test.txt&#8221;, 10);

        for (String line : lines) {
            System.out.println(line);
        }
    }
}</code></pre><div><hr></div><h1>&#128269; Complexity</h1><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;e6834f51-c7ce-4156-947a-ed170dde8b67&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Aspect | Complexity              |
| ------ | ----------------------- |
| Time   | O(file_size) worst case |
| Space  | O(N * avg_line_length)  |
</code></pre></div><div><hr></div><h1>&#9889; Improvements (Production Level)</h1><h2>1. Use Buffered Block Reads</h2><p>Instead of reading char-by-char:</p><ul><li><p>Read chunks (e.g., 4KB)<br></p></li><li><p>Traverse buffer backwards<br></p></li></ul><h2>2. Handle Encoding</h2><ul><li><p>Use <code>CharsetDecoder</code> for UTF-8 safety<br></p></li></ul><h2>3. Support Streams (like <code>tail -f</code>)</h2><ul><li><p>Add file watcher (<code>WatchService</code>)<br></p></li><li><p>Continuously read appended lines<br></p></li></ul><h2>4. Memory Optimization</h2><ul><li><p>Use <code>ArrayDeque</code> instead of LinkedList<br></p></li></ul><div><hr></div><h1>&#129521; Cleaner LLD Version</h1><pre><code>interface TailReader {
    List&lt;String&gt; readLastNLines(String filePath, int n) throws IOException;
}</code></pre><h3>Reverse Reader</h3><pre><code>class ReverseTailReader implements TailReader {
    @Override
    public List&lt;String&gt; readLastNLines(String filePath, int n) throws IOException {
        return new TailService().tail(filePath, n);
    }
}</code></pre><h3>Service Layer</h3><pre><code>class TailApplication {
    private final TailReader reader;

    public TailApplication(TailReader reader) {
        this.reader = reader;
    }

    public void execute(String filePath, int n) throws IOException {
        List&lt;String&gt; lines = reader.readLastNLines(filePath, n);
        lines.forEach(System.out::println);
    }
}</code></pre><div><hr></div><h1>&#128161; Follow-ups (Interview Ready)</h1><p>You can extend this design into:</p><h3>1. <code>tail -f</code> (Real-time streaming)</h3><ul><li><p>Use <code>WatchService</code><br></p></li><li><p>Poll file growth<br></p></li><li><p>Maintain pointer<br></p></li></ul><h3>2. Distributed Logs</h3><ul><li><p>Read from S3 / HDFS<br></p></li><li><p>Use range queries<br></p></li></ul><h3>3. API Service</h3><pre><code>GET /tail?file=abc.log&amp;lines=50</code></pre><h3>4. Large-scale Observability System</h3><ul><li><p>Combine with Kafka + log ingestion<br></p></li><li><p>Real-time tail via WebSockets</p><p><br></p></li></ul><div><hr></div><p><a href="https://github.com/abcmishra/TailServiceInUnix">Unix Functionality Github Link</a><br></p>]]></content:encoded></item><item><title><![CDATA[HLD: Design Temporary Email Service]]></title><description><![CDATA[Problem Statement (Refined)]]></description><link>https://programmingappliedai.substack.com/p/hld-design-temporary-email-service</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-temporary-email-service</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Fri, 01 May 2026 05:40:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Problem Statement (Refined)</h1><p>Design a <strong>Temporary Email Service</strong> that allows users to:</p><ul><li><p>Generate disposable email addresses</p></li><li><p>Receive emails in a sandboxed inbox</p></li><li><p>Auto-expire emails and addresses after a TTL</p></li><li><p>Avoid spam/abuse</p></li><li><p>Scale to millions of emails per day</p></li></ul><div><hr></div><h1>&#9989; Functional Requirements (FR)</h1><ol><li><p>Users can <strong>generate temporary email addresses</strong></p></li><li><p>System should <strong>receive emails</strong> sent to these addresses</p></li><li><p>Users can <strong>view emails via UI/API</strong></p></li><li><p>Emails and addresses should <strong>expire automatically (TTL-based)</strong></p></li><li><p>Support <strong>multiple emails per temp address</strong></p></li><li><p>Provide <strong>meaningful / human-readable email IDs (not random hashes)</strong></p></li></ol><div><hr></div><h1>&#9881;&#65039; Non-Functional Requirements (NFR)</h1><ol><li><p><strong>High throughput</strong> (millions of incoming emails/day)</p></li><li><p><strong>Low latency</strong> for inbox retrieval (&lt;200ms)</p></li><li><p><strong>Highly scalable</strong> (horizontal scaling)</p></li><li><p><strong>Fault tolerant</strong> (no email loss)</p></li><li><p><strong>Secure sandboxing</strong> (no malware execution)</p></li><li><p><strong>Abuse prevention</strong> (rate limiting, spam filtering)</p></li></ol><div><hr></div><h1>&#129513; Core Design Challenges</h1><h3>1. Email Address Generation (Important &#128293;)</h3><blockquote><p>Cannot just be hashes &#8594; must be meaningful</p></blockquote><h3>Approach:</h3><p>Use structured format:</p><pre><code>&lt;word&gt;-&lt;word&gt;-&lt;random&gt;@tempmail.com</code></pre><p>Examples:</p><ul><li><p><code>blue-tiger-92@tempmail.com</code><br></p></li><li><p><code>swift-lake-431@tempmail.com</code><br></p></li></ul><h3>Why this works:</h3><ul><li><p>Human-readable<br></p></li><li><p>Easier debugging<br></p></li><li><p>Still unique with suffix<br></p></li></ul><h3>Backend Strategy:</h3><ul><li><p>Dictionary-based generator + counter/random suffix<br></p></li><li><p>Maintain <strong>uniqueness via Redis / DB constraint</strong><br></p></li></ul><div><hr></div><h1>&#127959;&#65039; High-Level Architecture</h1><pre><code>                +-------------------+
                |   DNS (MX Record) |
                +--------+----------+
                         |
                         v
                +-------------------+
                | Email Receiving   |
                | Server (SMTP)     |
                +--------+----------+
                         |
                         v
                +-------------------+
                | Email Parser      |
                +--------+----------+
                         |
          +--------------+--------------+
          |                             |
          v                             v
+-------------------+        +----------------------+
| Spam Filter       |        | Attachment Scanner   |
+--------+----------+        +----------+-----------+
         |                              |
         +--------------+---------------+
                        v
                +-------------------+
                | Message Queue     | (Kafka)
                +--------+----------+
                         |
                         v
                +-------------------+
                | Email Storage     |
                +--------+----------+
                         |
         +---------------+---------------+
         |                               |
         v                               v
+-------------------+        +-------------------+
| Metadata DB       |        | Blob Storage      |
| (Cassandra)       |        | (S3 / GCS)        |
+-------------------+        +-------------------+

                +-------------------+
                | Inbox API Service |
                +--------+----------+
                         |
                         v
                +-------------------+
                | Frontend UI       |
                +-------------------+</code></pre><div><hr></div><h1>&#128260; Key Flow</h1><h3>1. Email Creation</h3><ul><li><p>User requests &#8594; Service generates email ID<br></p></li><li><p>Store in DB with TTL<br></p></li></ul><div><hr></div><h3>2. Email Receiving Flow</h3><ol><li><p>SMTP server receives email<br></p></li><li><p>Parses:<br></p><ul><li><p>To address<br></p></li><li><p>Subject<br></p></li><li><p>Body<br></p></li></ul></li><li><p>Push to Kafka<br></p></li><li><p>Consumers:<br></p><ul><li><p>Store metadata &#8594; Cassandra<br></p></li><li><p>Store attachments &#8594; Blob store<br></p></li></ul></li></ol><div><hr></div><h3>3. Inbox Fetch</h3><ul><li><p>Query by email address<br></p></li><li><p>Fetch recent messages (sorted by timestamp)<br></p></li></ul><div><hr></div><h1>&#129521; Data Modeling</h1><h3>Email Address Table</h3><pre><code>email_id (PK)
created_at
expires_at
status (active/expired)</code></pre><div><hr></div><h3>Email Metadata Table (Cassandra)</h3><pre><code>partition_key: email_id
clustering_key: timestamp

Fields:
- message_id
- subject
- sender
- preview
- blob_url
- created_at</code></pre><div><hr></div><h1>&#9203; TTL Strategy</h1><ul><li><p>Use <strong>DB TTL (Cassandra TTL)</strong><br></p></li><li><p>Also maintain <strong>background cleanup job</strong><br></p></li></ul><div><hr></div><h1>&#128640; Scaling Deep Dive</h1><h2>1. Email Ingestion Scaling</h2><ul><li><p>Multiple SMTP servers behind load balancer<br></p></li><li><p>Partition by domain or hash(email)<br></p></li></ul><div><hr></div><h2>2. Kafka Partitioning</h2><ul><li><p>Partition key = email_id<br></p></li><li><p>Ensures ordering per inbox<br></p></li></ul><div><hr></div><h2>3. Storage Scaling</h2><ul><li><p>Cassandra &#8594; write-heavy optimized<br></p></li><li><p>Blob store &#8594; scalable for attachments<br></p></li></ul><div><hr></div><h2>4. Read Scaling</h2><ul><li><p>Cache inbox in Redis<br></p></li><li><p>Recent emails only<br></p></li></ul><div><hr></div><h1>&#128737;&#65039; Security &amp; Sandboxing</h1><h3>Must handle:</h3><ul><li><p>Malicious links<br></p></li><li><p>Attachments<br></p></li><li><p>Scripts<br></p></li></ul><h3>Approach:</h3><ul><li><p>Strip scripts from HTML<br></p></li><li><p>Convert to safe format<br></p></li><li><p>Virus scan attachments<br></p></li><li><p>Disable external image loading<br></p></li></ul><div><hr></div><h1>&#128683; Abuse Prevention</h1><ul><li><p>Rate limit email creation per IP<br></p></li><li><p>Blocklist domains<br></p></li><li><p>CAPTCHA<br></p></li><li><p>Detect bot patterns<br></p></li></ul><div><hr></div><h1>&#128161; Out-of-the-Box Ideas (Strong Interview Signal)</h1><h3>1. Auto Forwarding Rules</h3><ul><li><p>Forward temp email &#8594; real inbox<br></p></li></ul><div><hr></div><h3>2. Disposable API Keys</h3><ul><li><p>Use temp emails in automated testing<br></p></li></ul><div><hr></div><h3>3. Session-based Emails</h3><ul><li><p>Email tied to browser session<br></p></li><li><p>No login needed<br></p></li></ul><div><hr></div><h3>4. Smart Expiry</h3><ul><li><p>Extend TTL if actively used<br></p></li></ul><div><hr></div><h3>5. Email Categorization</h3><ul><li><p>ML model for:<br></p><ul><li><p>Spam<br></p></li><li><p>OTP<br></p></li><li><p>Promotions<br></p></li></ul></li></ul><div><hr></div><h3>6. Domain Pooling</h3><ul><li><p>Multiple domains:</p></li></ul><pre><code>@maildrop.cc
@tempmail.dev</code></pre><ul><li><p>Avoid blacklisting<br></p></li></ul><div><hr></div><h1>&#128293; Bottlenecks &amp; Tradeoffs</h1><p>ProblemSolutionHot email IDsShard by hashLarge attachmentsOffload to blobHigh read trafficRedis cacheSpam overloadPre-filter before Kafka</p><div><hr></div><h1>&#129514; APIs</h1><h3>Create Email</h3><pre><code>POST /email
Response:
{
  &#8220;email&#8221;: &#8220;blue-tiger-92@tempmail.com&#8221;,
  &#8220;expires_at&#8221;: &#8220;...&#8221;
}</code></pre><div><hr></div><h3>Get Inbox</h3><pre><code>GET /emails/{email_id}</code></pre><div><hr></div><h3>Get Email Detail</h3><pre><code>GET /emails/{email_id}/{message_id}</code></pre><div><hr></div><h1>&#129504; Interview Tips</h1><ul><li><p>Start with <strong>email infra (SMTP)</strong> &#8594; shows depth<br></p></li><li><p>Emphasize <strong>Kafka for decoupling</strong><br></p></li><li><p>Push on:<br></p><ul><li><p><strong>TTL strategy</strong><br></p></li><li><p><strong>Abuse prevention</strong><br></p></li><li><p><strong>Scaling ingestion vs reads</strong><br></p></li></ul></li></ul><div><hr></div><p><br></p>]]></content:encoded></item><item><title><![CDATA[HLD: Design DB migration platform for a company like TicketMaster transitioning to a nosql based datastore.(Asked in Mongo DB interview)]]></title><description><![CDATA[If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.]]></description><link>https://programmingappliedai.substack.com/p/hld-design-db-migration-platform</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/hld-design-db-migration-platform</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Fri, 10 Apr 2026 16:45:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>If you&#8217;re looking for paid 1:1 mentorship with a strong focus on LLD (core emphasis on Multithreading), HLD, DSA, and system design research papers, feel free to reach out.</strong></h3><p>&#128233; <strong>Contact:</strong> programmingappliedai@gmail.com</p><p>FR</p><ul><li><p>Support bulk migration of historical data from RDBMS to NoSQL</p></li><li><p>Capture and replicate real-time data changes (CDC) from source to target</p></li><li><p>Transform relational schema into NoSQL-compatible data models</p></li><li><p>Enable dual writes to both databases during migration phase</p></li><li><p>Ensure seamless incremental sync between bulk load and live updates</p></li><li><p>Provide data validation mechanisms (counts, checksums, record-level diff)</p></li><li><p>Support controlled traffic cutover from old DB to new datastore</p></li><li><p>Allow rollback to source database in case of failures</p></li><li><p>Handle write conflicts and ensure consistency during dual-write phase</p></li><li><p>Provide monitoring, alerting, and operational controls (pause/resume/retry)</p></li></ul><p><strong>NFR</strong></p><ul><li><p><strong>High Availability</strong> &#8211; Migration should not cause downtime; ticket booking and browsing must remain continuously available</p></li><li><p><strong>Strong Consistency (Critical Flows)</strong> &#8211; Ensure strict consistency for operations like seat booking to prevent double bookings</p></li><li><p><strong>Scalability</strong> &#8211; System should handle large-scale data (TB&#8211;PB) and high throughput during peak traffic events</p></li><li><p><strong>Fault Tolerance</strong> &#8211; System should recover from failures using retries, idempotent operations, and checkpointing</p></li><li><p><strong>Low Latency Impact</strong> &#8211; Migration (especially dual writes and CDC) should not significantly increase application latency</p></li><li><p><strong>Observability</strong> &#8211; Provide detailed metrics, logging, and alerting for migration progress, lag, errors, and system health</p></li></ul><p><strong>API&#8217;s</strong></p><h2><strong>1. Start Bulk Migration</strong></h2><p><strong>POST</strong> <code>/migration/start</code></p><p><strong>Request:</strong></p><pre><code>{
  &#8220;migrationId&#8221;: &#8220;mig_123&#8221;,
  &#8220;sourceDB&#8221;: &#8220;mysql_cluster_A&#8221;,
  &#8220;targetDB&#8221;: &#8220;cassandra_cluster_B&#8221;,
  &#8220;tables&#8221;: [&#8221;events&#8221;, &#8220;tickets&#8221;, &#8220;bookings&#8221;],
  &#8220;batchSize&#8221;: 10000
}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;STARTED&#8221;,
  &#8220;migrationId&#8221;: &#8220;mig_123&#8221;
}</code></pre><div><hr></div><h2><strong>2. Get Migration Status</strong></h2><p><strong>GET</strong> <code>/migration/{migrationId}/status</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;migrationId&#8221;: &#8220;mig_123&#8221;,
  &#8220;status&#8221;: &#8220;IN_PROGRESS&#8221;,
  &#8220;progress&#8221;: &#8220;65%&#8221;,
  &#8220;lagInMs&#8221;: 1200,
  &#8220;errors&#8221;: 10
}</code></pre><div><hr></div><h2><strong>3. Pause Migration</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/pause</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;PAUSED&#8221;
}</code></pre><div><hr></div><h2><strong>4. Resume Migration</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/resume</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;RESUMED&#8221;
}</code></pre><div><hr></div><h2><strong>5. Start CDC (Real-Time Sync)</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/cdc/start</code></p><p><strong>Request:</strong></p><pre><code>{
  &#8220;source&#8221;: &#8220;binlog&#8221;,
  &#8220;offset&#8221;: &#8220;log_456&#8221;
}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;CDC_STARTED&#8221;
}</code></pre><div><hr></div><h2><strong>6. Get CDC Lag</strong></h2><p><strong>GET</strong> <code>/migration/{migrationId}/cdc/lag</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;lagInMs&#8221;: 800,
  &#8220;lastSyncedTimestamp&#8221;: &#8220;2026-04-10T10:00:00Z&#8221;
}</code></pre><div><hr></div><h2><strong>7. Validate Data</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/validate</code></p><p><strong>Request:</strong></p><pre><code>{
  &#8220;type&#8221;: &#8220;checksum&#8221;,
  &#8220;tables&#8221;: [&#8221;bookings&#8221;]
}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;VALIDATION_STARTED&#8221;
}</code></pre><div><hr></div><h2><strong>8. Get Validation Report</strong></h2><p><strong>GET</strong> <code>/migration/{migrationId}/validation/report</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;COMPLETED&#8221;,
  &#8220;mismatchedRecords&#8221;: 25,
  &#8220;details&#8221;: &#8220;checksum mismatch in bookings&#8221;
}</code></pre><div><hr></div><h2><strong>9. Trigger Cutover</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/cutover</code></p><p><strong>Request:</strong></p><pre><code>{
  &#8220;mode&#8221;: &#8220;phased&#8221;,
  &#8220;trafficPercentage&#8221;: 50
}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;CUTOVER_IN_PROGRESS&#8221;
}</code></pre><div><hr></div><h2><strong>10. Rollback Migration</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/rollback</code></p><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;ROLLED_BACK&#8221;
}</code></pre><div><hr></div><h2><strong>11. Dual Write Toggle</strong></h2><p><strong>POST</strong> <code>/migration/{migrationId}/dual-write</code></p><p><strong>Request:</strong></p><pre><code>{
  &#8220;enabled&#8221;: true
}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;status&#8221;: &#8220;DUAL_WRITE_ENABLED&#8221;
}</code></pre><p><strong>Databases and Schema</strong></p><h1><strong>Databases Used in Migration Platform</strong></h1><h3><strong>1. Source Database (RDBMS)</strong></h3><ul><li><p>Example: MySQL / PostgreSQL</p></li><li><p>Purpose: Existing transactional system (Ticket booking, inventory)</p></li></ul><div><hr></div><h3><strong>2. Target Database (NoSQL)</strong></h3><ul><li><p>Example: Cassandra / DynamoDB</p></li><li><p>Purpose: Scalable, high-throughput datastore post-migration</p></li></ul><div><hr></div><h3><strong>3. Migration Metadata DB</strong></h3><ul><li><p>Example: PostgreSQL / MySQL</p></li><li><p>Purpose: Track migration jobs, states, checkpoints</p></li></ul><div><hr></div><h3><strong>4. Validation / Audit Store</strong></h3><ul><li><p>Example: S3 / Blob store / Cassandra</p></li><li><p>Purpose: Store validation reports, mismatches</p></li></ul><div><hr></div><h3><strong>5. Cache (Optional)</strong></h3><ul><li><p>Example: Redis</p></li><li><p>Purpose: Speed up reads during dual-read phase</p></li></ul><div><hr></div><h1><strong>Schema Design</strong></h1><div><hr></div><h2><strong>1. Source DB Schema (Relational - Simplified)</strong></h2><h3><strong>Events Table</strong></h3><pre><code>Events(
  event_id BIGINT PRIMARY KEY,
  name VARCHAR,
  venue VARCHAR,
  date TIMESTAMP
)</code></pre><h3><strong>Tickets Table</strong></h3><pre><code>Tickets(
  ticket_id BIGINT PRIMARY KEY,
  event_id BIGINT,
  seat_number VARCHAR,
  price DECIMAL,
  status VARCHAR,  -- AVAILABLE / BOOKED
  FOREIGN KEY (event_id) REFERENCES Events(event_id)
)</code></pre><h3><strong>Bookings Table</strong></h3><pre><code>Bookings(
  booking_id BIGINT PRIMARY KEY,
  user_id BIGINT,
  ticket_id BIGINT,
  status VARCHAR, -- CONFIRMED / CANCELLED
  created_at TIMESTAMP
)</code></pre><p>&#128073; Highly normalized &#8594; joins required</p><div><hr></div><h2><strong>2. Target DB Schema (NoSQL - Cassandra Style)</strong></h2><h3><strong>Design Principle</strong></h3><ul><li><p>Query-driven<br></p></li><li><p>Denormalized<br></p></li><li><p>Avoid joins<br></p></li></ul><div><hr></div><h3><strong>Table: Event_Tickets (Primary Read Path)</strong></h3><pre><code>Event_Tickets(
  event_id,
  seat_number,
  ticket_id,
  price,
  status,
  user_id,
  booking_status,
  PRIMARY KEY (event_id, seat_number)
)</code></pre><p>&#128073; Fetch all seats for an event quickly<br><br>&#128073; Handles seat availability + booking in one place</p><div><hr></div><h3><strong>Table: User_Bookings</strong></h3><pre><code>User_Bookings(
  user_id,
  booking_id,
  event_id,
  ticket_id,
  status,
  created_at,
  PRIMARY KEY (user_id, booking_id)
)</code></pre><p>&#128073; Query bookings per user</p><div><hr></div><h3><strong>Table: Event_Metadata</strong></h3><pre><code>Event_Metadata(
  event_id PRIMARY KEY,
  name,
  venue,
  date
)</code></pre><div><hr></div><h2><strong>3. Migration Metadata DB Schema</strong></h2><h3><strong>Migration Jobs</strong></h3><pre><code>Migration_Jobs(
  migration_id VARCHAR PRIMARY KEY,
  status VARCHAR, -- STARTED / IN_PROGRESS / COMPLETED
  start_time TIMESTAMP,
  end_time TIMESTAMP
)</code></pre><div><hr></div><h3><strong>Table Progress Tracking</strong></h3><pre><code>Migration_Progress(
  migration_id,
  table_name,
  last_processed_pk BIGINT,
  status VARCHAR,
  PRIMARY KEY (migration_id, table_name)
)</code></pre><p>&#128073; Used for checkpointing + resume</p><div><hr></div><h3><strong>CDC Offsets</strong></h3><pre><code>CDC_Offsets(
  migration_id,
  source,
  offset VARCHAR,
  updated_at TIMESTAMP,
  PRIMARY KEY (migration_id, source)
)</code></pre><p>&#128073; Tracks binlog/Kafka offset</p><div><hr></div><h2><strong>4. Validation / Audit Schema</strong></h2><h3><strong>Validation Results</strong></h3><pre><code>Validation_Results(
  migration_id,
  table_name,
  total_records_source BIGINT,
  total_records_target BIGINT,
  mismatch_count BIGINT,
  status VARCHAR,
  PRIMARY KEY (migration_id, table_name)
)</code></pre><div><hr></div><h3><strong>Mismatch Records (Optional)</strong></h3><pre><code>Mismatch_Records(
  migration_id,
  table_name,
  record_id,
  source_value TEXT,
  target_value TEXT
)</code></pre><div><hr></div><h1><strong>Key Design Insights (Interview Gold)</strong></h1><ul><li><p><strong>Denormalization in NoSQL</strong> &#8594; avoids joins, improves latency<br></p></li><li><p><strong>Multiple tables per query pattern</strong> &#8594; common in Cassandra<br></p></li><li><p><strong>Checkpointing via Migration_Progress</strong> &#8594; ensures fault tolerance<br></p></li><li><p><strong>CDC offsets</strong> &#8594; critical for exactly-once / no data loss<br></p></li><li><p><strong>Event_Tickets table</strong> &#8594; solves <em>seat consistency + fast lookup</em><br></p></li></ul><div><hr></div><div><hr></div><h1><strong>Microservices in DB Migration Platform</strong></h1><div><hr></div><h2><strong>1. Migration Orchestrator Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Central controller of migration lifecycle</p></li><li><p>Starts/stops jobs, manages phases (bulk &#8594; CDC &#8594; cutover)</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Trigger bulk migration</p></li><li><p>Start/stop CDC</p></li><li><p>Initiate cutover / rollback</p></li><li><p>Maintain state machine</p></li></ul><div><hr></div><h2><strong>2. Bulk Migration Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Migrate historical data from RDBMS &#8594; NoSQL</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Read data in batches</p></li><li><p>Transform schema (normalize &#8594; denormalize)</p></li><li><p>Write to NoSQL</p></li><li><p>Update checkpoints</p></li></ul><div><hr></div><h2><strong>3. CDC (Change Data Capture) Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Capture real-time changes from source DB</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Read binlogs (Debezium/Kafka)</p></li><li><p>Convert events &#8594; NoSQL format</p></li><li><p>Push to stream (Kafka)</p></li></ul><div><hr></div><h2><strong>4. Stream Processing / Replication Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Apply CDC events to NoSQL</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Consume Kafka topics</p></li><li><p>Ensure ordering (per key)</p></li><li><p>Idempotent writes</p></li><li><p>Conflict resolution</p></li></ul><div><hr></div><h2><strong>5. Schema Transformation Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Convert relational schema &#8594; NoSQL model</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Flatten joins</p></li><li><p>Build denormalized records</p></li><li><p>Maintain mapping rules</p></li></ul><div><hr></div><h2><strong>6. Dual Write Proxy Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Enable application to write to both DBs</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Intercept write requests</p></li><li><p>Write to RDBMS + NoSQL</p></li><li><p>Handle partial failures (retry / compensate)</p></li></ul><div><hr></div><h2><strong>7. Validation Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Ensure data correctness</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Row count validation</p></li><li><p>Checksums</p></li><li><p>Record-level diff</p></li><li><p>Generate reports</p></li></ul><div><hr></div><h2><strong>8. Cutover Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Switch traffic from RDBMS &#8594; NoSQL</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Gradual traffic shift (0% &#8594; 100%)</p></li><li><p>Enable shadow reads</p></li><li><p>Monitor errors</p></li></ul><div><hr></div><h2><strong>9. Rollback Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>Revert to old system if needed</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Redirect traffic back</p></li><li><p>Disable dual writes</p></li><li><p>Ensure consistency</p></li></ul><div><hr></div><h2><strong>10. Monitoring &amp; Observability Service</strong></h2><p><strong>Responsibility:</strong></p><ul><li><p>System visibility</p></li></ul><p><strong>Key tasks:</strong></p><ul><li><p>Track lag (CDC)</p></li><li><p>Migration progress</p></li><li><p>Error rates</p></li><li><p>Alerts</p></li></ul><div><hr></div><h1><strong>Interaction Flow (End-to-End)</strong></h1><div><hr></div><h2><strong>Phase 1: Bulk Migration</strong></h2><ol><li><p>Orchestrator &#8594; triggers Bulk Migration Service</p></li><li><p>Bulk Service:</p><ul><li><p>Reads from RDBMS</p></li><li><p>Calls Schema Transformer</p></li><li><p>Writes to NoSQL</p></li></ul></li><li><p>Updates checkpoints in Metadata DB</p></li></ol><div><hr></div><h2><strong>Phase 2: Real-Time Sync (CDC)</strong></h2><ol><li><p>CDC Service:</p><ul><li><p>Reads binlogs &#8594; pushes to Kafka</p></li></ul></li><li><p>Stream Processor:</p><ul><li><p>Consumes events</p></li><li><p>Transforms + writes to NoSQL</p></li></ul></li><li><p>Offsets stored for recovery</p></li></ol><div><hr></div><h2><strong>Phase 3: Dual Writes</strong></h2><ol><li><p>Application &#8594; Dual Write Proxy</p></li><li><p>Proxy:</p><ul><li><p>Writes to RDBMS</p></li><li><p>Writes to NoSQL</p></li></ul></li><li><p>Handles failures with retries / idempotency</p></li></ol><div><hr></div><h2><strong>Phase 4: Validation</strong></h2><ol><li><p>Validation Service:</p><ul><li><p>Compares source vs target</p></li><li><p>Generates reports</p></li></ul></li><li><p>Orchestrator decides readiness</p></li></ol><div><hr></div><h2><strong>Phase 5: Cutover</strong></h2><ol><li><p>Cutover Service:</p><ul><li><p>Gradually shifts reads to NoSQL</p></li><li><p>Then writes fully to NoSQL</p></li></ul></li><li><p>Shadow reads verify correctness</p></li></ol><div><hr></div><h2><strong>Phase 6: Rollback (if needed)</strong></h2><ol><li><p>Rollback Service:</p><ul><li><p>Redirects traffic back to RDBMS</p></li><li><p>Stops CDC / dual writes</p></li></ul></li></ol><div><hr></div><h1><strong>High-Level Interaction Diagram (Textual)</strong></h1><pre><code>Client
  &#8595;
Dual Write Proxy
  &#8595;              &#8600;
RDBMS         NoSQL

RDBMS &#8594; CDC Service &#8594; Kafka &#8594; Stream Processor &#8594; NoSQL

Bulk Migration Service &#8594; NoSQL

Validation Service &#8596; RDBMS &amp; NoSQL

Orchestrator &#8594; Controls all services</code></pre><div><hr></div><h1><strong>Key Design Insights (What interviewer looks for)</strong></h1><ul><li><p><strong>Decoupling via Kafka</strong> &#8594; avoids tight coupling between CDC and writes<br></p></li><li><p><strong>Idempotent consumers</strong> &#8594; ensures no duplicate writes<br></p></li><li><p><strong>Partitioning by event_id / ticket_id</strong> &#8594; preserves ordering<br></p></li><li><p><strong>Dual write + CDC overlap</strong> &#8594; ensures zero data loss<br></p></li><li><p><strong>Shadow reads before cutover</strong> &#8594; reduces risk<br></p></li></ul><div><hr></div><p>If you want to go <strong>next level (staff-level discussion)</strong>, I can explain:</p><ul><li><p>Exactly-once semantics in CDC pipeline<br></p></li><li><p>Handling <strong>seat booking consistency in Cassandra (LWT vs Redis locks)</strong><br></p></li><li><p>Or failure scenarios (Kafka lag, partial writes, replay strategies) &#128640;<br></p></li></ul><p>flow diagram</p><p>Here&#8217;s a <strong>clean, interview-ready flow diagram</strong> you can draw on a whiteboard &#128071;</p><div><hr></div><h1><strong>DB Migration Platform &#8211; Flow Diagram</strong></h1><pre><code>                  +----------------------+
                  |   Migration          |
                  |   Orchestrator       |
                  +----------+-----------+
                             |
        -----------------------------------------------
        |                     |                      |
        &#8595;                     &#8595;                      &#8595;

+----------------+   +----------------+    +----------------+
| Bulk Migration |   |   CDC Service  |    |  Validation    |
|   Service      |   | (Binlog Reader)|    |   Service      |
+--------+-------+   +--------+-------+    +--------+-------+
         |                    |                     |
         &#8595;                    &#8595;                     |
   +------------+     +---------------+            |
   |  RDBMS     |----&gt;|    Kafka      |------------+
   +------------+     +-------+-------+
                               |
                               &#8595;
                      +----------------------+
                      | Stream Processor     |
                      | (Replication Layer)  |
                      +----------+-----------+
                                 |
                                 &#8595;
                         +--------------+
                         |   NoSQL DB   |
                         +--------------+

------------------------------------------------------------

                 (Application Traffic Flow)

                     +------------------+
Client  -----------&gt; | Dual Write Proxy |
                     +--------+---------+
                              |
                  -------------------------
                  |                       |
                  &#8595;                       &#8595;
             +---------+           +------------+
             |  RDBMS  |           |  NoSQL DB  |
             +---------+           +------------+

------------------------------------------------------------

                 (Cutover Phase)

Client  -------------------------------------&gt; NoSQL DB
                     (RDBMS removed gradually)</code></pre><div><hr></div><h1><strong>How to Explain This in Interview (Quick Script)</strong></h1><ul><li><p><strong>Top layer</strong> &#8594; Orchestrator controls everything<br></p></li><li><p><strong>Left path</strong> &#8594; Bulk migration moves historical data<br></p></li><li><p><strong>Middle path</strong> &#8594; CDC + Kafka handles real-time updates<br></p></li><li><p><strong>Right path</strong> &#8594; Validation ensures correctness<br></p></li><li><p><strong>Bottom</strong> &#8594; Dual writes keep both DBs in sync<br></p></li><li><p><strong>Final step</strong> &#8594; Cutover shifts traffic fully to NoSQL<br></p></li></ul><div><hr></div><h1></h1><p></p><p><br></p>]]></content:encoded></item><item><title><![CDATA[Event-sourced state transition problem]]></title><description><![CDATA[Given: Order state transitions with timestamps . States: Created &#8594; Confirmed &#8594; Reached Merchant &#8594; Reached Customer &#8594; Delivered]]></description><link>https://programmingappliedai.substack.com/p/event-sourced-state-transition-problem</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/event-sourced-state-transition-problem</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Sat, 21 Mar 2026 07:08:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Given: Order state transitions with timestamps . States: Created &#8594; Confirmed &#8594; Reached Merchant &#8594; Reached Customer &#8594; Delivered</p><p><br>Questions:<br>Write a query to fetch all order IDs with their latest state in the last 1 hour<br>Exclude orders that are already delivered<br>How would this query behave at scale?<br>What indexes would you add?</p><p></p><p>This is a classic <strong>event-sourced state transition</strong> problem &#8212; very relevant for high-scale systems like food delivery or ride-sharing.</p><p>Let&#8217;s go step by step.</p><div><hr></div><h2>1. Query: Latest state in last 1 hour (excluding delivered)</h2><p>Assume table:</p><pre><code>order_state_transitions (
    order_id BIGINT,
    state VARCHAR,
    timestamp TIMESTAMP
)</code></pre><h3>&#9989; SQL Query</h3><pre><code>SELECT order_id, state
FROM (
    SELECT 
        order_id,
        state,
        timestamp,
        ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY timestamp DESC) as rn
    FROM order_state_transitions
    WHERE timestamp &gt;= NOW() - INTERVAL &#8216;1 hour&#8217;
) t
WHERE rn = 1
AND state != &#8216;Delivered&#8217;;</code></pre><div><hr></div><h3>&#128269; Explanation</h3><ul><li><p><code>WHERE timestamp &gt;= NOW() - 1 hour</code><br><br>&#8594; limits dataset early (critical for performance)<br></p></li><li><p><code>ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY timestamp DESC)</code><br><br>&#8594; finds latest state per order<br></p></li><li><p><code>rn = 1</code><br><br>&#8594; keeps only latest record<br></p></li><li><p><code>state != 'Delivered'</code><br><br>&#8594; filters completed orders<br></p></li></ul><div><hr></div><h2>2. Behavior at Scale &#128640;</h2><p>At scale (millions of events/min):</p><h3>&#10060; Problems</h3><ol><li><p><strong>Window function is expensive</strong><br></p><ul><li><p>Needs sorting per <code>order_id</code><br></p></li><li><p>Memory + CPU heavy<br></p></li></ul></li><li><p><strong>Large scan even for 1 hour</strong><br></p><ul><li><p>If system handles high throughput &#8594; still huge data<br></p></li></ul></li><li><p><strong>Hot partitions</strong><br></p><ul><li><p>Recent data is heavily accessed<br></p></li></ul></li><li><p><strong>Repeated computation</strong><br></p><ul><li><p>Every query recomputes latest state<br></p></li></ul></li></ol><div><hr></div><h3>&#9888;&#65039; Real-world impact</h3><ul><li><p>High latency (100ms &#8594; seconds)<br></p></li><li><p>Increased DB CPU<br></p></li><li><p>Not suitable for real-time dashboards or APIs<br></p></li></ul><div><hr></div><h2>3. Optimizations (What you&#8217;d do in production)</h2><h3>&#9989; 1. Maintain a <strong>current state table (denormalized)</strong></h3><pre><code>orders_current_state (
    order_id BIGINT PRIMARY KEY,
    current_state VARCHAR,
    last_updated TIMESTAMP
)</code></pre><p>Update this on every state change.</p><p>&#128073; Query becomes:</p><pre><code>SELECT order_id, current_state
FROM orders_current_state
WHERE last_updated &gt;= NOW() - INTERVAL &#8216;1 hour&#8217;
AND current_state != &#8216;Delivered&#8217;;</code></pre><p>&#10004; O(1) lookup<br><br>&#10004; No window function<br><br>&#10004; Much faster</p><div><hr></div><h3>&#9989; 2. Stream processing (Kafka-style)</h3><p>Instead of querying raw DB:</p><ul><li><p>Consume events<br></p></li><li><p>Maintain latest state in:<br></p><ul><li><p>Redis / Cassandra / materialized view<br></p></li></ul></li></ul><div><hr></div><h3>&#9989; 3. Partitioning</h3><p>Partition table by time:</p><pre><code>PARTITION BY RANGE (timestamp)</code></pre><p>&#8594; Only scan last 1-hour partition</p><div><hr></div><h2>4. Indexing Strategy &#128202;</h2><p>If you <strong>must run the original query</strong>, indexes are critical.</p><h3>&#9989; Primary Index</h3><pre><code>CREATE INDEX idx_order_time 
ON order_state_transitions (order_id, timestamp DESC);</code></pre><p>&#10004; Helps window function ordering<br><br>&#10004; Faster partitioning by <code>order_id</code></p><div><hr></div><h3>&#9989; Time-based Index</h3><pre><code>CREATE INDEX idx_timestamp 
ON order_state_transitions (timestamp);</code></pre><p>&#10004; Helps filter last 1 hour quickly</p><div><hr></div><h3>&#9989; Covering Index (best case)</h3><pre><code>CREATE INDEX idx_covering 
ON order_state_transitions (timestamp, order_id, state);</code></pre><p>&#10004; Avoids table lookup (index-only scan)</p><div><hr></div><h3>&#128640; Ideal combo</h3><ul><li><p><code>(timestamp)</code> &#8594; prune data<br></p></li><li><p><code>(order_id, timestamp DESC)</code> &#8594; latest per order<br></p></li></ul><div><hr></div><h2>5. Final System Design Insight &#129504;</h2><p>In real systems (Uber/Zomato style):</p><p>&#128073; You <strong>never compute latest state from raw events on demand</strong></p><p>Instead:</p><ul><li><p>Write &#8594; append-only event log<br></p></li><li><p>Maintain &#8594; <strong>materialized latest state</strong><br></p></li><li><p>Query &#8594; read from optimized store<br></p></li></ul><div><hr></div><h2>TL;DR</h2><ul><li><p>Use window function for correctness<br></p></li><li><p>Avoid it in production at scale<br></p></li><li><p>Maintain <strong>current state table</strong><br></p></li><li><p>Index on <code>(timestamp)</code> and <code>(order_id, timestamp DESC)</code><br></p></li><li><p>Consider streaming + caching layer<br></p></li></ul><div><hr></div><h1>1. Kafka + Consumer Architecture &#128640;</h1><h3>&#129513; Core Idea</h3><p>Treat order state changes as an <strong>event stream</strong>, not just DB writes.</p><div><hr></div><h2>&#128260; Flow</h2><h3>1. Producer (Order Service)</h3><p>Every state change emits an event:</p><pre><code>{
  &#8220;order_id&#8221;: 123,
  &#8220;state&#8221;: &#8220;Reached Customer&#8221;,
  &#8220;timestamp&#8221;: &#8220;2026-03-21T10:00:00Z&#8221;
}</code></pre><div><hr></div><h3>2. Kafka Topic</h3><pre><code>topic: order_state_transitions
partition key: order_id</code></pre><p>&#128073; Why <code>order_id</code> as key?</p><ul><li><p>Ensures <strong>ordering per order</strong><br></p></li><li><p>All events for an order go to same partition<br></p></li></ul><div><hr></div><h3>3. Consumers</h3><h4>&#9989; Consumer 1: Current State Updater</h4><ul><li><p>Reads events<br></p></li><li><p>Updates <strong>materialized view</strong><br></p></li></ul><pre><code>orders_current_state
(order_id, current_state, last_updated)</code></pre><div><hr></div><h4>&#9989; Consumer 2: Analytics / Monitoring</h4><ul><li><p>SLA tracking<br></p></li><li><p>Delay detection (e.g., stuck at &#8220;Reached Merchant&#8221;)<br></p></li></ul><div><hr></div><h4>&#9989; Consumer 3: Notification Service</h4><ul><li><p>Trigger push notifications:<br></p><ul><li><p>&#8220;Order Out for Delivery&#8221;<br></p></li><li><p>&#8220;Delivered&#8221;<br></p></li></ul></li></ul><div><hr></div><h3>&#9881;&#65039; Processing Logic</h3><pre><code>for each event:
    if event.timestamp &gt; stored_timestamp:
        update current_state</code></pre><p>&#128073; Protects against <strong>out-of-order events</strong></p><div><hr></div><h3>&#9888;&#65039; Challenges</h3><p>ProblemSolutionOut-of-order eventsUse timestamp/version checkDuplicate eventsIdempotent updatesConsumer lagScale partitionsReprocessingKafka replay capability</p><div><hr></div><h3>&#9989; Why this architecture?</h3><ul><li><p>No heavy DB queries<br></p></li><li><p>Real-time updates<br></p></li><li><p>Scales horizontally<br></p></li><li><p>Enables multiple downstream use cases<br></p></li></ul><div><hr></div><h1>2. Redis vs Cassandra Tradeoffs &#9878;&#65039;</h1><p>This is where interviews get interesting.</p><div><hr></div><h2>&#128997; Redis (In-memory, ultra-fast)</h2><h3>&#9989; Pros</h3><ul><li><p>Sub-millisecond reads<br></p></li><li><p>Perfect for <strong>latest state lookup</strong><br></p></li><li><p>Supports TTL (auto-expire old orders)<br></p></li><li><p>Simple key-value model<br></p></li></ul><pre><code>key: order:123 &#8594; &#8220;Reached Customer&#8221;</code></pre><div><hr></div><h3>&#10060; Cons</h3><ul><li><p>Memory expensive<br></p></li><li><p>Limited durability (unless tuned)<br></p></li><li><p>Not ideal for long-term storage<br></p></li></ul><div><hr></div><h2>&#128998; Cassandra (Distributed, write-heavy DB)</h2><h3>&#9989; Pros</h3><ul><li><p>Handles <strong>massive write throughput</strong><br></p></li><li><p>Persistent storage<br></p></li><li><p>Highly scalable<br></p></li><li><p>Good for time-series/event data<br></p></li></ul><pre><code>PRIMARY KEY (order_id, timestamp)</code></pre><div><hr></div><h3>&#10060; Cons</h3><ul><li><p>Higher read latency than Redis<br></p></li><li><p>More complex data modeling<br></p></li><li><p>Eventually consistent<br></p></li></ul><div><hr></div><h2>&#129504; When to use what?</h2><p>Use CaseBest ChoiceReal-time API (get current state)&#9989; RedisHistorical queries / audit&#9989; CassandraHigh write ingestion&#9989; CassandraUltra-low latency reads&#9989; Redis</p><div><hr></div><h2>&#128161; Best Practice (Hybrid Approach)</h2><p>&#128073; Use both:</p><ul><li><p>Kafka &#8594; Consumers &#8594;<br></p><ul><li><p>Redis &#8594; latest state (fast reads)<br></p></li><li><p>Cassandra &#8594; full history (durability)<br></p></li></ul></li></ul><div><hr></div><h2>&#128293; Architecture Pattern</h2><pre><code>Kafka &#8594; Consumer &#8594;
    &#9500;&#9472;&#9472; Redis (current state)
    &#9492;&#9472;&#9472; Cassandra (event log)</code></pre><div><hr></div><h1>3. Full HLD Interview Answer &#127959;&#65039;</h1><p>Here&#8217;s how you&#8217;d present this in an interview.</p><div><hr></div><h2>&#129534; Problem Statement</h2><p>Design a system to:</p><ul><li><p>Track order state transitions<br></p></li><li><p>Fetch latest state for active orders<br></p></li><li><p>Handle high throughput (millions of events)<br></p></li></ul><div><hr></div><h2>&#9989; Functional Requirements</h2><ol><li><p>Track order lifecycle states<br></p></li><li><p>Fetch latest state of an order<br></p></li><li><p>Fetch active orders (not delivered)<br></p></li><li><p>Support real-time updates<br></p></li><li><p>Maintain historical transitions<br></p></li></ol><div><hr></div><h2>&#9881;&#65039; Non-Functional Requirements</h2><ol><li><p>Low latency (&lt;50ms reads)<br></p></li><li><p>High throughput (writes/sec in millions)<br></p></li><li><p>High availability<br></p></li><li><p>Fault tolerance<br></p></li><li><p>Scalability<br></p></li></ol><div><hr></div><h2>&#129513; High-Level Components</h2><h3>1. Order Service</h3><ul><li><p>Produces state change events<br></p></li></ul><h3>2. Kafka</h3><ul><li><p>Event streaming backbone<br></p></li><li><p>Partitioned by <code>order_id</code><br></p></li></ul><div><hr></div><h3>3. Stream Processors (Consumers)</h3><h4>a) State Updater</h4><ul><li><p>Updates Redis (latest state)<br></p></li></ul><h4>b) Persistence Layer</h4><ul><li><p>Writes to Cassandra (history)<br></p></li></ul><h4>c) Notification Service</h4><ul><li><p>Sends real-time updates<br></p></li></ul><div><hr></div><h3>4. Storage Layer</h3><h4>Redis</h4><pre><code>order_id &#8594; current_state</code></pre><h4>Cassandra</h4><pre><code>(order_id, timestamp) &#8594; state</code></pre><div><hr></div><h3>5. Query Service (Read API)</h3><p>Handles:</p><pre><code>GET /orders/active?lastUpdated=1h</code></pre><p>Reads from:</p><ul><li><p>Redis (fast path)<br></p></li></ul><div><hr></div><h2>&#128260; Data Flow</h2><pre><code>Order Service
     &#8595;
Kafka (partitioned by order_id)
     &#8595;
Consumers
     &#8595;
 &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
 &#8595;               &#8595;               &#8595;
Redis        Cassandra     Notifications</code></pre><div><hr></div><h2>&#9889; Scaling Strategy</h2><ul><li><p>Increase Kafka partitions<br></p></li><li><p>Horizontal scaling of consumers<br></p></li><li><p>Redis sharding<br></p></li><li><p>Cassandra cluster scaling<br></p></li></ul><div><hr></div><h2>&#129504; Key Design Decisions</h2><h3>1. Why not query DB directly?</h3><p>&#8594; Too slow at scale (window functions)</p><h3>2. Why event-driven?</h3><p>&#8594; Decouples producers &amp; consumers</p><h3>3. Why materialized view?</h3><p>&#8594; O(1) read performance</p><div><hr></div><h2>&#128680; Edge Cases</h2><ul><li><p>Duplicate events &#8594; idempotency<br></p></li><li><p>Out-of-order &#8594; timestamp checks<br></p></li><li><p>Late events &#8594; reconciliation jobs<br></p></li><li><p>Redis failure &#8594; rebuild from Kafka<br></p></li></ul><div><hr></div><h2>&#127919; Final Takeaway</h2><p>This evolves from:</p><pre><code>Naive SQL &#8594; Bottleneck &#10060;</code></pre><p>to:</p><pre><code>Event-driven + Materialized View &#8594; Scalable &#9989;</code></pre><div><hr></div><h1>1. Exactly-Once Semantics in Kafka &#9881;&#65039;</h1><h2>&#10071; The Problem</h2><p>In real systems, Kafka guarantees:</p><ul><li><p><strong>At-least-once delivery</strong> by default</p></li></ul><p>This means:</p><ul><li><p>Duplicate events can occur</p></li><li><p>Out-of-order events can occur (rare but possible across retries)</p></li></ul><div><hr></div><h2>&#9989; Goal</h2><p>Ensure:</p><blockquote><p>Each order&#8217;s latest state is <strong>correctly reflected exactly once</strong></p></blockquote><div><hr></div><h2>&#128273; Techniques</h2><h3>&#9989; 1. Idempotent Consumers (Most Important)</h3><p>Store <strong>last processed timestamp (or version)</strong></p><pre><code>if incoming.timestamp &gt; stored.timestamp:
    update state
else:
    ignore</code></pre><p>&#10004; Handles:</p><ul><li><p>duplicates<br></p></li><li><p>retries<br></p></li><li><p>out-of-order events<br></p></li></ul><div><hr></div><h3>&#9989; 2. Kafka Idempotent Producers</h3><p>Enable:</p><pre><code>enable.idempotence=true</code></pre><p>&#10004; Prevents duplicate writes from producer retries</p><div><hr></div><h3>&#9989; 3. Transactions (Advanced)</h3><p>Kafka supports <strong>exactly-once semantics (EOS)</strong> using:</p><ul><li><p>Producer transactions<br></p></li><li><p>Consumer offset + DB write atomicity<br></p></li></ul><p>Flow:</p><pre><code>begin transaction
    consume event
    update DB
    commit offset
commit transaction</code></pre><p>&#10004; Ensures:</p><ul><li><p>No partial updates<br></p></li><li><p>No data loss<br></p></li></ul><div><hr></div><h3>&#9888;&#65039; Tradeoff</h3><p>ApproachComplexityUse CaseIdempotencyLow&#9989; Most systemsKafka TransactionsHighFinancial systems</p><div><hr></div><h2>&#128161; Interview Insight</h2><p>&#128073; Say this:</p><blockquote><p>&#8220;I&#8217;d prefer idempotent consumers over full EOS due to lower complexity and similar guarantees for this use case.&#8221;</p></blockquote><div><hr></div><h1>2. Redis Data Modeling &amp; Eviction &#129504;</h1><h2>&#127919; Goal</h2><p>Fast lookup for:</p><ul><li><p>Latest state<br></p></li><li><p>Active (non-delivered) orders<br></p></li></ul><div><hr></div><h2>&#9989; Data Model Options</h2><h3>Option 1: Simple Key-Value</h3><pre><code>SET order:123 &#8220;Reached Customer&#8221;</code></pre><p>&#10004; Simple<br><br>&#10060; Hard to query &#8220;last 1 hour&#8221;</p><div><hr></div><h3>&#9989; Option 2: Hash (Better)</h3><pre><code>HSET order:123 state &#8220;Reached Customer&#8221; timestamp 1711000000</code></pre><div><hr></div><h3>&#9989; Option 3: Sorted Set (Best for time queries)</h3><pre><code>ZADD active_orders &lt;timestamp&gt; order_id</code></pre><p>&#10004; Enables:</p><pre><code>ZRANGEBYSCORE active_orders now-1h now</code></pre><p>&#128073; Perfect for:</p><ul><li><p>&#8220;last 1 hour active orders&#8221;<br></p></li></ul><div><hr></div><h2>&#129504; Final Redis Design</h2><pre><code>Key 1: order:{id} &#8594; {state, timestamp}
Key 2: active_orders (ZSET) &#8594; timestamp &#8594; order_id</code></pre><div><hr></div><h2>&#128293; Handling Delivered Orders</h2><p>When state = Delivered:</p><pre><code>DEL order:{id}
ZREM active_orders order_id</code></pre><p>&#10004; Keeps dataset small<br><br>&#10004; Only active orders remain</p><div><hr></div><h2>&#9888;&#65039; Eviction Strategy</h2><p>Set TTL:</p><pre><code>EXPIRE order:{id} 86400  (1 day)</code></pre><div><hr></div><h2>&#128680; Memory Concerns</h2><ul><li><p>Millions of active orders &#8594; GBs of RAM<br></p></li><li><p>Use:<br></p><ul><li><p>Redis Cluster (sharding)<br></p></li><li><p>Compression (if needed)<br></p></li></ul></li></ul><div><hr></div><h2>&#128161; Interview Insight</h2><p>&#128073; Say:</p><blockquote><p>&#8220;I&#8217;d use Redis Sorted Sets for time-based queries and Hashes for state storage, ensuring O(log N) insert and efficient range queries.&#8221;</p></blockquote><div><hr></div><h1>3. Cassandra Schema Design (Time-Series) &#128998;</h1><h2>&#127919; Goal</h2><p>Efficiently store:</p><ul><li><p>Order history<br></p></li><li><p>High write throughput<br></p></li></ul><div><hr></div><h2>&#10071; Bad Schema (common mistake)</h2><pre><code>PRIMARY KEY (order_id, timestamp)</code></pre><p>&#10060; Hot partition problem (all events for one order)</p><div><hr></div><h2>&#9989; Better Schema</h2><pre><code>CREATE TABLE order_events (
    order_id BIGINT,
    event_date DATE,
    timestamp TIMESTAMP,
    state TEXT,
    PRIMARY KEY ((order_id, event_date), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);</code></pre><div><hr></div><h2>&#128269; Why this works</h2><h3>&#9989; Partition Key</h3><pre><code>(order_id, event_date)</code></pre><p>&#10004; Spreads data<br><br>&#10004; Avoids large partitions</p><div><hr></div><h3>&#9989; Clustering Key</h3><pre><code>timestamp DESC</code></pre><p>&#10004; Latest event comes first<br><br>&#10004; Efficient reads</p><div><hr></div><h2>&#128293; Query Patterns</h2><h3>Get latest state:</h3><pre><code>SELECT * FROM order_events
WHERE order_id = 123
AND event_date = &#8216;2026-03-21&#8217;
LIMIT 1;</code></pre><div><hr></div><h3>Get history:</h3><pre><code>SELECT * FROM order_events
WHERE order_id = 123
AND event_date = &#8216;2026-03-21&#8217;;</code></pre><div><hr></div><h2>&#9888;&#65039; Challenges</h2><p>ProblemSolutionCross-day queriesQuery multiple partitionsLate eventsAllow slight backfillLarge partitionsUse bucketing (hour-level if needed)</p><div><hr></div><h2>&#129504; Advanced Optimization</h2><h3>Bucketing (for very high scale)</h3><pre><code>PRIMARY KEY ((order_id, event_date, hour_bucket), timestamp)</code></pre><div><hr></div><h2>&#128161; Interview Insight</h2><p>&#128073; Say:</p><blockquote><p>&#8220;I&#8217;d bucket partitions by date (or hour for extreme scale) to avoid unbounded partition growth and maintain predictable performance.&#8221;</p></blockquote><div><hr></div><h1>&#128293; Putting It All Together (Final Architecture)</h1><pre><code>                &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                &#9474;   Order Service    &#9474;
                &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                          &#8595;
                   Kafka (partitioned)
                          &#8595;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#8595;              &#8595;              &#8595;
   State Updater   Persistence    Notification
        &#8595;              &#8595;
     Redis         Cassandra
        &#8595;
   Query Service (API)</code></pre><div><hr></div><h1>&#127919; Final Senior-Level Takeaways</h1><ol><li><p><strong>Never query raw events for latest state at scale</strong><br></p></li><li><p><strong>Use Kafka + consumers for real-time materialization</strong><br></p></li><li><p><strong>Redis = speed, Cassandra = durability</strong><br></p></li><li><p><strong>Idempotency &gt; complex exactly-once</strong><br></p></li><li><p><strong>Design for access patterns, not normalization</strong><br></p></li></ol><div><hr></div><p><strong>Open Questions</strong></p><ul><li><p>Handling <strong>consumer lag + backpressure (very important for Kafka at scale)</strong></p></li><li><p>Designing <strong>SLA monitoring (detect stuck orders automatically)</strong></p></li><li><p>Or converting this into a <strong>production-ready API contract + metrics + alerting setup</strong></p><p></p><h1>1. Handling Consumer Lag &amp; Backpressure in Kafka &#128678;</h1><h2>&#10071; Problem</h2><p>At scale:</p><ul><li><p>Producers &#8594; millions of events/sec</p></li><li><p>Consumers can&#8217;t keep up &#8594; <strong>lag builds up</strong></p></li></ul><p>&#128073; Lag = difference between:</p><ul><li><p>Latest offset (Kafka)</p></li><li><p>Committed offset (consumer)</p></li></ul><div><hr></div><h2>&#128269; Why this is dangerous</h2><ul><li><p>Delayed order state updates</p></li><li><p>Users see stale data</p></li><li><p>Downstream systems (notifications, SLA) break</p></li></ul><div><hr></div><h2>&#9989; Solutions</h2><h3>&#9989; 1. Horizontal Scaling (Primary lever)</h3><ul><li><p>Increase partitions in topic</p></li><li><p>Increase consumer instances</p></li></ul><pre><code># Rule:
Consumers &#8804; Partitions</code></pre><p>&#10004; Parallelism increases linearly</p><div><hr></div><h3>&#9989; 2. Smarter Partitioning</h3><p>Use:</p><pre><code>partition key = order_id</code></pre><p>&#10004; Guarantees ordering per order<br><br>&#10004; Enables parallel processing across orders</p><div><hr></div><h3>&#9989; 3. Backpressure Handling</h3><p>If consumers are slow:</p><h4>Option A: Slow down producers</h4><ul><li><p>Apply <strong>rate limiting</strong><br></p></li><li><p>Buffer via upstream queue<br></p></li></ul><h4>Option B: Buffer + absorb spikes</h4><ul><li><p>Kafka already acts as buffer<br></p></li><li><p>Increase retention temporarily<br></p></li></ul><div><hr></div><h3>&#9989; 4. Batch Processing</h3><p>Instead of:</p><pre><code>process 1 event at a time</code></pre><p>Do:</p><pre><code>process 100&#8211;1000 events in batch</code></pre><p>&#10004; Better throughput<br><br>&#10004; Fewer network/DB calls</p><div><hr></div><h3>&#9989; 5. Async + Parallel Processing</h3><ul><li><p>Use thread pools inside consumer<br></p></li><li><p>But maintain ordering per key<br></p></li></ul><p>&#128073; Trick:</p><ul><li><p>Partition-level parallelism (safe)<br></p></li><li><p>Not per-message random threading<br></p></li></ul><div><hr></div><h3>&#9989; 6. Prioritize Critical Events</h3><p>Use separate topics:</p><pre><code>order_state_high_priority
order_state_low_priority</code></pre><p>&#10004; Prevents backlog from affecting critical flows</p><div><hr></div><h3>&#128202; Monitoring (VERY IMPORTANT)</h3><p>Track:</p><ul><li><p>Consumer lag per partition<br></p></li><li><p>Processing latency<br></p></li><li><p>Error rate<br></p></li></ul><div><hr></div><h2>&#128161; Interview Insight</h2><p>Say:</p><blockquote><p>&#8220;Kafka acts as a buffer, but I&#8217;d control lag via partition scaling, batching, and monitoring lag metrics to auto-scale consumers.&#8221;</p></blockquote><div><hr></div><h1>2. SLA Monitoring (Detect Stuck Orders) &#9201;&#65039;</h1><h2>&#127919; Goal</h2><p>Detect cases like:</p><ul><li><p>Order stuck at &#8220;Reached Merchant&#8221; for 30 mins<br></p></li><li><p>Delivery delays<br></p></li></ul><div><hr></div><h2>&#9989; Approach: Stream-Based SLA Engine</h2><div><hr></div><h2>&#128260; Flow</h2><p>Kafka &#8594; SLA Consumer &#8594; Redis / Alert System</p><div><hr></div><h2>&#129504; Logic</h2><p>Maintain expected transition times:</p><pre><code>Created &#8594; Confirmed           (2 mins)
Confirmed &#8594; Merchant          (5 mins)
Merchant &#8594; Customer           (20 mins)</code></pre><div><hr></div><h3>&#9989; Real-time Detection</h3><p>For every event:</p><pre><code>current_state = &#8220;Reached Merchant&#8221;
last_transition_time = T

expected_next_time = T + SLA_limit

if now &gt; expected_next_time:
    mark as delayed</code></pre><div><hr></div><h2>&#9989; Storage for SLA Tracking</h2><h3>Redis:</h3><pre><code>order:123 &#8594; {
    state: &#8220;Reached Merchant&#8221;,
    last_updated: T
}</code></pre><div><hr></div><h2>&#9989; Periodic Checker (Fallback)</h2><p>Run every 1&#8211;5 mins:</p><pre><code>scan active orders
if current_time - last_updated &gt; SLA_threshold:
    trigger alert</code></pre><div><hr></div><h2>&#128680; Alerting</h2><ul><li><p>Push to:<br></p><ul><li><p>Ops dashboard<br></p></li><li><p>PagerDuty / Slack<br></p></li><li><p>Customer notifications<br></p></li></ul></li></ul><div><hr></div><h2>&#128293; Advanced: State Transition Graph</h2><p>Represent SLA as:</p><pre><code>State Machine + Time Constraints</code></pre><p>&#10004; More flexible<br><br>&#10004; Handles dynamic SLAs</p><div><hr></div><h2>&#128161; Interview Insight</h2><p>Say:</p><blockquote><p>&#8220;I&#8217;d build an SLA monitoring consumer that evaluates state transitions in real-time and triggers alerts if thresholds are breached, with a periodic reconciliation job for safety.&#8221;</p></blockquote><div><hr></div><h1>3. Production-Ready API + Metrics + Alerting &#128225;</h1><p>Now let&#8217;s make this system <strong>real-world deployable</strong>.</p><div><hr></div><h2>&#127760; APIs</h2><h3>&#9989; 1. Get Order State</h3><pre><code>GET /orders/{order_id}</code></pre><p><strong>Response:</strong></p><pre><code>{
  &#8220;order_id&#8221;: 123,
  &#8220;state&#8221;: &#8220;Reached Customer&#8221;,
  &#8220;last_updated&#8221;: &#8220;2026-03-21T10:00:00Z&#8221;
}</code></pre><p>&#128073; Source: Redis</p><div><hr></div><h3>&#9989; 2. Get Active Orders (last 1 hour)</h3><pre><code>GET /orders/active?since=1h</code></pre><p><strong>Response:</strong></p><pre><code>[
  { &#8220;order_id&#8221;: 123, &#8220;state&#8221;: &#8220;Confirmed&#8221; },
  { &#8220;order_id&#8221;: 456, &#8220;state&#8221;: &#8220;Reached Merchant&#8221; }
]</code></pre><p>&#128073; Source: Redis ZSET</p><div><hr></div><h3>&#9989; 3. Get Order History</h3><pre><code>GET /orders/{order_id}/history</code></pre><p>&#128073; Source: Cassandra</p><div><hr></div><h3>&#9989; 4. Admin: Reprocess Events</h3><pre><code>POST /orders/reprocess</code></pre><p>&#10004; Replay Kafka events<br><br>&#10004; Fix inconsistencies</p><div><hr></div><h2>&#128202; Metrics (Critical for Production)</h2><div><hr></div><h3>&#9989; Kafka Metrics</h3><ul><li><p>Consumer lag<br></p></li><li><p>Throughput (events/sec)<br></p></li><li><p>Rebalance count<br></p></li></ul><div><hr></div><h3>&#9989; Redis Metrics</h3><ul><li><p>Memory usage<br></p></li><li><p>Evictions<br></p></li><li><p>Latency<br></p></li></ul><div><hr></div><h3>&#9989; Cassandra Metrics</h3><ul><li><p>Write latency<br></p></li><li><p>Read latency<br></p></li><li><p>Compaction stats<br></p></li></ul><div><hr></div><h3>&#9989; Application Metrics</h3><ul><li><p>API latency (P50, P95, P99)<br></p></li><li><p>Error rate<br></p></li><li><p>SLA violations count<br></p></li></ul><div><hr></div><h2>&#128680; Alerting Strategy</h2><p>Trigger alerts on:</p><h3>&#128308; Critical</h3><ul><li><p>Consumer lag &gt; threshold<br></p></li><li><p>Kafka broker down<br></p></li><li><p>Redis unavailable<br></p></li></ul><div><hr></div><h3>&#128993; Warning</h3><ul><li><p>SLA violations increasing<br></p></li><li><p>API latency spike<br></p></li></ul><div><hr></div><h2>&#128200; Observability Stack</h2><p>Use:</p><ul><li><p>Metrics &#8594; Prometheus<br></p></li><li><p>Dashboards &#8594; Grafana<br></p></li><li><p>Logs &#8594; ELK stack<br></p></li><li><p>Tracing &#8594; OpenTelemetry<br></p></li></ul><div><hr></div><h2>&#128293; Resilience Strategies</h2><h3>&#9989; 1. Redis Failure</h3><ul><li><p>Rebuild from Kafka replay<br></p></li><li><p>Fallback to Cassandra (slower)<br></p></li></ul><div><hr></div><h3>&#9989; 2. Kafka Failure</h3><ul><li><p>Retry with backoff<br></p></li><li><p>Multi-AZ cluster<br></p></li></ul><div><hr></div><h3>&#9989; 3. Consumer Crash</h3><ul><li><p>Offset-based recovery<br></p></li><li><p>Stateless consumers<br></p></li></ul><div><hr></div><h2>&#129504; Final Interview Closing Statement</h2><p></p><blockquote><p>&#8220;I&#8217;d design this as an event-driven system with Kafka as the backbone, Redis for low-latency reads, and Cassandra for durable history. I&#8217;d ensure correctness via idempotent consumers, scalability via partitioning, and reliability via monitoring, replay mechanisms, and SLA tracking.&#8221;</p></blockquote><div><hr></div><h1>&#127919; Final Takeaway</h1><p>You&#8217;ve now covered:</p><p>&#10004; Query optimization &#8594; avoided<br><br>&#10004; Event-driven design &#8594; implemented<br><br>&#10004; Scaling &#8594; Kafka + partitioning<br><br>&#10004; Storage &#8594; Redis + Cassandra<br><br>&#10004; Reliability &#8594; idempotency + replay<br><br>&#10004; Observability &#8594; metrics + alerts</p><div><hr></div><p></p></li></ul>]]></content:encoded></item><item><title><![CDATA[How can consumer throughput be increased in kafka]]></title><description><![CDATA[&#128640; 1.]]></description><link>https://programmingappliedai.substack.com/p/how-can-consumer-throughput-be-increased</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/how-can-consumer-throughput-be-increased</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Sat, 21 Mar 2026 06:45:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>&#128640; 1. Increase Parallelism (Biggest Lever)</h1><h3>&#9989; Increase partitions</h3><ul><li><p>Kafka guarantees <strong>1 consumer per partition per group</strong></p></li><li><p>More partitions &#8658; more parallel consumption</p></li></ul><p>&#128073; Rule of thumb:</p><ul><li><p>Partitions &#8805; total consumer threads</p></li></ul><div><hr></div><h3>&#9989; Scale consumer group horizontally</h3><ul><li><p>Add more consumer instances in the same group</p></li><li><p>Kafka auto-rebalances partitions</p></li></ul><p>&#9888;&#65039; Watch out:</p><ul><li><p>Too many rebalances can hurt throughput</p></li></ul><div><hr></div><h3>&#9989; Multi-threaded consumers</h3><ul><li><p>Default Kafka consumer is single-threaded</p></li><li><p>Use:</p><ul><li><p>Thread pool for processing</p></li><li><p>Separate polling + processing</p></li></ul></li></ul><p>Pattern:</p><pre><code>Poll &#8594; Queue &#8594; Worker Threads</code></pre><div><hr></div><h1>&#9889; 2. Optimize Polling &amp; Fetching</h1><h3>&#9989; Increase <code>fetch.min.bytes</code></h3><ul><li><p>Broker waits to accumulate more data before responding<br></p></li><li><p>Improves batching<br></p></li></ul><div><hr></div><h3>&#9989; Increase <code>fetch.max.wait.ms</code></h3><ul><li><p>Wait longer to get larger batches<br></p></li></ul><div><hr></div><h3>&#9989; Tune <code>max.poll.records</code></h3><ul><li><p>More records per poll = better throughput<br></p></li><li><p>But avoid:<br></p><ul><li><p>Long processing &#8594; consumer rebalance<br></p></li></ul></li></ul><div><hr></div><h3>&#9989; Increase <code>receive.buffer.bytes</code></h3><ul><li><p>Helps in high network throughput scenarios<br></p></li></ul><div><hr></div><h1>&#128230; 3. Batch Processing (Critical)</h1><h3>&#9989; Process records in batches</h3><p>Instead of:</p><pre><code>process(record)</code></pre><p>Do:</p><pre><code>process(batch_of_records)</code></pre><p>Benefits:</p><ul><li><p>Better CPU cache usage<br></p></li><li><p>Fewer DB/network calls<br></p></li></ul><div><hr></div><h3>&#9989; Bulk writes (DB optimization)</h3><ul><li><p>Use batch inserts / bulk APIs<br></p></li><li><p>Example:<br></p><ul><li><p>Instead of 1000 DB calls &#8594; 1 bulk write<br></p></li></ul></li></ul><div><hr></div><h1>&#128260; 4. Async &amp; Non-blocking Processing</h1><h3>&#9989; Avoid blocking I/O</h3><ul><li><p>Use async calls (futures, reactive frameworks)<br></p></li></ul><div><hr></div><h3>&#9989; Decouple consumption &amp; processing</h3><ul><li><p>Use internal queue (like Disruptor / BlockingQueue)<br></p></li></ul><div><hr></div><h1>&#129504; 5. Optimize Business Logic</h1><h3>&#9989; Reduce processing time per message</h3><ul><li><p>Cache frequently accessed data (Redis)<br></p></li><li><p>Avoid heavy joins / external calls<br></p></li></ul><div><hr></div><h3>&#9989; Idempotency design</h3><ul><li><p>Enables safe retries without slowing pipeline<br></p></li></ul><div><hr></div><h1>&#128190; 6. Offset Commit Strategy</h1><h3>&#9989; Use async commits</h3><ul><li><p><code>enable.auto.commit=false</code><br></p></li><li><p>Use <code>commitAsync()</code><br></p></li></ul><div><hr></div><h3>&#9989; Commit in batches</h3><ul><li><p>Commit after processing N records<br></p></li></ul><div><hr></div><h1>&#129525; 7. JVM &amp; System Tuning</h1><h3>&#9989; Increase heap size</h3><ul><li><p>Avoid GC pauses<br></p></li></ul><div><hr></div><h3>&#9989; Tune GC</h3><ul><li><p>Use G1GC / ZGC for low latency<br></p></li></ul><div><hr></div><h3>&#9989; CPU scaling</h3><ul><li><p>More cores = more processing threads<br></p></li></ul><div><hr></div><h1>&#128225; 8. Network &amp; Broker-Level Optimizations</h1><h3>&#9989; Compression</h3><ul><li><p>Use <code>snappy</code> or <code>lz4</code><br></p></li><li><p>Reduces network overhead<br></p></li></ul><div><hr></div><h3>&#9989; Co-locate consumers with brokers</h3><ul><li><p>Reduces network latency<br></p></li></ul><div><hr></div><h3>&#9989; Increase broker I/O capacity</h3><ul><li><p>SSDs, better network bandwidth<br></p></li></ul><div><hr></div><h1>&#129514; 9. Avoid Common Bottlenecks</h1><p>&#10060; Frequent rebalances<br><br>&#10060; Long processing inside <code>poll()</code> loop<br><br>&#10060; Synchronous DB/API calls<br><br>&#10060; Too few partitions<br><br>&#10060; Large message size</p><div><hr></div><h1>&#129513; 10. Advanced Patterns (System Design Level)</h1><h3>&#128313; Consumer &#8594; Queue &#8594; Worker Pool</h3><p>Decouple ingestion from processing</p><div><hr></div><h3>&#128313; Kafka &#8594; Stream Processor</h3><p>Use:</p><ul><li><p>Kafka Streams<br></p></li><li><p>Apache Flink<br></p></li></ul><div><hr></div><h3>&#128313; Backpressure handling</h3><ul><li><p>Pause/resume consumption (<code>consumer.pause()</code>)<br></p></li></ul><div><hr></div><h1>&#129504; Mental Model (Important)</h1><p>Throughput =<br><br>&#128073; <strong>min(fetch speed, processing speed, commit speed)</strong></p><p>You must optimize <strong>all three</strong>, not just one.</p><div><hr></div><h1>&#128161; Practical Strategy (What I&#8217;d do in real system)</h1><ol><li><p>Increase partitions (if low)<br></p></li><li><p>Add consumers horizontally<br></p></li><li><p>Introduce batch processing + bulk DB writes<br></p></li><li><p>Decouple poll &amp; processing (thread pool)<br></p></li><li><p>Tune fetch configs<br></p></li><li><p>Add caching layer<br></p></li><li><p>Monitor lag + rebalance frequency<br></p></li></ol><div><hr></div><p>Great&#8212;let&#8217;s walk through a <strong>real-world Kafka throughput optimization case</strong> using a <strong>Payments / Ledger system</strong> (very relevant to your fintech + system design work).</p><div><hr></div><h1>&#128179; Problem Context (Real System)</h1><p>You&#8217;re building something like a <strong>UPI / wallet system</strong>:</p><h3>Flow:</h3><pre><code>Payment Service &#8594; Kafka &#8594; Ledger Service (consumer)</code></pre><p>Each payment event must:</p><ol><li><p>Validate transaction<br></p></li><li><p>Update user balance<br></p></li><li><p>Write ledger entry<br></p></li><li><p>Emit downstream event<br></p></li></ol><div><hr></div><h1>&#128680; Initial Problem</h1><p>At scale:</p><ul><li><p>50M+ events/day<br></p></li><li><p>Consumers lagging<br></p></li><li><p>High latency (seconds &#8594; minutes)<br></p></li><li><p>DB becoming bottleneck<br></p></li></ul><div><hr></div><h1>&#128269; Root Causes (Typical)</h1><h3>&#10060; Single-threaded consumption</h3><ul><li><p>One message processed at a time<br></p></li></ul><h3>&#10060; Per-message DB writes</h3><ul><li><p>1 Kafka message &#8594; 3 DB queries<br></p></li></ul><h3>&#10060; Synchronous external calls</h3><ul><li><p>Fraud check / user lookup<br></p></li></ul><h3>&#10060; Small batches</h3><ul><li><p><code>max.poll.records = 10</code><br></p></li></ul><div><hr></div><h1>&#9881;&#65039; Step-by-Step Throughput Optimization</h1><div><hr></div><h2>&#129525; Step 1: Increase Parallelism</h2><h3>Before:</h3><pre><code>8 partitions &#8594; 2 consumers</code></pre><h3>After:</h3><pre><code>32 partitions &#8594; 8 consumers</code></pre><p>&#128073; Immediate 4x throughput gain</p><div><hr></div><h2>&#128230; Step 2: Batch Processing (Game Changer)</h2><h3>Before:</h3><pre><code>for (record : records) {
    process(record);
}</code></pre><h3>After:</h3><pre><code>processBatch(records);</code></pre><h3>Inside batch:</h3><ul><li><p>Group by user_id<br></p></li><li><p>Aggregate updates<br></p></li></ul><div><hr></div><h3>&#128165; Optimization:</h3><p>Instead of:</p><pre><code>1000 messages &#8594; 3000 DB queries</code></pre><p>Do:</p><pre><code>1000 messages &#8594; 50 bulk DB writes</code></pre><p>&#128073; Massive DB load reduction</p><div><hr></div><h2>&#128260; Step 3: Async Processing Pipeline</h2><h3>Introduce internal pipeline:</h3><pre><code>Kafka Poll Thread
        &#8595;
   In-Memory Queue
        &#8595;
 Worker Thread Pool
        &#8595;
 Batch Aggregator
        &#8595;
 DB Writer</code></pre><h3>Why this works:</h3><ul><li><p>Polling stays fast (avoids rebalance)<br></p></li><li><p>Processing scales independently<br></p></li></ul><div><hr></div><h2>&#9889; Step 4: Async I/O + Parallel Calls</h2><h3>Before:</h3><pre><code>fraudCheck();
dbWrite();
eventPublish();</code></pre><h3>After:</h3><pre><code>CompletableFuture.allOf(
    fraudCheckAsync(),
    dbWriteAsync(),
    publishAsync()
);</code></pre><p>&#128073; CPU + I/O parallelism unlocked</p><div><hr></div><h2>&#129504; Step 5: Smart Caching</h2><p>Use:</p><ul><li><p>Redis<br></p></li></ul><p>Cache:</p><ul><li><p>User metadata<br></p></li><li><p>Account status<br></p></li><li><p>Limits<br></p></li></ul><p>&#128073; Avoid repeated DB hits</p><div><hr></div><h2>&#129534; Step 6: Offset Commit Optimization</h2><h3>Before:</h3><ul><li><p>Commit after every message &#10060;<br></p></li></ul><h3>After:</h3><ul><li><p>Commit after batch (e.g., 1000 records)<br></p></li><li><p>Use async commit<br></p></li></ul><pre><code>consumer.commitAsync();</code></pre><p>&#128073; Reduces commit overhead significantly</p><div><hr></div><h2>&#128225; Step 7: Kafka Config Tuning</h2><pre><code>fetch.min.bytes=1MB
fetch.max.wait.ms=50
max.poll.records=1000</code></pre><p>&#128073; Larger batches &#8594; higher throughput</p><div><hr></div><h2>&#128190; Step 8: Idempotent Ledger Design</h2><p>Critical for fintech &#9888;&#65039;</p><h3>Use:</h3><ul><li><p>Transaction ID as unique key<br></p></li><li><p>Upsert instead of insert<br></p></li></ul><p>&#128073; Enables:</p><ul><li><p>Safe retries<br></p></li><li><p>Parallel processing<br></p></li></ul><div><hr></div><h2>&#128293; Step 9: Partitioning Strategy</h2><p>Partition by:</p><pre><code>user_id</code></pre><p>&#128073; Ensures:</p><ul><li><p>Ordering per user<br></p></li><li><p>Parallelism across users<br></p></li></ul><div><hr></div><h2>&#128202; Final Architecture</h2><pre><code>                &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
                &#9474;  Kafka Topic &#9474;
                &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                       &#8595;
              &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
              &#9474; Consumer Group  &#9474;
              &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                     &#8595;
            &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
            &#9474; Polling Thread   &#9474;
            &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                   &#8595;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474; In-Memory Queue      &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
               &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Worker Thread Pool         &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
            &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Batch Aggregator           &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
            &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Bulk DB Writer (Ledger DB) &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
            &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Event Publisher (Kafka)    &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;</code></pre><div><hr></div><h1>&#128200; Real Impact (Typical Gains)</h1><p>OptimizationGainPartition scaling3&#8211;5xBatch processing10&#8211;50xAsync pipeline2&#8211;3xCaching2&#8211;10xConfig tuning20&#8211;30%</p><p>&#128073; Combined: <strong>10x&#8211;100x throughput improvement</strong></p><div><hr></div><h1>&#9888;&#65039; Trade-offs (Important)</h1><h3>&#128312; Larger batches</h3><ul><li></li></ul><ul><li><p>throughput<br></p></li></ul><ul><li><p>&#8211; higher latency<br></p></li></ul><div><hr></div><h3>&#128312; More partitions</h3><ul><li></li></ul><ul><li><p>parallelism<br></p></li></ul><ul><li><p>&#8211; harder rebalancing<br></p></li></ul><div><hr></div><h3>&#128312; Async processing</h3><ul><li></li></ul><ul><li><p>speed<br></p></li></ul><ul><li><p>&#8211; complexity (ordering, retries)<br></p></li></ul><div><hr></div><h1>&#129504; Key Insight (What Interviewers Love)</h1><blockquote><p>Kafka is rarely the bottleneck.<br><br><strong>Your downstream system (DB / processing) is.</strong></p></blockquote><p>So:<br><br>&#128073; Optimize <strong>end-to-end pipeline</strong>, not just Kafka configs.</p><div><hr></div><h1>&#128260; What Problem Are We Solving?</h1><h3>&#10060; Naive consumer:</h3><pre><code>while (true) {
    records = consumer.poll();
    for (record : records) {
        process(record); // blocking
    }
}</code></pre><h3>Issues:</h3><ul><li><p>Poll thread is blocked &#8594; triggers <strong>rebalance</strong><br></p></li><li><p>No parallelism<br></p></li><li><p>Low CPU utilization<br></p></li><li><p>Throughput tightly coupled to processing speed<br></p></li></ul><div><hr></div><h1>&#128640; Goal of Async Pipeline</h1><p>&#128073; <strong>Decouple ingestion from processing</strong></p><p>So:</p><ul><li><p>Kafka polling stays fast &#9989;<br></p></li><li><p>Processing scales independently &#9989;<br></p></li><li><p>System absorbs spikes (buffering) &#9989;<br></p></li></ul><div><hr></div><h1>&#129513; Core Architecture</h1><pre><code>Kafka &#8594; Poll Thread &#8594; Queue &#8594; Worker Pool &#8594; Batch &#8594; DB</code></pre><p>Let&#8217;s break each component &#128071;</p><div><hr></div><h1>1&#65039;&#8419; Poll Thread (Fast + Non-blocking)</h1><h3>Responsibilities:</h3><ul><li><p>Only <strong>poll Kafka</strong><br></p></li><li><p>Push records to internal queue<br></p></li><li><p>Never block on processing<br></p></li></ul><pre><code>while (true) {
    ConsumerRecords&lt;K, V&gt; records = consumer.poll(Duration.ofMillis(100));
    
    for (ConsumerRecord record : records) {
        queue.put(record); // fast enqueue
    }
}</code></pre><h3>&#9888;&#65039; Key Rule:</h3><p>&#128073; Keep <code>poll()</code> loop <strong>lightweight</strong></p><p>If you block here:</p><ul><li><p>Kafka thinks consumer is dead<br></p></li><li><p>Rebalance happens &#8594; throughput drops<br></p></li></ul><div><hr></div><h1>2&#65039;&#8419; In-Memory Queue (Buffer Layer)</h1><p>Use:</p><ul><li><p><code>BlockingQueue</code><br></p></li><li><p>Disruptor (low latency)<br></p></li></ul><h3>Why this matters:</h3><ul><li><p>Smooths traffic spikes<br></p></li><li><p>Decouples Kafka speed from processing speed<br></p></li></ul><div><hr></div><h3>Backpressure (VERY IMPORTANT)</h3><p>If queue is full:</p><pre><code>queue.put(record); // blocks OR</code></pre><p>Better:</p><pre><code>if (!queue.offer(record)) {
    consumer.pause(partitions);
}</code></pre><p>Resume later:</p><pre><code>consumer.resume(partitions);</code></pre><p>&#128073; Prevents system overload instead of crashing</p><div><hr></div><h1>3&#65039;&#8419; Worker Thread Pool (Parallel Processing)</h1><pre><code>ExecutorService pool = Executors.newFixedThreadPool(N);

while (true) {
    Record record = queue.take();
    
    pool.submit(() -&gt; process(record));
}</code></pre><h3>Benefits:</h3><ul><li><p>Utilizes multi-core CPUs<br></p></li><li><p>Parallel I/O (DB, APIs)<br></p></li></ul><div><hr></div><h3>&#9888;&#65039; Ordering Problem</h3><p>Kafka guarantees:<br><br>&#128073; Order <strong>within a partition</strong></p><p>But with threads:<br><br>&#10060; Order can break</p><div><hr></div><h3>&#9989; Solution: Partition-aware processing</h3><pre><code>Partition 0 &#8594; Thread 1
Partition 1 &#8594; Thread 2</code></pre><p>OR:</p><ul><li><p>Use <strong>key-based routing</strong><br></p></li><li><p>Same key &#8594; same worker<br></p></li></ul><div><hr></div><h1>4&#65039;&#8419; Batch Aggregator (Throughput Booster)</h1><p>Instead of processing one-by-one:</p><pre><code>List&lt;Record&gt; batch = new ArrayList&lt;&gt;();

queue.drainTo(batch, 1000);
processBatch(batch);</code></pre><h3>Why:</h3><ul><li><p>Reduces DB calls<br></p></li><li><p>Improves cache locality<br></p></li><li><p>Enables bulk writes<br></p></li></ul><div><hr></div><h1>5&#65039;&#8419; DB Writer (Bulk + Async)</h1><pre><code>INSERT INTO ledger VALUES (...), (...), (...);</code></pre><p>Instead of:</p><pre><code>INSERT INTO ledger VALUES (...); // 1000 times &#10060;</code></pre><div><hr></div><h1>&#128257; Offset Commit Strategy (Critical)</h1><p>You must ensure:<br><br>&#128073; <strong>Process &#8594; then commit</strong></p><div><hr></div><h3>&#10060; Wrong:</h3><pre><code>poll &#8594; commit &#8594; process</code></pre><h3>&#9989; Correct:</h3><pre><code>poll &#8594; enqueue &#8594; process &#8594; commit</code></pre><div><hr></div><h3>Batch commit example:</h3><pre><code>if (processedCount &gt;= 1000) {
    consumer.commitAsync();
}</code></pre><div><hr></div><h1>&#9888;&#65039; Failure Handling (Real-world complexity)</h1><div><hr></div><h2>Case 1: Worker crashes</h2><p>&#128073; Message not committed &#8594; reprocessed</p><p>&#10004;&#65039; Requires <strong>idempotency</strong></p><div><hr></div><h2>Case 2: Partial batch failure</h2><h3>Strategy:</h3><ul><li><p>Retry failed records<br></p></li><li><p>Send to DLQ (dead letter queue)<br></p></li></ul><div><hr></div><h2>DLQ pattern:</h2><pre><code>Kafka Topic &#8594; Consumer &#8594; Failure &#8594; DLQ Topic</code></pre><div><hr></div><h1>&#128202; Threading Model (Clean Design)</h1><pre><code>            &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
            &#9474; Poll Thread  &#9474;
            &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
                   &#8595;
        &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
        &#9474; Blocking Queue       &#9474;
        &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
               &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Worker Thread Pool (N)   &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
            &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; Batch Processor          &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
            &#8595;
     &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
     &#9474; DB / External Services   &#9474;
     &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;</code></pre><div><hr></div><h1>&#9889; Performance Gains (Why this works)</h1><p>ComponentGainDecouplingNo poll blockingThread poolCPU parallelismQueueBurst handlingBatchFewer DB ops</p><p>&#128073; Combined: <strong>5x&#8211;20x improvement</strong></p><div><hr></div><h1>&#129504; Advanced Enhancements (Senior-level insights)</h1><div><hr></div><h2>&#128313; Adaptive thread pool</h2><ul><li><p>Increase threads during high lag<br></p></li><li><p>Reduce during idle<br></p></li></ul><div><hr></div><h2>&#128313; Dynamic batching</h2><ul><li><p>Batch size based on:<br></p><ul><li><p>queue size<br></p></li><li><p>lag<br></p></li></ul></li></ul><div><hr></div><h2>&#128313; Priority queues</h2><ul><li><p>High-priority events processed first<br></p></li></ul><div><hr></div><h2>&#128313; Zero-copy processing</h2><ul><li><p>Avoid unnecessary serialization/deserialization<br></p></li></ul><div><hr></div><h1>&#128161; Key Insight (Interview Gold)</h1><blockquote><p>Kafka consumer is NOT just a loop.<br><br>It is a <strong>mini stream processing system</strong>.</p></blockquote><p>You are essentially building:<br><br>&#128073; A lightweight version of</p><ul><li><p>Kafka Streams<br></p></li><li><p>Apache Flink<br></p></li></ul><div><hr></div><h1>&#128282; Final Takeaway</h1><p>To maximize throughput:<br><br>&#128073; <strong>Keep polling fast, push work downstream, and process in parallel batches</strong></p><div><hr></div><h1>&#129513; High-Level Components</h1><pre><code>KafkaConsumerService
 &#9500;&#9472;&#9472; Poller Thread
 &#9500;&#9472;&#9472; Blocking Queue
 &#9500;&#9472;&#9472; Worker Pool
 &#9500;&#9472;&#9472; Batch Processor
 &#9500;&#9472;&#9472; Offset Manager
 &#9492;&#9472;&#9472; DLQ Producer</code></pre><div><hr></div><h1>&#127959;&#65039; 1. Core Consumer Service</h1><pre><code>public class KafkaConsumerService {

    private final KafkaConsumer&lt;String, String&gt; consumer;
    private final BlockingQueue&lt;ConsumerRecord&lt;String, String&gt;&gt; queue;
    private final ExecutorService workerPool;
    private final BatchProcessor batchProcessor;
    private final OffsetManager offsetManager;

    public KafkaConsumerService(Properties props, int workerThreads, int queueSize) {
        this.consumer = new KafkaConsumer&lt;&gt;(props);
        this.queue = new ArrayBlockingQueue&lt;&gt;(queueSize);
        this.workerPool = Executors.newFixedThreadPool(workerThreads);
        this.batchProcessor = new BatchProcessor(offsetManager);
        this.offsetManager = new OffsetManager(consumer);
    }

    public void start() {
        consumer.subscribe(List.of(&#8221;payments-topic&#8221;));

        // Start worker threads
        for (int i = 0; i &lt; 8; i++) {
            workerPool.submit(new Worker(queue, batchProcessor));
        }

        // Start polling loop
        poll();
    }

    private void poll() {
        while (true) {
            ConsumerRecords&lt;String, String&gt; records = consumer.poll(Duration.ofMillis(100));

            for (ConsumerRecord&lt;String, String&gt; record : records) {
                boolean added = queue.offer(record);

                if (!added) {
                    // Backpressure: pause consumption
                    consumer.pause(consumer.assignment());
                    break;
                }
            }

            // Resume if queue has capacity
            if (queue.remainingCapacity() &gt; 100) {
                consumer.resume(consumer.assignment());
            }
        }
    }
}</code></pre><div><hr></div><h1>&#129525; 2. Worker Thread</h1><pre><code>public class Worker implements Runnable {

    private final BlockingQueue&lt;ConsumerRecord&lt;String, String&gt;&gt; queue;
    private final BatchProcessor batchProcessor;

    public Worker(BlockingQueue&lt;ConsumerRecord&lt;String, String&gt;&gt; queue,
                  BatchProcessor batchProcessor) {
        this.queue = queue;
        this.batchProcessor = batchProcessor;
    }

    @Override
    public void run() {
        List&lt;ConsumerRecord&lt;String, String&gt;&gt; batch = new ArrayList&lt;&gt;();

        while (true) {
            try {
                ConsumerRecord&lt;String, String&gt; record = queue.poll(100, TimeUnit.MILLISECONDS);

                if (record != null) {
                    batch.add(record);
                }

                if (batch.size() &gt;= 500) {
                    batchProcessor.process(batch);
                    batch.clear();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}</code></pre><div><hr></div><h1>&#128230; 3. Batch Processor</h1><pre><code>public class BatchProcessor {

    private final OffsetManager offsetManager;
    private final LedgerRepository repository = new LedgerRepository();

    public BatchProcessor(OffsetManager offsetManager) {
        this.offsetManager = offsetManager;
    }

    public void process(List&lt;ConsumerRecord&lt;String, String&gt;&gt; records) {
        try {
            // Transform records
            List&lt;LedgerEntry&gt; entries = transform(records);

            // Bulk DB write
            repository.bulkInsert(entries);

            // Mark offsets processed
            offsetManager.markProcessed(records);

        } catch (Exception e) {
            // Send failed batch to DLQ
            sendToDLQ(records);
        }
    }

    private List&lt;LedgerEntry&gt; transform(List&lt;ConsumerRecord&lt;String, String&gt;&gt; records) {
        // Map JSON &#8594; Object
        return records.stream()
                .map(r -&gt; new LedgerEntry(r.value()))
                .toList();
    }

    private void sendToDLQ(List&lt;ConsumerRecord&lt;String, String&gt;&gt; records) {
        // Produce to DLQ topic
    }
}</code></pre><div><hr></div><h1>&#129534; 4. Offset Manager (VERY IMPORTANT)</h1><pre><code>public class OffsetManager {

    private final KafkaConsumer&lt;String, String&gt; consumer;
    private final Map&lt;TopicPartition, OffsetAndMetadata&gt; offsets = new ConcurrentHashMap&lt;&gt;();

    public OffsetManager(KafkaConsumer&lt;String, String&gt; consumer) {
        this.consumer = consumer;
    }

    public synchronized void markProcessed(List&lt;ConsumerRecord&lt;String, String&gt;&gt; records) {
        for (ConsumerRecord&lt;String, String&gt; record : records) {
            TopicPartition tp = new TopicPartition(record.topic(), record.partition());

            offsets.put(tp, new OffsetAndMetadata(record.offset() + 1));
        }

        // Commit asynchronously
        consumer.commitAsync(offsets, (map, ex) -&gt; {
            if (ex != null) {
                System.err.println(&#8221;Commit failed: &#8220; + ex.getMessage());
            }
        });
    }
}</code></pre><div><hr></div><h1>&#128190; 5. Repository (Bulk Writes)</h1><pre><code>public class LedgerRepository {

    public void bulkInsert(List&lt;LedgerEntry&gt; entries) {
        // Example: JDBC batch insert

        String sql = &#8220;INSERT INTO ledger (id, amount, user_id) VALUES (?, ?, ?)&#8221;;

        try (Connection conn = dataSource.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            for (LedgerEntry entry : entries) {
                stmt.setString(1, entry.getId());
                stmt.setDouble(2, entry.getAmount());
                stmt.setString(3, entry.getUserId());
                stmt.addBatch();
            }

            stmt.executeBatch();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}</code></pre><div><hr></div><h1>&#9888;&#65039; Production-Grade Improvements</h1><div><hr></div><h2>&#128313; 1. Partition-aware workers</h2><ul><li><p>Ensure ordering per partition<br></p></li><li><p>Use:<br></p></li></ul><pre><code>partition &#8594; dedicated queue &#8594; worker</code></pre><div><hr></div><h2>&#128313; 2. Idempotency layer</h2><ul><li><p>Use unique transaction_id<br></p></li><li><p>DB constraint:<br></p></li></ul><pre><code>UNIQUE(transaction_id)</code></pre><div><hr></div><h2>&#128313; 3. DLQ integration</h2><ul><li><p>Separate Kafka topic:<br></p></li></ul><pre><code>payments-dlq-topic</code></pre><div><hr></div><h2>&#128313; 4. Metrics (CRITICAL)</h2><p>Track:</p><ul><li><p>Consumer lag<br></p></li><li><p>Queue size<br></p></li><li><p>Processing latency<br></p></li><li><p>Batch size<br></p></li></ul><p>Use:</p><ul><li><p>Prometheus<br></p></li><li><p>Grafana<br></p></li></ul><div><hr></div><h2>&#128313; 5. Graceful shutdown</h2><pre><code>Runtime.getRuntime().addShutdownHook(new Thread(() -&gt; {
    workerPool.shutdown();
    consumer.close();
}));</code></pre><div><hr></div><h1>&#129504; Final Mental Model</h1><p>This system is:</p><p>&#128073; <strong>Kafka Consumer + Internal Stream Processor</strong></p><p>Similar to:</p><ul><li><p>Kafka Streams<br></p></li><li><p>Apache Flink<br></p></li></ul><p>&#8230;but custom-built for:</p><ul><li><p>Lower latency<br></p></li><li><p>Full control<br></p></li><li><p>Simpler infra<br></p></li></ul><div><hr></div><h1>&#128640; What Makes This &#8220;Senior-Level&#8221;</h1><ul><li><p>Decoupled ingestion vs processing<br></p></li><li><p>Backpressure handling (<code>pause/resume</code>)<br></p></li><li><p>Batch + bulk DB writes<br></p></li><li><p>Async offset commits<br></p></li><li><p>Failure isolation (DLQ)<br></p></li><li><p>Extensible for retries, idempotency<br></p></li></ul><div><hr></div><p><br><br><br></p>]]></content:encoded></item><item><title><![CDATA[Design a complete architecture of a error report system for an ecommerce app.]]></title><description><![CDATA[When a user receives an irrelevant search result and clicks &#8216;Not Relevant,&#8217; an issue is raised, assigned to technical support, and the support team can then view the detailed error report along with relevant log]]></description><link>https://programmingappliedai.substack.com/p/design-a-complete-architecture-of</link><guid isPermaLink="false">https://programmingappliedai.substack.com/p/design-a-complete-architecture-of</guid><dc:creator><![CDATA[Shashank Mishra]]></dc:creator><pubDate>Sat, 21 Mar 2026 06:14:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!riGX!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F58e132e8-cd28-4037-b0ef-feabb2b68221_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When a user receives an irrelevant search result and clicks &#8216;Not Relevant,&#8217; an issue is raised, assigned to technical support, and the support team can then view the detailed error report along with relevant log<br><br><strong>Functional Requirements</strong> </p><ol><li><p><strong>Capture User Feedback</strong></p><ul><li><p>Allow users to mark search results as <em>&#8220;Not Relevant.&#8221;</em></p></li></ul></li><li><p><strong>Collect Request Context</strong></p><ul><li><p>Store query, filters, timestamp, user/session ID, and device metadata.</p></li></ul></li><li><p><strong>Create Issue Automatically</strong></p><ul><li><p>Generate a ticket whenever feedback is submitted.</p></li></ul></li><li><p><strong>Attach Relevant Logs</strong></p><ul><li><p>Fetch and link search/query/ranking logs for the request.</p></li></ul></li><li><p><strong>Categorize Issue</strong></p><ul><li><p>Classify into types like relevance issue, ranking issue, or data issue.</p></li></ul></li><li><p><strong>Deduplicate Issues</strong></p><ul><li><p>Group similar reports to avoid duplicate tickets.</p></li></ul></li><li><p><strong>Assign Priority</strong></p><ul><li><p>Set severity based on frequency and business impact.</p></li></ul></li><li><p><strong>Auto-Assign to Team</strong></p><ul><li><p>Route issue to the appropriate team (search, backend, infra).</p></li></ul></li><li><p><strong>Provide Support Dashboard</strong></p><ul><li><p>Enable viewing, filtering, and tracking of issues and logs.</p></li></ul></li><li><p><strong>Manage Issue Lifecycle</strong></p></li></ol><ul><li><p>Support states like Open &#8594; In Progress &#8594; Resolved &#8594; Closed.</p></li></ul><p></p><p><strong> Non-Functional Requirements (NFRs)</strong> </p><ol><li><p><strong>Scalability</strong></p><ul><li><p>System should handle high volumes of user feedback events (e.g., millions/day) without degradation.</p></li></ul></li><li><p><strong>Low Latency</strong></p><ul><li><p>Issue creation and logging should happen near real-time (within a few seconds of user action).</p></li></ul></li><li><p><strong>High Availability</strong></p><ul><li><p>System should be highly available (&#8805;99.9%) to ensure continuous error reporting and tracking.</p></li></ul></li><li><p><strong>Reliability &amp; Durability</strong></p><ul><li><p>No loss of feedback data; all events and logs must be reliably stored (using durable queues/storage).</p></li></ul></li><li><p><strong>Fault Tolerance</strong></p><ul><li><p>System should gracefully handle failures (e.g., retry mechanisms, dead-letter queues).</p></li></ul></li><li><p><strong>Security &amp; Privacy</strong></p><ul><li><p>Sensitive user data must be masked/encrypted and comply with data protection standards.</p></li></ul></li></ol><p><strong>API&#8217;s </strong></p><h1><strong>1. Submit Feedback (User &#8594; System)</strong></h1><h3><strong>POST /feedback</strong></h3><pre><code>Request:
{
  &#8220;userId&#8221;: &#8220;12345&#8221;,
  &#8220;sessionId&#8221;: &#8220;sess-789&#8221;,
  &#8220;query&#8221;: &#8220;iphone 14&#8221;,
  &#8220;filters&#8221;: {
    &#8220;priceRange&#8221;: &#8220;50000-80000&#8221;,
    &#8220;brand&#8221;: &#8220;Apple&#8221;
  },
  &#8220;resultIds&#8221;: [&#8221;p1&#8221;, &#8220;p2&#8221;, &#8220;p3&#8221;],
  &#8220;action&#8221;: &#8220;NOT_RELEVANT&#8221;,
  &#8220;timestamp&#8221;: 1710000000
}</code></pre><pre><code>Response:
{
  &#8220;status&#8221;: &#8220;SUCCESS&#8221;,
  &#8220;issueId&#8221;: &#8220;ISSUE-1001&#8221;,
  &#8220;message&#8221;: &#8220;Feedback recorded and issue created&#8221;
}</code></pre><div><hr></div><h1><strong>2. Get Issue Details (Support Dashboard)</strong></h1><h3><strong>GET /issues/{issueId}</strong></h3><pre><code>Response:
{
  &#8220;issueId&#8221;: &#8220;ISSUE-1001&#8221;,
  &#8220;query&#8221;: &#8220;iphone 14&#8221;,
  &#8220;category&#8221;: &#8220;SEARCH_RELEVANCE&#8221;,
  &#8220;priority&#8221;: &#8220;HIGH&#8221;,
  &#8220;status&#8221;: &#8220;OPEN&#8221;,
  &#8220;createdAt&#8221;: 1710000000,
  &#8220;assignedTo&#8221;: &#8220;search-team&#8221;,
  &#8220;logs&#8221;: [
    {
      &#8220;service&#8221;: &#8220;search-service&#8221;,
      &#8220;logId&#8221;: &#8220;log-123&#8221;,
      &#8220;traceId&#8221;: &#8220;trace-xyz&#8221;
    }
  ]
}</code></pre><div><hr></div><h1><strong>3. Search / Filter Issues</strong></h1><h3><strong>GET /issues?status=OPEN&amp;priority=HIGH&amp;query=iphone</strong></h3><pre><code>Response:
{
  &#8220;issues&#8221;: [
    {
      &#8220;issueId&#8221;: &#8220;ISSUE-1001&#8221;,
      &#8220;query&#8221;: &#8220;iphone 14&#8221;,
      &#8220;priority&#8221;: &#8220;HIGH&#8221;,
      &#8220;status&#8221;: &#8220;OPEN&#8221;,
      &#8220;count&#8221;: 120
    }
  ]
}</code></pre><div><hr></div><h1><strong>4. Update Issue Status</strong></h1><h3><strong>PATCH /issues/{issueId}</strong></h3><pre><code>Request:
{
  &#8220;status&#8221;: &#8220;IN_PROGRESS&#8221;,
  &#8220;assignedTo&#8221;: &#8220;engineer-123&#8221;
}</code></pre><pre><code>Response:
{
  &#8220;status&#8221;: &#8220;SUCCESS&#8221;,
  &#8220;message&#8221;: &#8220;Issue updated successfully&#8221;
}</code></pre><div><hr></div><h1><strong>5. Get Logs for an Issue</strong></h1><h3><strong>GET /issues/{issueId}/logs</strong></h3><pre><code>Response:
{
  &#8220;issueId&#8221;: &#8220;ISSUE-1001&#8221;,
  &#8220;logs&#8221;: [
    {
      &#8220;timestamp&#8221;: 1710000000,
      &#8220;service&#8221;: &#8220;ranking-service&#8221;,
      &#8220;message&#8221;: &#8220;Ranking mismatch detected&#8221;,
      &#8220;traceId&#8221;: &#8220;trace-xyz&#8221;
    }
  ]
}</code></pre><div><hr></div><h1><strong>6. Get Aggregated Metrics (Impact Analysis)</strong></h1><h3><strong>GET /issues/{issueId}/metrics</strong></h3><pre><code>Response:
{
  &#8220;issueId&#8221;: &#8220;ISSUE-1001&#8221;,
  &#8220;affectedUsers&#8221;: 1200,
  &#8220;occurrences&#8221;: 3500,
  &#8220;firstSeen&#8221;: 1709990000,
  &#8220;lastSeen&#8221;: 1710005000
}</code></pre><div><hr></div><h1><strong>7. Manual Reassignment (Admin/Support)</strong></h1><h3><strong>POST /issues/{issueId}/assign</strong></h3><pre><code>Request:
{
  &#8220;assignedTo&#8221;: &#8220;search-team&#8221;
}</code></pre><pre><code>Response:
{
  &#8220;status&#8221;: &#8220;SUCCESS&#8221;,
  &#8220;message&#8221;: &#8220;Issue reassigned&#8221;
}</code></pre><div><hr></div><p><strong><br>Databases and Schema</strong></p><h1><strong>Types of Databases to Use</strong></h1><h3><strong>1. OLTP DB (Primary Issue Store)</strong></h3><ul><li><p><strong>Type</strong>: Relational DB (e.g., PostgreSQL / MySQL)</p></li><li><p><strong>Why</strong>:</p><ul><li><p>Strong consistency for issue lifecycle</p></li><li><p>Supports queries like filtering, status updates, joins</p></li></ul></li></ul><div><hr></div><h3><strong>2. Log Storage / Observability</strong></h3><ul><li><p><strong>Type</strong>: Search + log store (e.g., Elasticsearch)</p></li><li><p><strong>Why</strong>:</p><ul><li><p>Full-text search on logs</p></li><li><p>Fast filtering using traceId, service, timestamp</p></li></ul></li></ul><div><hr></div><h3><strong>3. Event Stream (Ingestion Pipeline)</strong></h3><ul><li><p><strong>Type</strong>: Distributed log (e.g., Apache Kafka)</p></li><li><p><strong>Why</strong>:</p><ul><li><p>Decouple user request from processing</p></li><li><p>Handle high throughput reliably</p></li></ul></li></ul><div><hr></div><h3><strong>4. Analytics / Aggregation DB</strong></h3><ul><li><p><strong>Type</strong>: Columnar DB (e.g., ClickHouse / BigQuery)</p></li><li><p><strong>Why</strong>:</p><ul><li><p>Compute metrics (affected users, frequency)</p></li><li><p>Efficient aggregation queries</p></li></ul></li></ul><div><hr></div><h3><strong>5. Cache Layer</strong></h3><ul><li><p><strong>Type</strong>: In-memory store (e.g., Redis)</p></li><li><p><strong>Why</strong>:</p><ul><li><p>Cache hot issues, dashboards</p></li><li><p>Speed up frequent queries</p></li></ul></li></ul><div><hr></div><h1>&#129513; <strong>Schema Design</strong></h1><div><hr></div><h2><strong>1. Issues Table (PostgreSQL)</strong></h2><pre><code>CREATE TABLE issues (
    issue_id VARCHAR PRIMARY KEY,
    query TEXT,
    category VARCHAR,
    priority VARCHAR,
    status VARCHAR,
    assigned_team VARCHAR,
    created_at TIMESTAMP,
    updated_at TIMESTAMP,
    dedupe_key VARCHAR,
    occurrence_count INT DEFAULT 1
);</code></pre><div><hr></div><h2><strong>2. Feedback Events Table (Optional - OLTP / Kafka Sink)</strong></h2><pre><code>CREATE TABLE feedback_events (
    event_id VARCHAR PRIMARY KEY,
    user_id VARCHAR,
    session_id VARCHAR,
    query TEXT,
    filters JSONB,
    result_ids TEXT[],
    action VARCHAR,
    timestamp TIMESTAMP,
    trace_id VARCHAR
);</code></pre><div><hr></div><h2><strong>3. Logs Index (Elasticsearch)</strong></h2><pre><code>{
  &#8220;traceId&#8221;: &#8220;trace-xyz&#8221;,
  &#8220;service&#8221;: &#8220;search-service&#8221;,
  &#8220;timestamp&#8221;: &#8220;2026-03-21T10:00:00Z&#8221;,
  &#8220;level&#8221;: &#8220;ERROR&#8221;,
  &#8220;message&#8221;: &#8220;Ranking mismatch&#8221;,
  &#8220;metadata&#8221;: {
    &#8220;query&#8221;: &#8220;iphone 14&#8221;,
    &#8220;latency&#8221;: 120
  }
}</code></pre><div><hr></div><h2><strong>4. Aggregated Metrics Table (ClickHouse / Analytics DB)</strong></h2><pre><code>CREATE TABLE issue_metrics (
    issue_id String,
    date Date,
    occurrences UInt32,
    affected_users UInt32
) ENGINE = MergeTree()
ORDER BY (issue_id, date);</code></pre><div><hr></div><h2><strong>5. Assignment History Table</strong></h2><pre><code>CREATE TABLE issue_assignments (
    id SERIAL PRIMARY KEY,
    issue_id VARCHAR,
    assigned_to VARCHAR,
    changed_at TIMESTAMP
);</code></pre><div><hr></div><h1>&#128293; <strong>Key Design Insights (Interview Gold)</strong></h1><ul><li><p>Use <strong>Kafka &#8594; consumers &#8594; multiple DBs</strong> (fan-out architecture)<br></p></li><li><p>Use <strong>dedupe_key = hash(query + filters)</strong> for grouping issues<br></p></li><li><p>Logs are <strong>not stored in OLTP DB</strong> &#8594; use Elasticsearch<br></p></li><li><p>Metrics go to <strong>analytics DB, not primary DB</strong><br></p></li><li><p>Keep <strong>issue DB small and query-efficient</strong><br></p></li></ul><div><hr></div><p><strong>Microservies and their interaction</strong></p><p>:</p><div><hr></div><h1>&#129513; <strong>Microservices</strong></h1><h3><strong>1. API Gateway</strong></h3><ul><li><p>Entry point for all client (app/dashboard) requests</p></li><li><p>Handles auth, rate limiting, routing</p></li></ul><div><hr></div><h3><strong>2. Feedback Service</strong></h3><ul><li><p>Receives <em>&#8220;Not Relevant&#8221;</em> clicks</p></li><li><p>Validates request &amp; publishes event to queue</p></li></ul><div><hr></div><h3><strong>3. Event Ingestion Service (Stream Processor)</strong></h3><ul><li><p>Consumes events from queue</p></li><li><p>Performs:</p><ul><li><p>Deduplication</p></li><li><p>Basic enrichment (add traceId, metadata)</p></li></ul></li></ul><div><hr></div><h3><strong>4. Issue Service</strong></h3><ul><li><p>Creates &amp; manages issues</p></li><li><p>Maintains issue lifecycle (OPEN &#8594; CLOSED)</p></li><li><p>Stores in DB (PostgreSQL)</p></li></ul><div><hr></div><h3><strong>5. Log Service</strong></h3><ul><li><p>Fetches logs using traceId</p></li><li><p>Queries log store (Elasticsearch)</p></li><li><p>Attaches logs to issue</p></li></ul><div><hr></div><h3><strong>6. Assignment Service</strong></h3><ul><li><p>Assigns issue to correct team</p></li><li><p>Uses rules (category &#8594; team mapping)</p></li></ul><div><hr></div><h3><strong>7. Notification Service</strong></h3><ul><li><p>Sends alerts (Slack/Email)</p></li><li><p>Triggered on issue creation/update</p></li></ul><div><hr></div><h3><strong>8. Analytics Service</strong></h3><ul><li><p>Aggregates metrics (frequency, affected users)</p></li><li><p>Writes to analytics DB (ClickHouse)</p></li></ul><div><hr></div><h3><strong>9. Dashboard Service</strong></h3><ul><li><p>Used by support/engineers</p></li><li><p>Fetches issues, logs, metrics</p></li></ul><div><hr></div><h1>&#128260; <strong>End-to-End Interaction Flow</strong></h1><h3><strong>Step 1: User Action</strong></h3><ul><li><p>User clicks <em>&#8220;Not Relevant&#8221;</em></p></li><li><p>Request &#8594; <strong>API Gateway &#8594; Feedback Service</strong></p></li></ul><div><hr></div><h3><strong>Step 2: Event Publishing</strong></h3><ul><li><p>Feedback Service &#8594; publishes event to queue<br>(e.g., Apache Kafka topic: <code>feedback-events</code>)</p></li></ul><div><hr></div><h3><strong>Step 3: Event Processing</strong></h3><ul><li><p>Event Ingestion Service consumes event</p></li><li><p>Generates:</p><ul><li><p><code>dedupe_key</code></p></li><li><p><code>traceId</code></p></li></ul></li><li><p>Checks if similar issue exists</p></li></ul><div><hr></div><h3><strong>Step 4: Issue Handling</strong></h3><ul><li><p>If new &#8594; call <strong>Issue Service &#8594; create issue</strong></p></li><li><p>If duplicate &#8594; increment occurrence count</p></li></ul><div><hr></div><h3><strong>Step 5: Log Enrichment</strong></h3><ul><li><p>Issue Service &#8594; calls <strong>Log Service</strong></p></li><li><p>Log Service &#8594; fetch logs from Elasticsearch</p></li><li><p>Attach logs to issue</p></li></ul><div><hr></div><h3><strong>Step 6: Assignment</strong></h3><ul><li><p>Issue Service &#8594; calls <strong>Assignment Service</strong></p></li><li><p>Assign to correct team (search/backend)</p></li></ul><div><hr></div><h3><strong>Step 7: Notification</strong></h3><ul><li><p>Assignment Service &#8594; triggers <strong>Notification Service</strong></p></li><li><p>Notify engineers (Slack/email)</p></li></ul><div><hr></div><h3><strong>Step 8: Analytics Pipeline</strong></h3><ul><li><p>Event also consumed by Analytics Service</p></li><li><p>Stores aggregates in ClickHouse</p></li></ul><div><hr></div><h3><strong>Step 9: Dashboard Usage</strong></h3><ul><li><p>Support team &#8594; Dashboard Service</p></li><li><p>Fetch:</p><ul><li><p>Issues (from PostgreSQL)</p></li><li><p>Logs (via Log Service)</p></li><li><p>Metrics (from analytics DB)</p></li></ul></li></ul><div><hr></div><h1>&#129504; <strong>Key Design Patterns (Important)</strong></h1><ul><li><p><strong>Event-driven architecture (Kafka-based)</strong></p></li><li><p><strong>Fan-out consumers (Issue + Analytics)</strong></p></li><li><p><strong>Async processing &#8594; no user latency impact</strong></p></li><li><p><strong>Separation of concerns (logs, issues, analytics)</strong></p></li></ul><div><hr></div><h1>&#128640; <strong>One-Line Flow</strong></h1><blockquote><p>&#8220;User feedback &#8594; Kafka &#8594; processing &#8594; issue creation &#8594; log enrichment &#8594; assignment &#8594; notification &#8594; analytics &#8594; dashboard.&#8221;</p></blockquote><div><hr></div><p><strong>High-Level Architecture Diagram (Text Form)</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;4e0f34f2-eb79-4d65-a16f-f4589f9e4e4c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">User App
   &#9474;
   &#9660;
API Gateway
   &#9474;
   &#9660;
Feedback Service
   &#9474;
   &#9660;
Kafka (feedback-events topic)
   &#9474;
   &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9658; Event Processor Service
   &#9474;                    &#9474;
   &#9474;                    &#9500;&#9472;&#9472;&#9658; Issue Service &#9472;&#9472;&#9472;&#9658; PostgreSQL (Issues DB)
   &#9474;                    &#9474;         &#9474;
   &#9474;                    &#9474;         &#9500;&#9472;&#9472;&#9658; Log Service &#9472;&#9472;&#9472;&#9658; Elasticsearch (Logs)
   &#9474;                    &#9474;         &#9474;
   &#9474;                    &#9474;         &#9492;&#9472;&#9472;&#9658; Assignment Service
   &#9474;                    &#9474;                      &#9474;
   &#9474;                    &#9474;                      &#9492;&#9472;&#9472;&#9658; Notification Service (Slack/Email)
   &#9474;
   &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9658; Analytics Service &#9472;&#9472;&#9472;&#9658; ClickHouse (Metrics DB)

------------------------------------------------------------

Support Dashboard
   &#9474;
   &#9660;
Dashboard Service
   &#9474;
   &#9500;&#9472;&#9472;&#9658; Issue Service (Issues)
   &#9500;&#9472;&#9472;&#9658; Log Service (Logs)
   &#9492;&#9472;&#9472;&#9658; Analytics Service (Metrics)







</code></pre></div><h1>&#128260; <strong>Step-by-Step Flow (Crisp)</strong></h1><h3><strong>1. User Action</strong></h3><ul><li><p>User clicks <em>&#8220;Not Relevant&#8221;</em></p></li><li><p>Request &#8594; API Gateway &#8594; Feedback Service</p></li></ul><div><hr></div><h3><strong>2. Async Ingestion</strong></h3><ul><li><p>Feedback Service publishes event to<br><strong>Apache Kafka (</strong><code>feedback-events</code><strong>)</strong></p></li></ul><div><hr></div><h3><strong>3. Parallel Processing (Fan-out)</strong></h3><h4><strong>A. Issue Pipeline</strong></h4><ul><li><p>Event Processor:</p><ul><li><p>Generates <code>dedupe_key</code></p></li><li><p>Checks duplicates</p></li></ul></li><li><p>Calls Issue Service:</p><ul><li><p>Create / update issue in DB</p></li></ul></li></ul><div><hr></div><h4><strong>B. Log Enrichment</strong></h4><ul><li><p>Issue Service &#8594; Log Service</p></li><li><p>Fetch logs from<br><strong>Elasticsearch</strong> using <code>traceId</code></p></li></ul><div><hr></div><h4><strong>C. Assignment</strong></h4><ul><li><p>Issue &#8594; Assignment Service</p></li><li><p>Assign team (search/backend)</p></li></ul><div><hr></div><h4><strong>D. Notification</strong></h4><ul><li><p>Trigger Notification Service</p></li><li><p>Send Slack/email alerts</p></li></ul><div><hr></div><h4><strong>E. Analytics Pipeline</strong></h4><ul><li><p>Kafka &#8594; Analytics Service</p></li><li><p>Store metrics in<br><strong>ClickHouse</strong></p></li></ul><div><hr></div><h3><strong>4. Dashboard (Read Path)</strong></h3><ul><li><p>Support &#8594; Dashboard Service</p></li><li><p>Fetch:</p><ul><li><p>Issues &#8594; PostgreSQL</p></li><li><p>Logs &#8594; Elasticsearch</p></li><li><p>Metrics &#8594; ClickHouse</p></li></ul></li></ul><div><hr></div><h1>&#128293; <strong>What Makes This Strong in Interviews</strong></h1><h3>&#9989; Patterns you&#8217;re demonstrating:</h3><ul><li><p>Event-driven architecture</p></li><li><p>Async processing (decoupling user flow)</p></li><li><p>Fan-out consumers</p></li><li><p>Observability (logs + traces + metrics together)</p></li></ul><div><hr></div><h1>&#128161; <strong>Advanced Add-ons (Say this if time permits)</strong></h1><ul><li><p>Use <strong>idempotent consumers</strong> to avoid duplicate issue creation</p></li><li><p>Use <strong>Kafka partitions by query hash</strong> for better ordering</p></li><li><p>Add <strong>DLQ (Dead Letter Queue)</strong> for failed events</p></li><li><p>Use <strong>traceId propagation (OpenTelemetry style)</strong> across services</p></li></ul><div><hr></div><h1>&#128640; One-Line Summary</h1><blockquote><p>&#8220;We decouple feedback ingestion using Kafka, process events asynchronously to create/enrich issues, and provide a unified debugging view via logs, metrics, and issue tracking.&#8221;</p></blockquote><div><hr></div><h1>&#129504; <strong>1. Kafka Topic &amp; Partitioning Strategy</strong></h1><h3><strong>Topic Design</strong></h3><ul><li><p><code>feedback-events</code> &#8594; raw user feedback</p></li><li><p><code>issue-events</code> &#8594; processed (deduped/enriched) events</p></li><li><p><code>notification-events</code> &#8594; downstream notifications</p></li></ul><div><hr></div><h3><strong>Partitioning Key (VERY IMPORTANT)</strong></h3><p>&#128073; Use:</p><pre><code>partition_key = hash(query + filters)</code></pre><h3>Why?</h3><ul><li><p>Ensures <strong>same query &#8594; same partition</strong><br></p></li><li><p>Guarantees <strong>ordering for deduplication</strong><br></p></li><li><p>Avoids cross-partition coordination (huge win)<br></p></li></ul><div><hr></div><h3><strong>Number of Partitions</strong></h3><ul><li><p>Assume: <strong>100M events/day &#8776; ~1150 events/sec</strong><br></p></li><li><p>Safe design: <strong>~2000&#8211;5000 events/sec capacity</strong><br></p></li></ul><p>&#128073; Choose:</p><ul><li><p>~50&#8211;100 partitions<br></p></li></ul><div><hr></div><h3><strong>Consumer Groups</strong></h3><ul><li><p><code>event-processor-group</code><br></p></li><li><p><code>analytics-group</code><br></p></li><li><p><code>notification-group</code><br></p></li></ul><p>&#128073; Enables <strong>fan-out processing</strong></p><div><hr></div><h1>&#128257; <strong>2. Deduplication Strategy (Core Logic)</strong></h1><p>This is where you stand out.</p><div><hr></div><h2><strong>Step 1: Generate Dedupe Key</strong></h2><pre><code>dedupe_key = hash(query + filters + category)</code></pre><div><hr></div><h2><strong>Step 2: Fast Lookup (Redis)</strong></h2><p>Use:</p><ul><li><p>Redis<br></p></li></ul><pre><code>Key: dedupe_key
Value: issue_id
TTL: 24 hours (or configurable)</code></pre><div><hr></div><h2><strong>Step 3: Flow</strong></h2><pre><code>IF dedupe_key exists in Redis:
    &#8594; existing issue
    &#8594; increment occurrence_count
ELSE:
    &#8594; create new issue
    &#8594; store mapping in Redis</code></pre><div><hr></div><h2><strong>Step 4: Persistent Check (Fallback)</strong></h2><ul><li><p>Query DB (PostgreSQL) if cache miss<br></p></li><li><p>Prevents Redis loss issues<br></p></li></ul><div><hr></div><h2>&#128293; Optimization</h2><ul><li><p>Use <strong>Bloom Filter</strong> (optional) to reduce DB hits<br></p></li></ul><div><hr></div><h1>&#128202; <strong>3. Scaling to 100M+ Events/Day</strong></h1><div><hr></div><h2><strong>A. Ingestion Layer</strong></h2><ul><li><p>Kafka handles burst traffic<br></p></li><li><p>Use <strong>batch producers</strong> from Feedback Service<br></p></li></ul><div><hr></div><h2><strong>B. Processing Layer</strong></h2><ul><li><p>Horizontally scale consumers<br></p></li><li><p>Each consumer handles:<br></p><ul><li><p>Partition subset<br></p></li><li><p>Independent processing<br></p></li></ul></li></ul><div><hr></div><h2><strong>C. Storage Strategy</strong></h2><h3>OLTP (Issues DB)</h3><ul><li><p>Shard by:<br></p></li></ul><pre><code>hash(issue_id) OR time-based (monthly partitions)</code></pre><div><hr></div><h3>Logs (Elasticsearch)</h3><ul><li><p>Index by:<br></p></li></ul><pre><code>logs-YYYY-MM-DD</code></pre><div><hr></div><h3>Analytics (ClickHouse)</h3><ul><li><p>Partition by date<br></p></li><li><p>Pre-aggregate data<br></p></li></ul><div><hr></div><h2><strong>D. Backpressure Handling</strong></h2><ul><li><p>Kafka retains events (buffer)<br></p></li><li><p>Consumers lag monitored<br></p></li><li><p>Auto-scale consumers<br></p></li></ul><div><hr></div><h2><strong>E. Failure Handling</strong></h2><ul><li><p>Retry with exponential backoff<br></p></li><li><p>Dead Letter Queue (DLQ) in Kafka<br></p></li></ul><div><hr></div><h1>&#128269; <strong>4. Observability (Senior-Level Touch)</strong></h1><p>Use:</p><ul><li><p>Distributed tracing (traceId propagation)<br></p></li><li><p>Metrics:<br></p><ul><li><p>event lag<br></p></li><li><p>issue creation rate<br></p></li><li><p>duplicate ratio<br></p></li></ul></li></ul><div><hr></div><h1>&#129302; <strong>5. Smart Enhancements (Very Impressive)</strong></h1><h3><strong>A. Auto Prioritization</strong></h3><ul><li><p>High frequency &#8594; auto HIGH priority<br></p></li></ul><div><hr></div><h3><strong>B. ML-based Relevance Detection</strong></h3><ul><li><p>Combine:<br></p><ul><li><p>CTR drop<br></p></li><li><p>high &#8220;Not Relevant&#8221; clicks<br></p></li></ul></li><li><p>Auto-create issues (even without user click)<br></p></li></ul><div><hr></div><h3><strong>C. Anomaly Detection</strong></h3><ul><li><p>Sudden spike in same query &#8594; alert<br></p></li></ul><div><hr></div><h1>&#128640; <strong>Final One-Liner (Senior Level)</strong></h1><blockquote><p>&#8220;We use Kafka with query-based partitioning for ordered processing, Redis-backed deduplication for low-latency issue grouping, and horizontally scalable consumers to handle 100M+ events/day with strong observability and fault tolerance.&#8221;</p></blockquote><div><hr></div><h1>&#127757; <strong>1. Multi-Region Architecture (Global Scale)</strong></h1><h3><strong>Goal</strong></h3><ul><li><p>Low latency for users worldwide</p></li><li><p>High availability (region failure safe)</p></li></ul><div><hr></div><h2><strong>Design Approach</strong></h2><h3><strong>A. Active-Active Regions</strong></h3><ul><li><p>Deploy system in:</p><ul><li><p><code>ap-south</code> (India)</p></li><li><p><code>us-east</code></p></li><li><p><code>eu-west</code></p></li></ul></li></ul><p>&#128073; Each region has:</p><ul><li><p>API Gateway</p></li><li><p>Feedback Service</p></li><li><p>Kafka cluster</p></li><li><p>Local processing</p></li></ul><div><hr></div><h2><strong>B. Regional Ingestion</strong></h2><ul><li><p>User &#8594; nearest region (via Geo DNS)</p></li><li><p>Feedback handled <strong>locally first</strong> (low latency)</p></li></ul><div><hr></div><h2><strong>C. Cross-Region Replication</strong></h2><p>Use:</p><ul><li><p>Apache Kafka MirrorMaker / Cluster Linking</p></li></ul><p>&#128073; Replicate:</p><ul><li><p><code>feedback-events</code> &#8594; global visibility</p></li></ul><div><hr></div><h2><strong>D. Global vs Local Processing</strong></h2><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;8e025064-54d1-4467-867a-bfc38ff01647&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">| Component          | Strategy               |
| ------------------ | ---------------------- |
| Feedback ingestion | Regional               |
| Deduplication      | Regional + Global      |
| Issue DB           | Global (or replicated) |
| Analytics          | Global aggregation     |
</code></pre></div><div><hr></div><h2>&#9888;&#65039; Challenge: Duplicate Issues Across Regions</h2><h3>Solution:</h3><ul><li><p>Use <strong>global dedupe key</strong></p></li><li><p>Maintain <strong>global Redis / distributed cache</strong></p></li><li><p>Or:</p><ul><li><p>Region-local dedupe first</p></li><li><p>Periodic merge (eventual consistency)</p></li></ul></li></ul><div><hr></div><h2>&#129504; Tradeoff</h2><ul><li><p>Strong consistency &#10060; (too expensive globally)</p></li><li><p>Eventual consistency &#9989; (practical)</p></li></ul><div><hr></div><h1>&#128257; <strong>2. Exactly-Once Processing (Advanced Kafka)</strong></h1><h3><strong>Problem</strong></h3><ul><li><p>Duplicate events (retries, failures)</p></li><li><p>Double issue creation &#10060;</p></li></ul><div><hr></div><h2><strong>Solution Approach</strong></h2><h3><strong>A. Idempotent Producers</strong></h3><ul><li><p>Ensure no duplicate writes to Kafka</p></li></ul><div><hr></div><h3><strong>B. Idempotent Consumers</strong></h3><p>Core idea:</p><pre><code>Process event ONLY if not processed before</code></pre><div><hr></div><h3><strong>C. Deduplication Store (Critical)</strong></h3><p>Use:</p><ul><li><p>Redis or DB<br></p></li></ul><pre><code>Key: event_id
Value: processed</code></pre><div><hr></div><h3><strong>D. Transactional Flow (Best Practice)</strong></h3><pre><code>1. Consume event
2. Check idempotency key
3. Process (create/update issue)
4. Commit offset ONLY after success</code></pre><div><hr></div><h2>&#128293; Even Stronger (Gold Answer)</h2><p>Use <strong>Kafka Transactions</strong>:</p><ul><li><p>Consume + produce + commit offset &#8594; atomic<br></p></li></ul><div><hr></div><h1>&#128176; <strong>3. Cost Optimization (Very Underrated)</strong></h1><div><hr></div><h2><strong>A. Reduce Log Storage Cost</strong></h2><p>Instead of storing all logs:</p><ul><li><p>Store only:<br></p><ul><li><p>Errors<br></p></li><li><p>Slow queries<br></p></li><li><p>Sampled logs (e.g., 1%)<br></p></li></ul></li></ul><p>&#128073; Huge savings in Elasticsearch</p><div><hr></div><h2><strong>B. Data Retention Policies</strong></h2><p>Data TypeRetentionRaw events7 daysIssuesLong-termLogs3&#8211;7 daysMetricsAggregated only</p><div><hr></div><h2><strong>C. Tiered Storage</strong></h2><ul><li><p>Hot data &#8594; SSD<br></p></li><li><p>Cold data &#8594; S3 / cheap storage<br></p></li></ul><div><hr></div><h2><strong>D. Batch Processing</strong></h2><ul><li><p>Batch writes to DB<br></p></li><li><p>Batch Kafka consumption<br></p></li></ul><p>&#128073; Reduces infra cost</p><div><hr></div><h2><strong>E. Adaptive Sampling</strong></h2><p>If traffic spikes:</p><pre><code>Only process 1 in N low-priority events</code></pre><div><hr></div><h1>&#9878;&#65039; <strong>4. Tradeoffs (Staff-Level Clarity)</strong></h1><p>DecisionTradeoffKafka over sync API+scalability, +latency bufferingRedis dedupe+fast, -eventual consistency riskMulti-region active-active+availability, -complexitySampling logs+cost, -debugging completeness</p><div><hr></div><h1>&#129504; <strong>5. What Interviewers Look For Here</strong></h1><p>When you say this, you stand out:</p><ul><li><p>&#8220;I&#8217;ll prefer <strong>eventual consistency</strong> for global dedupe&#8221;<br></p></li><li><p>&#8220;I&#8217;ll use <strong>idempotency keys</strong> to avoid duplicates&#8221;<br></p></li><li><p>&#8220;I&#8217;ll optimize cost using <strong>log sampling + retention policies</strong>&#8221;<br></p></li><li><p>&#8220;I&#8217;ll design for <strong>failure first (DLQ, retries, replay)</strong>&#8221;<br></p></li></ul><div><hr></div><h1>&#128640; <strong>Ultimate One-Liner (Staff Level)</strong></h1><blockquote><p>&#8220;I&#8217;d design a multi-region, event-driven system with regional ingestion and global replication, ensure correctness via idempotent processing and Kafka transactions, and optimize cost using sampling, tiered storage, and retention policies.&#8221;</p></blockquote><div><hr></div><p><br><br></p>]]></content:encoded></item></channel></rss>