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": {}
}

%%