Skip to content

Comprehensive Caching Implementation Guide

This guide documents the complete three-layer caching strategy implemented for the vertical-farm application.

Overview

The caching implementation consists of three complementary layers:

  1. Frontend Supabase Query Caching - Client-side caching with real-time invalidation
  2. Backend Response Caching - Server-side middleware with ETag support
  3. Cloudflare CDN Caching - Edge caching with global distribution

Layer 1: Frontend Supabase Query Caching

Implementation: frontend/src/lib/supabase-cache.ts

Features: - In-memory caching with configurable TTL - localStorage persistence for cross-session caching - Stale-while-revalidate strategy - Real-time cache invalidation via Supabase subscriptions - LRU eviction and size limits

Cache Strategies: - Farms: 10 minutes TTL, 2 minutes stale time - Farm Hierarchy: 15 minutes TTL, 2 minutes stale time
- Device Assignments: 5 minutes TTL, 30 seconds stale time

Usage Example:

import { supabaseWithCache } from '@/lib/supabase-cache';

// Cached farm data with automatic invalidation
const farms = await supabaseWithCache.getFarmsWithCache(userId);

// Cached hierarchy with real-time updates
const hierarchy = await supabaseWithCache.getFarmHierarchyWithCache(farmId);

Real-time Invalidation: - Automatically invalidates cache when database changes occur - Uses Supabase real-time subscriptions for instant updates - Pattern-based invalidation for related data

Layer 2: Backend Response Caching

Implementation: backend/app/middleware/cache_middleware.py

Features: - In-memory response caching with configurable TTL - ETag generation and validation for efficient revalidation - Automatic cache invalidation on data mutations - User-specific caching support - Cache statistics and monitoring

Cache TTL Configuration:

CACHE_SETTINGS = {
    "/api/v1/farms": 300,           # 5 minutes
    "/api/v1/farms/hierarchy": 900, # 15 minutes
    "/api/v1/devices": 180,         # 3 minutes
    "/api/v1/user/profile": 1800,   # 30 minutes
}

ETag Support: - Generates ETags based on response content hash - Supports If-None-Match headers for 304 responses - Reduces bandwidth usage for unchanged data

Integration:

# Added to FastAPI main.py
from app.middleware.cache_middleware import ResponseCacheMiddleware
app.add_middleware(ResponseCacheMiddleware)

Layer 3: Cloudflare CDN Caching

Configuration: cloudflare-config.txt

Page Rules (Priority Order):

  1. Health Checks - No cache
  2. URL: *vertical-farm.goodgoodgreens.org/health*
  3. Cache Level: Bypass

  4. Static Assets - Aggressive cache

  5. URL: *vertical-farm.goodgoodgreens.org/static/*
  6. Edge Cache TTL: 1 year
  7. Browser Cache TTL: 1 year

  8. API Endpoints - Short cache with revalidation

  9. URL: *vertical-farm.goodgoodgreens.org/api/*
  10. Edge Cache TTL: 5 minutes
  11. Origin Cache Control: On

Transform Rules: - Security headers for all requests - Cache-Control headers for different content types - Vary headers for proper cache segmentation

Optional Workers: - Custom caching logic for specific endpoints - Advanced cache invalidation strategies - Real-time data handling

Cache Invalidation Strategy

Frontend Cache Invalidation

// Pattern-based invalidation
supabaseWithCache.invalidateCache('farms:');

// Specific key invalidation
supabaseWithCache.invalidateCache('farm-hierarchy:123');

// Real-time automatic invalidation via subscriptions

Backend Cache Invalidation

# Automatic invalidation on mutations
@app.post("/api/v1/farms")
async def create_farm(farm_data: FarmCreate):
    result = await create_farm_service(farm_data)
    # Cache automatically invalidated by middleware
    return result

Cloudflare Cache Invalidation

# Purge specific URLs
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  --data '{"files":["https://vertical-farm.goodgoodgreens.org/api/v1/farms"]}'

# Purge by cache tags (if using Workers)
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  --data '{"tags":["farms","devices"]}'

Performance Benefits

Expected Performance Improvements

Frontend Caching: - 80-90% reduction in database queries for repeated data - Sub-100ms response times for cached data - Improved user experience with instant data loading

Backend Caching: - 60-70% reduction in database load - 304 responses reduce bandwidth by 90% - Faster API response times (50-200ms vs 200-500ms)

Cloudflare Caching: - Global edge caching reduces latency by 50-80% - Reduced origin server load by 70-80% - Improved availability during traffic spikes

Cache Hit Rate Targets

  • Frontend cache: 85%+ hit rate
  • Backend cache: 70%+ hit rate
  • Cloudflare cache: 90%+ hit rate for static content, 60%+ for API

Monitoring and Debugging

Frontend Cache Statistics

const stats = supabaseWithCache.getCacheStats();
console.log('Cache hit rate:', stats.hitRate);
console.log('Cache size:', stats.size);
console.log('Cache entries:', stats.entries);

Backend Cache Monitoring

# Cache statistics endpoint
@app.get("/api/v1/cache/stats")
async def get_cache_stats():
    return cache_middleware.get_stats()

Cloudflare Analytics

  • Monitor cache hit ratios in Cloudflare dashboard
  • Track bandwidth savings and performance improvements
  • Set up alerts for cache performance degradation

Configuration Management

Environment Variables

# Frontend (.env.local)
NEXT_PUBLIC_CACHE_ENABLED=true
NEXT_PUBLIC_CACHE_DEBUG=false

# Backend (.env)
CACHE_ENABLED=true
CACHE_DEFAULT_TTL=300
CACHE_MAX_SIZE=1000

Feature Flags

// Disable caching for development/debugging
const cacheConfig = {
  enabled: process.env.NEXT_PUBLIC_CACHE_ENABLED === 'true',
  debug: process.env.NEXT_PUBLIC_CACHE_DEBUG === 'true'
};

Testing Strategy

Frontend Cache Testing

// Test cache hit/miss behavior
describe('Supabase Cache', () => {
  it('should cache farm data', async () => {
    const farms1 = await supabaseWithCache.getFarmsWithCache();
    const farms2 = await supabaseWithCache.getFarmsWithCache();
    expect(farms2.fromCache).toBe(true);
  });
});

Backend Cache Testing

# Test ETag generation and validation
def test_etag_caching():
    response1 = client.get("/api/v1/farms")
    etag = response1.headers["etag"]

    response2 = client.get("/api/v1/farms", headers={"If-None-Match": etag})
    assert response2.status_code == 304

Load Testing

# Test cache performance under load
ab -n 1000 -c 10 https://vertical-farm.goodgoodgreens.org/api/v1/farms

Troubleshooting

Common Issues

Cache Not Working: 1. Check environment variables 2. Verify middleware order 3. Check cache TTL settings 4. Monitor cache statistics

Stale Data: 1. Verify real-time subscriptions 2. Check cache invalidation patterns 3. Review TTL settings 4. Test manual invalidation

Performance Issues: 1. Monitor cache hit rates 2. Check cache size limits 3. Review eviction policies 4. Optimize cache keys

Debug Tools

// Enable cache debugging
localStorage.setItem('cache-debug', 'true');

// View cache contents
console.log(supabaseWithCache.getCacheStats());

Future Enhancements

Planned Improvements

  1. Redis Integration - Shared cache across backend instances
  2. Cache Warming - Preload frequently accessed data
  3. Smart Invalidation - ML-based cache invalidation
  4. Compression - Compress cached responses
  5. Metrics Dashboard - Real-time cache performance monitoring

Advanced Features

  1. Distributed Caching - Multi-region cache synchronization
  2. Cache Partitioning - User-specific cache isolation
  3. Predictive Caching - Preload data based on user behavior
  4. Cache Analytics - Detailed performance insights

Conclusion

This three-layer caching implementation provides: - Improved Performance - Faster response times and reduced latency - Reduced Load - Lower database and server resource usage - Better UX - Instant data loading and improved responsiveness - Scalability - Support for increased user load - Cost Efficiency - Reduced bandwidth and server costs

The implementation is production-ready and includes comprehensive monitoring, debugging tools, and invalidation strategies to ensure data consistency while maximizing performance benefits.