Skip to main content

Caching Strategy Documentation

This document explains the caching implementation for the Infowebplus application.

Overview

The application uses a multi-layer caching strategy to improve performance:

  1. In-Memory Cache (Fallback) - Fast, local cache
  2. Redis Cache (Optional) - Distributed cache for production
  3. Next.js Revalidation - ISR (Incremental Static Regeneration)
  4. Sanity CDN - Always enabled for optimal performance

Cache Configuration

Environment Variables

Add these to your .env.local file:

# Cache Configuration
CACHE_PREFIX=infowebplus
CACHE_AUTH_TOKEN=your-secret-token-here

# Redis (Optional - Recommended for Production)
ENABLE_REDIS=true
REDIS_URL=redis://localhost:6379
# Or for Redis Cloud/Upstash:
# REDIS_URL=rediss://default:password@host:port

# Sanity Webhook (for cache invalidation)
SANITY_WEBHOOK_SECRET=your-webhook-secret

Cache TTL (Time To Live)

  • SHORT: 60 seconds (1 minute) - For frequently changing data
  • MEDIUM: 300 seconds (5 minutes) - Default for most content
  • LONG: 3600 seconds (1 hour) - For Sanity content (default)
  • VERY_LONG: 86400 seconds (24 hours) - For static content

Redis Setup

Why Redis?

Redis provides:

  • Distributed caching across multiple server instances
  • Persistence - Cache survives server restarts
  • Better performance for high-traffic sites
  • Shared cache across all instances

Installation

Redis is included as an optional dependency. To use it:

  1. Local Development:

    # Install Redis locally (macOS)
    brew install redis
    redis-server

    # Or use Docker
    docker run -d -p 6379:6379 redis:alpine
  2. Production (Recommended services):

    💡 For detailed pricing and recommendations, see the Redis Setup Guide and Vercel Deployment Guide.

  3. Enable Redis (Recommended: Upstash via Vercel Marketplace):

    🚀 Easiest Method - Vercel Marketplace:

    • Go to your Vercel project → IntegrationsBrowse Marketplace
    • Search for "Upstash" → Install "Upstash for Redis"
    • Sign in/up to Upstash (free)
    • Link your project and create/select database
    • Done! Environment variables are set automatically ✅

    Alternative - Manual Setup:

    ENABLE_REDIS=true
    REDIS_URL=rediss://default:password@your-upstash-endpoint:6379

    Quick Manual Setup:

    • Sign up at https://console.upstash.com (free, no credit card)
    • Create a Redis database (takes 2 minutes)
    • Copy the Redis URL and add to Vercel Environment Variables
    • Redeploy - Free tier handles millions of requests.

Redis Reliability

Redis is highly reliable for caching:

  • ✅ Fast (sub-millisecond latency)
  • ✅ Scalable (handles millions of requests)
  • ✅ Persistent (optional persistence mode)
  • ✅ Widely used in production
  • ✅ Automatic failover with Redis Sentinel/Cluster

Fallback: If Redis is unavailable, the app automatically falls back to in-memory caching.

Cache Invalidation

Manual Cache Clearing

Clear All Cache

curl -X POST https://your-domain.com/api/cache/clear?all=true \
-H "Authorization: Bearer your-secret-token"

Clear by Pattern

curl -X POST https://your-domain.com/api/cache/clear?pattern=content:* \
-H "Authorization: Bearer your-secret-token"

Check Cache Status

curl https://your-domain.com/api/cache/clear

Automatic Cache Invalidation (Sanity Webhook)

Set up a webhook in Sanity to automatically invalidate cache when content is updated:

  1. Go to Sanity Manage
  2. Select your project
  3. Go to APIWebhooks
  4. Click Create webhook
  5. Configure:
    • Name: Cache Invalidation
    • URL: https://your-domain.com/api/webhooks/sanity
    • Dataset: production (or your dataset)
    • Trigger on: Create, Update, Delete
    • HTTP method: POST
    • Secret: Set SANITY_WEBHOOK_SECRET in your env
    • HTTP Headers:
      Authorization: Bearer ${SANITY_WEBHOOK_SECRET}

Programmatic Cache Invalidation

import { deleteCache, deleteCachePattern } from '@/lib/cache'

// Delete specific cache entry
await deleteCache('content:locale:en', 'en')

// Delete all content cache
await deleteCachePattern('content:*')

API Endpoints

GET /api/cache/clear

Get cache statistics.

Response:

{
"success": true,
"stats": {
"type": "redis",
"size": 42,
"available": true
}
}

POST /api/cache/clear

Clear cache entries.

Query Parameters:

  • all=true - Clear all cache (requires auth)
  • pattern=content:* - Clear matching pattern

Headers:

  • Authorization: Bearer <token>

POST /api/cache/invalidate

Invalidate cache for specific document types.

Body:

{
"type": "document",
"documentType": "hero",
"locale": "en"
}

Headers:

  • Authorization: Bearer <token>

POST /api/webhooks/sanity

Sanity webhook endpoint for automatic cache invalidation.

Performance Improvements

Before Caching

  • Every request fetches from Sanity
  • Average response time: 500-2000ms
  • High load on Sanity API

After Caching

  • Cache hits: <10ms response time
  • Cache misses: 500-2000ms (first request)
  • Reduced Sanity API calls by ~95%

Monitoring

Check cache performance in development:

# Watch logs for cache hits/misses
npm run dev

Look for:

  • ✅ Cache hit for locale: en - Cache working
  • ⏳ Cache miss for locale: en - Fetching from Sanity

Troubleshooting

Cache Not Working

  1. Check Redis connection:

    redis-cli ping
    # Should return: PONG
  2. Check environment variables:

    echo $REDIS_URL
    echo $ENABLE_REDIS
  3. Check logs for errors

Cache Not Invalidating

  1. Verify webhook is configured in Sanity
  2. Check SANITY_WEBHOOK_SECRET matches
  3. Test webhook manually:
    curl -X POST https://your-domain.com/api/webhooks/sanity \
    -H "Authorization: Bearer your-secret" \
    -H "Content-Type: application/json" \
    -d '{"_type": "hero"}'

Best Practices

  1. Use Redis in Production - Better performance and reliability
  2. Set Appropriate TTLs - Balance freshness vs performance
  3. Invalidate on Updates - Use webhooks for automatic invalidation
  4. Monitor Cache Hit Rates - Aim for >80% hit rate
  5. Use Cache Prefixes - Avoid conflicts in shared Redis instances

Migration Guide

From No Cache to Cached

  1. Add environment variables
  2. Install Redis (optional but recommended)
  3. Deploy - caching works automatically
  4. Set up Sanity webhook for invalidation

From In-Memory to Redis

  1. Set up Redis instance
  2. Add REDIS_URL to environment
  3. Set ENABLE_REDIS=true
  4. Restart application
  5. Cache automatically migrates to Redis

Support

For issues or questions:

  • Check logs: npm run dev (development)
  • Test cache endpoints: /api/cache/clear
  • Verify Redis connection: redis-cli ping