forge-docs

0014. Application Caching Strategy

Status: Accepted Date: 2025-01-27 Context: Application-level caching to improve performance and cut load and cost across single-instance dev and multi-instance production.

Context

The Forge platform performs several expensive operations on every request or frequently accessed data:

  1. Cognito Token Validation - JWT parsing and signature validation via Cognito JWKS on every authenticated request
  2. User Profile Lookups - PostgreSQL queries for candidate profiles on profile page loads and header username display
  3. Document Retrieval - DynamoDB reads for parsed documents

Current state shows no caching layer, resulting in:

We must choose between:

  1. No caching - Continue with direct database/external service calls
  2. Local caching only - In-memory cache (Caffeine) for single-instance deployments
  3. Distributed caching - Redis/ElastiCache for multi-instance deployments
  4. Hybrid approach - Start with local caching, migrate to distributed for production

Additionally, we need to consider integration with planned distributed rate limiting infrastructure (Redis backend).


Decision

Implement a three-phase caching strategy using Quarkus Cache:

  1. Phase 1: Local Caching (Caffeine) - Use Quarkus Cache with default Caffeine backend for development and single-instance deployments
  2. Phase 2: Metrics and Monitoring - Add cache metrics (hit/miss rates) to Grafana dashboards before production migration
  3. Phase 3: Redis Backend (Production) - Migrate to quarkus-cache-redis with AWS ElastiCache for distributed caching across multiple service instances

Primary Use Cases:

Cache Implementation:

Infrastructure:


Rationale

Why Quarkus Cache

Why Three-Phase Approach

Why Cache-Aside Pattern

Why Shared Redis Infrastructure

Why These Use Cases


Architecture Overview

Phase 1: Local Caching (Caffeine)

┌─────────────────┐
│  Service        │
│  Instance       │
│                 │
│  ┌───────────┐  │
│  │ Caffeine  │  │
│  │ Cache     │  │
│  └───────────┘  │
│       │         │
└───────┼─────────┘
        │
        ├──> PostgreSQL (candidate profiles)
        ├──> DynamoDB (parsed documents)
        └──> Cognito (token validation)

Phase 3: Distributed Caching (Redis)

┌─────────────────┐     ┌─────────────────┐
│  Service        │     │  Service        │
│  Instance 1     │     │  Instance 2     │
│                 │     │                 │
│  ┌───────────┐  │     │  ┌───────────┐  │
│  │ Quarkus   │  │     │  │ Quarkus   │  │
│  │ Cache     │  │     │  │ Cache     │  │
│  └─────┬─────┘  │     │  └─────┬─────┘  │
└────────┼────────┘     └────────┼────────┘
         │                       │
         └────────────┬──────────┘
                      │
              ┌───────▼───────┐
              │ ElastiCache   │
              │ Redis Cluster │
              │               │
              │ cache:*       │
              │ ratelimit:*   │
              └───────┬───────┘
                      │
        ┌─────────────┼─────────────┐
        │             │             │
        ▼             ▼             ▼
   PostgreSQL    DynamoDB       Cognito

Implementation Details

Cache Configuration

Token Validation Cache:

Candidate Profile Cache:

Document Cache:

Error Handling

Security Considerations


Consequences

Positive

Negative

Risks and Mitigations


Success Metrics


References