Architecture Review: API Gateway Platform
A multi-tenant API gateway providing authentication, distributed rate limiting, request routing, payload transformation, and per-tenant usage analytics for API publishers. The hot path: authentication check, rate limit evaluation, and routing decision: must complete in under 1ms using Redis-only data structures to avoid proxying latency dominating upstream service response time. PostgreSQL stores tenant configuration, subscription plans, and API key definitions. Kafka receives API usage events for downstream billing and analytics. Configuration changes (rate limit updates, routing rule edits) must propagate to all gateway replicas without restart.
Evidence Confidence
Moderate
strong
Executive Summary
API Gateway Platform: moderate operational readiness (81% evidence confidence). 0 architectural strengths identified, 7 operational risks to manage. Primary concern: Cache Stampede (Dog-Pile). Requires Advanced operational maturity.
Readiness Rationale
Overall moderate readiness across 8 dimensions. Weak: consistency. Limited: team maturity. Strong: migration, observability, failure recovery.
Key Concerns
- !Cache Stampede (Dog-Pile)
- !Thundering Herd (Cache Stampede)
Key Strengths
- +Architecture is well-defined for the multi tenant saas problem profile
8
Assessments
4
Tradeoffs
6
Sections
11
Recommendations
Readiness Assessments
8Architectural Tradeoffs
4Recommendations
11Monitor: Cache Stampede (Dog-Pile)
risk_monitoringWhen a widely-shared cached value expires or is invalidated, all concurrent requests that miss simultaneously trigger identical expensive database queries, overwhelming the origin store before any single result can be computed and cached: a positive feedback loop that can collapse the database within seconds.
Affects 1 node. (Read-Heavy API Backend)
Monitor: Thundering Herd (Cache Stampede)
risk_monitoringWhen a popular cached key expires or a service recovers from downtime, all requests that were waiting or arrive simultaneously miss the cache and hit the origin database concurrently, producing a request spike that can overwhelm the database within seconds.
Affects 1 node. (Redis)
Implement: Monitor generic risk probe signals
observabilitySeed 'Cache Stampede (Dog-Pile) Risk Probe' identifies 2 metrics relevant to cache_stampede.
Metrics to instrument: error_rate, p95_latency_ms
Per-request PostgreSQL configuration lookup on the hot path → Local in-process configuration cache with Redis pub/sub invalidation
migration_planningTrigger: PostgreSQL hot path query p99 > 2ms under sustained request load; connection pool exhaustion on the configuration database during traffic spikes; gateway horizontal scaling causing proportional growth in PostgreSQL connection demand. Migrate from 'Per-request PostgreSQL configuration lookup on the hot path' to 'Local in-process configuration cache with Redis pub/sub invalidation'. Start with a 10-second TTL on routing rules and 30-second TTL on rate limits. Monitor cache hit rate; it should be > 99.9% under steady state. A low hit rate indicates the cache is being evicted faster than it is being populated, which requires heap sizing investigation.
Local cache introduces consistency window: test and document the maximum staleness window for each configuration type (rate limits, routing rules, API key validity) before switching to cached paths; Cache warm-up latency on gateway startup causes cold start period where every request falls through to PostgreSQL: implement background prefetch of all active tenant configurations at startup before accepting traffic
INCR + EXPIRE as separate Redis commands for rate limiting → Atomic Lua script implementing sliding window rate limiting
migration_planningTrigger: Rate limit enforcement allowing requests above the configured limit during concurrent burst traffic; rate limit anomalies found during load testing where measured allowed rate exceeds configured limit by > 10%. Migrate from 'INCR + EXPIRE as separate Redis commands for rate limiting' to 'Atomic Lua script implementing sliding window rate limiting'. The atomic INCR/TTL Lua script is a minimal 8–12 line script. Implement the simplest version first (fixed window), validate correctness, then migrate to sliding window if the fixed window burst behavior is unacceptable to tenants.
Lua script must be tested against the Redis version running in production: some Redis Cluster configurations restrict KEYS access within Lua scripts; validate that hash tags route all tenant keys to the same slot before deploying; Script complexity must be kept minimal: a Lua script that takes > 0.1ms to execute under load should be profiled and simplified; complex rate limit algorithms (token bucket with multi-level hierarchy) should be validated against Redis latency benchmarks before replacing the simpler approach
Prepare runbook for: Burst Traffic Cold Cache Stampede
simulation_preparednessSimulation demonstrates critical degradation of redis, postgresql
Without a runbook, recovery from this failure mode will be ad-hoc
Prepare runbook for: Connection Pool Exhaustion with Horizontal User Scale
simulation_preparednessSimulation demonstrates critical degradation of postgresql
Without a runbook, recovery from this failure mode will be ad-hoc
Plan evolution: OLTP Analytics Queries → OLTP + OLAP Separation
evolution_planningEvolution from Unified OLTP + Analytics on PostgreSQL → Separated OLTP (PostgreSQL) + OLAP (ClickHouse/Snowflake)
Migration complexity: medium. Rollback: always.
Plan evolution: Single Cache Layer → Distributed Cache
evolution_planningEvolution from Single Redis Node / Sentinel Cluster → Distributed Redis Cluster (Consistent Hash Ring)
Migration complexity: medium. Rollback: complex.
Monitor threshold: Tier 1: Redis Rate Limit Throughput
scaling_monitoringSignal: Redis command latency p99 > 0.5ms; gateway hot path p99 exceeding 2ms with Redis as the bottleneck (not upstream service); Redis CPU > 60% sustained; Lua script execution visible in SLOWLOG at > 0.1ms frequency
Bottleneck: Single Redis instance processing all rate limit Lua scripts serially for all tenants across all gateway replicas. Evolution: Shard rate limit counters across Redis Cluster nodes by hashing tenant_id to a cluster slot; this distributes Lua script execution across nodes proportional to tenant count; ensure tenant_id-keyed counters use hash tags ({tenant_id}) so all keys for a tenant land on the same slot and Lua scripts can operate on them atomically; do not use Redis Cluster without testing Lua script compatibility against your cluster topology first
Monitor threshold: Tier 2: Configuration Propagation Latency
scaling_monitoringSignal: Tenant reports that rate limit increase takes > 30 seconds to take effect across all gateway replicas; configuration change audit log shows primary PostgreSQL write completing, but gateway replicas still routing to old backend endpoints beyond the expected cache TTL window
Bottleneck: Local in-process cache TTL too long, or cache invalidation signal (Redis pub/sub or Kafka) not reaching all replicas. Evolution: Implement configuration change notification via Redis pub/sub: PostgreSQL configuration writes also publish a config_invalidated event to a Redis channel; each gateway replica subscribes to this channel and flushes the affected local cache key on receipt; this reduces propagation latency from TTL duration to sub-second pub/sub delivery without eliminating the local cache that protects Redis from per-request configuration lookups
Scaling Pressure Signals
8Redis command latency p99 > 0.5ms; gateway hot path p99 exceeding 2ms with Redis as the bottleneck (not upstream service); Redis CPU > 60% sustained; Lua script execution visible in SLOWLOG at > 0.1ms frequency
Threshold
Tier 1: Redis Rate Limit Throughput
Likely Bottleneck
Single Redis instance processing all rate limit Lua scripts serially for all tenants across all gateway replicas
Recommended Evolution
Shard rate limit counters across Redis Cluster nodes by hashing tenant_id to a cluster slot; this distributes Lua script execution across nodes proportional to tenant count; ensure tenant_id-keyed counters use hash tags ({tenant_id}) so all keys for a tenant land on the same slot and Lua scripts can operate on them atomically; do not use Redis Cluster without testing Lua script compatibility against your cluster topology first
Tenant reports that rate limit increase takes > 30 seconds to take effect across all gateway replicas; configuration change audit log shows primary PostgreSQL write completing, but gateway replicas still routing to old backend endpoints beyond the expected cache TTL window
Threshold
Tier 2: Configuration Propagation Latency
Likely Bottleneck
Local in-process cache TTL too long, or cache invalidation signal (Redis pub/sub or Kafka) not reaching all replicas
Recommended Evolution
Implement configuration change notification via Redis pub/sub: PostgreSQL configuration writes also publish a config_invalidated event to a Redis channel; each gateway replica subscribes to this channel and flushes the affected local cache key on receipt; this reduces propagation latency from TTL duration to sub-second pub/sub delivery without eliminating the local cache that protects Redis from per-request configuration lookups
Kafka producer batch queue filling faster than it can be flushed; usage event lag on the billing consumer > 5 minutes; Kafka broker I/O saturation during peak request periods; gateway producer retries visible in producer metrics
Threshold
Tier 3: Kafka Usage Event Throughput
Likely Bottleneck
Usage event Kafka produce throughput insufficient for peak request rate, or consumer lag accumulating faster than it can drain
Recommended Evolution
Tune Kafka producer batch.size and linger.ms for usage events to maximize batching efficiency (linger.ms = 5, batch.size = 65536 is a reasonable starting point); ensure Kafka topic partition count for usage events matches the maximum billing consumer parallelism; usage events can tolerate at-least-once delivery with deduplication on consumer side: set acks = 1 (not all) for usage events to reduce produce latency at the cost of broker failure durability
Redis Sentinel or Cluster failover taking > 30 seconds; gateway error rate spiking to 100% during failover window; rate limit counters reset post-failover causing burst allowance across the tenant fleet simultaneously
Threshold
Tier 4: Redis Availability and Failover
Likely Bottleneck
Single Redis primary handling all rate limit state with no fast failover path
Recommended Evolution
Deploy Redis Sentinel with at least 3 sentinel nodes for automatic failover with < 30s promotion time; implement a circuit breaker in the gateway for Redis unavailability: fail-open with local approximate rate limiting (leaky bucket in process memory) during the failover window; ensure Redis AOF persistence is enabled with appendfsync = everysec to minimize counter loss on failover
Redis command latency p99 > 0.5ms; gateway hot path p99 exceeding 2ms with Redis as the bottleneck (not upstream service); Redis CPU > 60% sustained; Lua script execution visible in SLOWLOG at > 0.1ms frequency
Threshold
Escalation trigger: Single Redis instance processing all rate limit Lua scripts serially for all tenants across all gateway replicas
Likely Bottleneck
Tier 1: Redis Rate Limit Throughput
Recommended Evolution
Monitor: error_rate, p95_latency_ms, active_connections
Tenant reports that rate limit increase takes > 30 seconds to take effect across all gateway replicas; configuration change audit log shows primary PostgreSQL write completing, but gateway replicas still routing to old backend endpoints beyond the expected cache TTL window
Threshold
Escalation trigger: Local in-process cache TTL too long, or cache invalidation signal (Redis pub/sub or Kafka) not reaching all replicas
Likely Bottleneck
Tier 2: Configuration Propagation Latency
Recommended Evolution
Monitor: error_rate, p95_latency_ms, active_connections
Kafka producer batch queue filling faster than it can be flushed; usage event lag on the billing consumer > 5 minutes; Kafka broker I/O saturation during peak request periods; gateway producer retries visible in producer metrics
Threshold
Escalation trigger: Usage event Kafka produce throughput insufficient for peak request rate, or consumer lag accumulating faster than it can drain
Likely Bottleneck
Tier 3: Kafka Usage Event Throughput
Recommended Evolution
Monitor: error_rate, p95_latency_ms, active_connections
Redis Sentinel or Cluster failover taking > 30 seconds; gateway error rate spiking to 100% during failover window; rate limit counters reset post-failover causing burst allowance across the tenant fleet simultaneously
Threshold
Escalation trigger: Single Redis primary handling all rate limit state with no fast failover path
Likely Bottleneck
Tier 4: Redis Availability and Failover
Recommended Evolution
Monitor: error_rate, p95_latency_ms, active_connections
Migration Readiness
12Migration Stages
3Per-request PostgreSQL configuration lookup on the hot path → Local in-process configuration cache with Redis pub/sub invalidation
infoMigration trigger: PostgreSQL hot path query p99 > 2ms under sustained request load; connection pool exhaustion on the configuration database during traffic spikes; gateway horizontal scaling causing proportional growth in PostgreSQL connection demand
INCR + EXPIRE as separate Redis commands for rate limiting → Atomic Lua script implementing sliding window rate limiting
infoMigration trigger: Rate limit enforcement allowing requests above the configured limit during concurrent burst traffic; rate limit anomalies found during load testing where measured allowed rate exceeds configured limit by > 10%
Single Redis instance with no persistence → Redis Sentinel with AOF persistence and gateway-side failover circuit breaker
infoMigration trigger: First Redis instance crash causing 100% gateway error rate for the full recovery period; tenant SLA requirements for gateway availability > 99.9%; rate limit counter reset post-restart causing coordinated burst across all tenants
Risks
9Local cache introduces consistency window: test and document
warningLocal cache introduces consistency window: test and document the maximum staleness window for each configuration type (rate limits, routing rules, API key validity) before switching to cached paths
Cache warm-up latency on gateway startup causes cold start p
warningCache warm-up latency on gateway startup causes cold start period where every request falls through to PostgreSQL: implement background prefetch of all active tenant configurations at startup before accepting traffic
Lua script must be tested against the Redis version running
warningLua script must be tested against the Redis version running in production: some Redis Cluster configurations restrict KEYS access within Lua scripts; validate that hash tags route all tenant keys to the same slot before deploying
Script complexity must be kept minimal: a Lua script that ta
warningScript complexity must be kept minimal: a Lua script that takes > 0.1ms to execute under load should be profiled and simplified; complex rate limit algorithms (token bucket with multi-level hierarchy) should be validated against Redis latency benchmarks before replacing the simpler approach
Sentinel failover time (default 30s) is a hard availability
warningSentinel failover time (default 30s) is a hard availability gap for all tenants simultaneously: this must be communicated in the platform SLA
AOF persistence adds fsync overhead to every Redis write; wi
warningAOF persistence adds fsync overhead to every Redis write; with appendfsync everysec the overhead is low but measurable under very high write rates; validate latency impact before enabling
Projection lag creates a read-after-write window where users
criticalProjection lag creates a read-after-write window where users see stale data after their own writes. Mitigation: Route immediate post-write reads to the write store (session-scoped write token); accept eventual consistency only for non-user-initiated reads
↗ direct-db-to-cqrs
Projection rebuild after schema change can take hours or day
criticalProjection rebuild after schema change can take hours or days on large datasets. Mitigation: Design blue/green projection deployment: build new projection in parallel before switching traffic; test rebuild time in staging
↗ direct-db-to-cqrs
Cross-service workflows that previously used database transa
criticalCross-service workflows that previously used database transactions now require Saga orchestration. Mitigation: Design idempotent event handlers; implement compensating transactions for every multi-step workflow; test failure injection in staging
↗ modular-monolith-to-event-driven
Review Sections
6Referenced Intelligence