Skip to content

[1.3] Configure Redis Cache Connection #91

Description

@Sorcecoder

Story 1.3: Configure Redis Cache Connection

Status: ready-for-dev

Story

As a developer,
I want Redis connection configured for caching and rate limiting,
So that the system can store temporary data efficiently.

Acceptance Criteria

  1. Given a Redis instance is available
    When the application starts
    Then a connection pool to Redis is established

  2. Given the Redis connection is established
    When the health endpoint is called
    Then the Redis connection health can be verified (returns status "ok" or error details)

  3. Given the Redis instance is unavailable or connection fails
    When a connection attempt is made
    Then failures are handled gracefully with appropriate structured logging (no crashes)

  4. Given the deployment environment
    When Redis configuration is needed
    Then environment variables control all Redis connection settings (host, port, password, TLS)

Tasks / Subtasks

  • Task 1: Create Redis client module (AC: Test issue #1, [1.3] Request Logging Infrastructure #4)

    • Create src/services/redis.ts with connection pool factory
    • Configure connection using environment variables (REDIS_URL or REDIS_HOST/PORT/PASSWORD)
    • Implement connection pool with serverless-appropriate settings
    • Add TLS/SSL support for production Redis instances
  • Task 2: Implement connection health check (AC: [1.1] Project Initialization and Flask API Setup #2)

    • Create checkRedisHealth() function in redis service
    • Return structured health status: { status: 'ok' | 'error', latencyMs?: number, error?: string }
    • Integrate with existing health endpoint from Story 1.1 (if exists)
  • Task 3: Implement graceful error handling (AC: [1.2] Health Check Endpoint #3)

    • Add connection retry logic with exponential backoff
    • Handle connection timeout scenarios
    • Log connection errors with structured JSON (no sensitive data)
    • Ensure application continues running if Redis unavailable (graceful degradation)
  • Task 4: Add environment configuration (AC: [1.3] Request Logging Infrastructure #4)

    • Update .env.example with Redis variables
    • Document required vs optional Redis environment variables
    • Support both REDIS_URL connection string and individual vars

Dev Notes

Technical Stack Requirements

  • Runtime: TypeScript with strict mode (from Story 1.1 project setup)
  • Redis Client: Use ioredis - industry standard for Node.js, excellent TypeScript support
  • Deployment Target: Serverless (AWS Lambda or Cloudflare Workers) - connection pooling must be optimized for short-lived functions

Architecture Patterns

Connection Pool Strategy (Serverless-Optimized):

// Singleton pattern for connection reuse across warm Lambda invocations
let redisClient: Redis | null = null;

export function getRedisClient(): Redis {
  if (!redisClient) {
    redisClient = new Redis({
      host: process.env.REDIS_HOST,
      port: parseInt(process.env.REDIS_PORT || '6379'),
      password: process.env.REDIS_PASSWORD,
      tls: process.env.REDIS_TLS === 'true' ? {} : undefined,
      maxRetriesPerRequest: 3,
      retryStrategy: (times) => Math.min(times * 100, 3000),
      lazyConnect: true, // Don't connect until first command
    });
  }
  return redisClient;
}

Health Check Pattern:

export async function checkRedisHealth(): Promise<HealthStatus> {
  const start = Date.now();
  try {
    await getRedisClient().ping();
    return { status: 'ok', latencyMs: Date.now() - start };
  } catch (error) {
    return { status: 'error', error: error.message };
  }
}

Required Environment Variables

Variable Required Default Description
REDIS_URL No* - Full connection URL (overrides individual vars)
REDIS_HOST Yes* localhost Redis server hostname
REDIS_PORT No 6379 Redis server port
REDIS_PASSWORD No - Redis AUTH password
REDIS_TLS No false Enable TLS connection
REDIS_DB No 0 Redis database number

*Either REDIS_URL or REDIS_HOST required.

File Structure

src/
├── services/
│   └── redis.ts          # Redis client factory and health check
├── types/
│   └── health.ts         # HealthStatus interface (may exist from 1.1)
└── utils/
    └── env.ts            # Environment variable helpers (may exist)

Integration Points

  • Health Endpoint: If Story 1.1 created /health endpoint, integrate Redis check:
    // In health handler
    const checks = {
      database: await checkDbHealth(),  // From Story 1.2
      redis: await checkRedisHealth(),  // This story
    };

Testing Requirements

  • Unit test connection factory with mocked Redis
  • Integration test with local Redis (via docker-compose or test Redis)
  • Test graceful degradation when Redis unavailable
  • Test environment variable parsing (URL vs individual vars)

Anti-Patterns to Avoid

  1. DO NOT create new connection per request - use singleton pattern
  2. DO NOT block application startup on Redis connection - use lazy connect
  3. DO NOT log connection URLs with passwords - sanitize credentials
  4. DO NOT use synchronous Redis operations - always use async/await
  5. DO NOT hardcode connection settings - all via environment variables

Dependencies to Install

{
  "dependencies": {
    "ioredis": "^5.3.0"
  },
  "devDependencies": {
    "@types/ioredis": "^5.0.0",
    "ioredis-mock": "^8.9.0"  // For unit testing
  }
}

Security Considerations (NFR-3.1)

  • Never log Redis passwords or full connection URLs
  • Use TLS in production environments
  • Consider Redis AUTH even in private networks
  • Implement connection timeout to prevent hanging

References

  • [Source: _bmad-output/planning-artifacts/prd.md#Technical-Architecture-Considerations] - Redis for caching and rate limiting
  • [Source: _bmad-output/planning-artifacts/epics.md#Story-1.3] - Original story definition
  • [Source: _bmad-output/planning-artifacts/prd.md#Caching-Strategy] - 24-hour cache TTL, X-Cache headers

Dev Agent Record

Agent Model Used

{{agent_model_name_version}}

Debug Log References

Completion Notes List

File List

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions