Use Read-Heavy SaaS API as the Foundational Architecture Pattern
Deterministic ADR derived from topology, simulation, and advisor intelligence for Read-Heavy SaaS API. Traceable to YAML knowledge entities.
Context
Most SaaS APIs read far more data than they write. A single PostgreSQL primary quickly becomes a read bottleneck as concurrent users grow. Naive connection-per-request patterns exhaust the database's max_connections under modest load. The system needs a tiered read path that serves hot data from cache, distributes remaining reads across replicas, and protects the primary with a connection pool. Primary operational risks include: Cache stampede on Redis restart or flush: all cache misses hit the primary simultaneously; Replication lag causes stale reads silently when replica is behind primary; Pool saturation under traffic spikes shifts all load to primary, potentially cascading.
Decision
We will adopt the **Read-Heavy SaaS API** architecture pattern. This is a moderate-complexity architecture appropriate for teams at experienced backend team level or above. The advisor rates this pattern as 'intermediate' operational maturity.
Rationale
A standard SaaS API architecture optimized for read-dominant workloads. PostgreSQL serves as the primary data store, Redis provides a caching layer for hot data, connection pooling bounds database concurrency, and read replicas scale read throughput without scaling write capacity. The primary architectural strength is: Redis caching absorbs repeated read requests at the edge, reducing database load and latency for high read-to-write ratio workloads by orders of magnitude. Redis caching absorbs repeated read requests at the edge, reducing database load and latency for high read-to-write ratio workloads by orders of magnitude. Key trade-off: Introduces eventual consistency: stale reads possible within TTL window. Operational note: Cache-aside (lazy population) is the dominant integration pattern. Evidence: Cache hit rates of 80–95% observed in production read-heavy APIs. Core technology stack: postgresql, redis.
Architectural Strengths
- ✓Redis caching absorbs repeated read requests at the edge, reducing database load and latency for high read-to-write ratio workloads by orders of magnitude
- ✓A connection pool bounds the total database connections an application can open, preventing connection storms during traffic…
- ✓Read-heavy APIs benefit directly from Redis as a caching tier that absorbs repeated identical reads and provides sub-millisecond…
- ✓Read-heavy APIs generate large numbers of short-lived database connections
- ✓PostgreSQL's built-in streaming replication provides the replication substrate that makes the read replica pattern operational
Accepted Tradeoffs
- ⚠Redis adds operational surface (sizing, eviction policy, cold-start warming)
- ⚠Read replicas introduce eventual consistency: lagged replicas serve stale data
- ⚠Connection pool limits impose a hard ceiling on database concurrency
- ⚠Cache invalidation requires explicit write-path coordination; silent stale reads are the failure mode
Risks
All database connections in the pool are in use; new requests queue and then time out, causing cascading latency and errors across all dependent services.
Asynchronous replicas fall behind the primary under write load and serve reads from an older version of the data. Reads keep succeeding, so nothing errors; what breaks is one of three specific consistency guarantees (read-after-write, monotonic reads, or consistent prefix), each with a distinct user-visible anomaly.
Alternatives Considered
AI Retrieval-Augmented Generation Platform was not selected because its high operational complexity exceeds the current team's readiness relative to Read-Heavy SaaS API's moderate complexity.
Analytics Data Platform was not selected because its high operational complexity exceeds the current team's readiness relative to Read-Heavy SaaS API's moderate complexity.
API Gateway Platform was not selected because its high operational complexity exceeds the current team's readiness relative to Read-Heavy SaaS API's moderate complexity.
Audit and Compliance Platform was not selected because its high operational complexity exceeds the current team's readiness relative to Read-Heavy SaaS API's moderate complexity.
Scaling Thresholds
Signals indicating the architecture is approaching its scaling limits:
Tier 1: Connection Exhaustion
Signal: p99 database latency rising; connection wait queue growing; requests timing out with "too many connections" or pool queue full errors
Evolution: Add PgBouncer connection pooler in transaction mode
Tier 2: Read Throughput Ceiling
Signal: Database CPU > 80% sustained; read query p99 rising; cache miss rate stable but overall latency increasing
Evolution: Add one or more streaming read replicas; implement lag-aware replica routing
Tier 3: Cache Miss Amplification
Signal: Redis hit rate < 60%; database read pressure rising despite cache presence; TTL expiry storms visible in Redis monitoring
Evolution: Expand Redis memory allocation; segment cache by object lifecycle; implement staggered TTL jitter to prevent expiry storms
Tier 4: Write Bottleneck Emerges
Signal: Write p99 > 50ms; replication lag > 1s consistently; WAL disk I/O saturated
Evolution: Evaluate write sharding, CQRS separation, or domain decomposition. This represents a fundamental architectural transition.
Migration Path
Single PostgreSQL, no cache, no pooling → PostgreSQL + PgBouncer + Redis cache
Connection pool exhaustion or p99 read latency > 200ms under normal load
PostgreSQL + PgBouncer + Redis cache → PostgreSQL + PgBouncer + Redis + streaming read replica
Primary CPU > 70% during peak read hours
Operational Requirements
- Minimum team maturity: Experienced Backend Team: This scenario has moderate operational complexity. It is recommended for Experienced Backend Team teams or higher.
- Runbooks and alerting for high-severity risks: 2 high-severity risks identified. Each requires a documented runbook, alerting threshold, and on-call response procedure before running in production.
- Cache sizing and eviction policy configuration: Redis or equivalent cache requires correct maxmemory configuration, eviction policy selection (allkeys-lru is common), and cold-start warming strategy after restarts.
- Replica lag monitoring and lag-aware routing: Read replicas must be monitored for replication lag. The application router must include a max_lag_ms threshold; queries above that threshold must be redirected to the primary.