Rate-Limiter-Design-diagram.excalidraw
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
Rate Limiter — System Architecture Diagram
Text Elements
Client ^client-label request ^req-label API Gateway / Rate Limiter Middleware ^gateway-label Rules Engine ^rules-engine-label Counter Check ^counter-check-label Rules DB ^rules-db-label Redis (counters) ^redis-label Distributed: each instance shares counters ^redis-note Within limit? ^decision-label YES ^yes-label NO ^no-label Backend Services ^backend-label 429 Too Many Requests ^reject-label Algorithm variants: Token Bucket | Sliding Window Log | Sliding Window Counter | Fixed Window ^algo-label Rate limit at gateway layer; counters in Redis for distributed consistency ^annotation
%%
Drawing
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "client",
"type": "rectangle",
"x": 40,
"y": 80,
"width": 100,
"height": 44,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f1f3f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "client-text",
"type": "text",
"x": 55,
"y": 94,
"width": 70,
"height": 20,
"text": "Client",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-client-gw",
"type": "arrow",
"x": 140,
"y": 102,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "request",
"fontSize": 11,
"strokeColor": "#1e1e1e"
}
},
{
"id": "gateway",
"type": "rectangle",
"x": 220,
"y": 40,
"width": 300,
"height": 180,
"strokeColor": "#1971c2",
"backgroundColor": "#e7f5ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "gateway-text",
"type": "text",
"x": 235,
"y": 48,
"width": 270,
"height": 20,
"text": "API Gateway / Rate Limiter Middleware",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1971c2",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "rules-engine",
"type": "rectangle",
"x": 240,
"y": 80,
"width": 120,
"height": 44,
"strokeColor": "#5c7cfa",
"backgroundColor": "#edf2ff",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "rules-engine-text",
"type": "text",
"x": 255,
"y": 94,
"width": 90,
"height": 20,
"text": "Rules Engine",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#5c7cfa",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "counter-check",
"type": "rectangle",
"x": 240,
"y": 150,
"width": 120,
"height": 44,
"strokeColor": "#5c7cfa",
"backgroundColor": "#edf2ff",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "counter-check-text",
"type": "text",
"x": 255,
"y": 164,
"width": 90,
"height": 20,
"text": "Counter Check",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#5c7cfa",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "rules-db",
"type": "ellipse",
"x": 240,
"y": 260,
"width": 120,
"height": 60,
"strokeColor": "#5c7cfa",
"backgroundColor": "#edf2ff",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "rules-db-text",
"type": "text",
"x": 255,
"y": 282,
"width": 90,
"height": 20,
"text": "Rules DB",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#5c7cfa",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-rules-db",
"type": "arrow",
"x": 300,
"y": 124,
"width": 0,
"height": 136,
"strokeColor": "#5c7cfa",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 100,
"points": [[0, 0], [0, 136]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "fetch rules",
"fontSize": 10,
"strokeColor": "#5c7cfa"
}
},
{
"id": "redis",
"type": "rectangle",
"x": 390,
"y": 140,
"width": 110,
"height": 80,
"strokeColor": "#c92a2a",
"backgroundColor": "#fff5f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "redis-text",
"type": "text",
"x": 400,
"y": 160,
"width": 90,
"height": 36,
"text": "Redis\n(counters)",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "redis-dashed-box",
"type": "rectangle",
"x": 378,
"y": 128,
"width": 134,
"height": 116,
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"strokeStyle": "dashed",
"opacity": 60
},
{
"id": "redis-dashed-label",
"type": "text",
"x": 380,
"y": 250,
"width": 130,
"height": 28,
"text": "Distributed: each\ninstance shares counters",
"fontSize": 10,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "top",
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-counter-redis",
"type": "arrow",
"x": 360,
"y": 172,
"width": 30,
"height": 0,
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [30, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "INCR",
"fontSize": 10,
"strokeColor": "#c92a2a"
}
},
{
"id": "decision",
"type": "diamond",
"x": 560,
"y": 80,
"width": 120,
"height": 80,
"strokeColor": "#1e1e1e",
"backgroundColor": "#fff9db",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "decision-text",
"type": "text",
"x": 575,
"y": 112,
"width": 90,
"height": 20,
"text": "Within limit?",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-gw-decision",
"type": "arrow",
"x": 520,
"y": 120,
"width": 40,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [40, 0]],
"startArrowhead": null,
"endArrowhead": "arrow"
},
{
"id": "backend",
"type": "rectangle",
"x": 720,
"y": 94,
"width": 140,
"height": 44,
"strokeColor": "#2f9e44",
"backgroundColor": "#ebfbee",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "backend-text",
"type": "text",
"x": 735,
"y": 108,
"width": 110,
"height": 20,
"text": "Backend Services",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-yes",
"type": "arrow",
"x": 680,
"y": 120,
"width": 40,
"height": 0,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [40, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "YES",
"fontSize": 11,
"strokeColor": "#2f9e44"
}
},
{
"id": "reject",
"type": "rectangle",
"x": 720,
"y": 200,
"width": 140,
"height": 44,
"strokeColor": "#c92a2a",
"backgroundColor": "#fff5f5",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100
},
{
"id": "reject-text",
"type": "text",
"x": 728,
"y": 214,
"width": 124,
"height": 20,
"text": "429 Too Many Requests",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "arrow-no",
"type": "arrow",
"x": 620,
"y": 160,
"width": 100,
"height": 62,
"strokeColor": "#c92a2a",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"points": [[0, 0], [100, 62]],
"startArrowhead": null,
"endArrowhead": "arrow",
"label": {
"text": "NO",
"fontSize": 11,
"strokeColor": "#c92a2a"
}
},
{
"id": "algo-panel",
"type": "rectangle",
"x": 40,
"y": 310,
"width": 820,
"height": 36,
"strokeColor": "#868e96",
"backgroundColor": "#f8f9fa",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "algo-text",
"type": "text",
"x": 55,
"y": 320,
"width": 790,
"height": 20,
"text": "Algorithm variants: Token Bucket | Sliding Window Log | Sliding Window Counter | Fixed Window",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#495057",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
},
{
"id": "annotation",
"type": "text",
"x": 40,
"y": 360,
"width": 700,
"height": 20,
"text": "Rate limit at gateway layer; counters in Redis for distributed consistency",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "top",
"strokeColor": "#e67700",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}%%