# How to Set Up Redis Caching for API Responses in FastAPI

> Effortlessly set up Redis caching for API responses in FastAPI using the boilerplate project. This guide shows you how to automatically store and invalidate responses with a simple decorator.

- Repository: [Benav Labs/fastapi-boilerplate](https://github.com/benavlabs/fastapi-boilerplate)
- Tags: how-to-guide
- Published: 2026-02-26

---

**FastAPI-Boilerplate provides a built-in Redis caching layer that automatically stores API responses and invalidates them on write operations using a simple decorator.**

Setting up Redis caching for API responses in the `benavlabs/fastapi-boilerplate` repository requires configuring environment variables, initializing a connection pool on startup, and applying the `@cache` decorator to your endpoint functions. This architecture separates concerns between configuration management in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py), lifecycle handling in [`src/app/core/setup.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/setup.py), and the caching logic itself in [`src/app/core/utils/cache.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/utils/cache.py).

## Configuring Redis Connection Settings

The boilerplate centralizes all Redis configuration in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py). The `Settings` class constructs the connection URI from discrete environment variables, making it easy to switch between local development and production deployments.

Key environment variables recognized by the system:

- `REDIS_CACHE_HOST` — defaults to `localhost` (use `redis` when running via Docker Compose)
- `REDIS_CACHE_PORT` — defaults to `6379`
- `REDIS_CACHE_DB` — defaults to `0`
- `REDIS_CACHE_PASSWORD` — optional authentication string

The `REDIS_CACHE_URL` property dynamically assembles these into a standard Redis URI:

```python

# src/app/core/config.py

f"redis://{self.REDIS_CACHE_HOST}:{self.REDIS_CACHE_PORT}"

```

## Initializing the Redis Connection Pool

FastAPI-Boilerplate manages the Redis client lifecycle through startup and shutdown event handlers defined in [`src/app/core/setup.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/setup.py). This ensures connections are pooled efficiently and released properly when the application terminates.

The `create_redis_cache_pool` function initializes the global `cache` object:

```python

# src/app/core/setup.py

import redis
from .config import settings
from .utils import cache

async def create_redis_cache_pool() -> None:
    cache.pool = redis.ConnectionPool.from_url(settings.REDIS_CACHE_URL)
    cache.client = redis.Redis.from_pool(cache.pool)

```

Correspondingly, `close_redis_cache_pool` handles graceful teardown:

```python

# src/app/core/setup.py

async def close_redis_cache_pool() -> None:
    if cache.client is not None:
        await cache.client.aclose()

```

These functions are registered as event handlers in [`src/app/main.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/main.py) and execute automatically on application startup and shutdown.

## Implementing the Cache Decorator

The `@cache` decorator in [`src/app/core/utils/cache.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/utils/cache.py) provides the primary interface for Redis caching of API responses. It intercepts incoming requests, generates cache keys based on configurable parameters, and handles serialization automatically.

### Basic Usage for GET Endpoints

Apply the decorator to any FastAPI endpoint function to cache its JSON response:

```python

# src/app/api/v1/posts.py

from fastapi import APIRouter, Depends
from ...core.utils.cache import cache
from ...schemas.post import PostRead

router = APIRouter(prefix="/posts", tags=["posts"])

@router.get("/{id}", response_model=PostRead)
@cache(key_prefix="{username}_post_cache", resource_id_name="id")
async def read_post(id: int, current_user: User = Depends(get_current_user)):
    # Database query executes only on cache miss

    return await crud_posts.get(id)

```

The decorator constructs the Redis key by combining `key_prefix` with the value of the parameter specified in `resource_id_name`. For a user named `alice` requesting post `123`, the key becomes `alice_post_cache_123`.

### Cache Invalidation Strategies

For endpoints that modify data, configure the decorator to invalidate related cache entries automatically. The `to_invalidate_extra` parameter accepts a dictionary mapping key patterns to parameter names:

```python

# src/app/api/v1/posts.py

@router.put("/{id}", response_model=PostRead)
@cache(
    key_prefix="{username}_post_cache",
    resource_id_name="id",
    to_invalidate_extra={"{username}_posts": "{username}"}
)
async def update_post(id: int, post_update: PostUpdate):
    # Updates the post and clears the user's post list cache

    return await crud_posts.update(id, post_update)

```

Alternatively, use `pattern_to_invalidate_extra` to clear multiple keys matching a glob pattern when you need to invalidate entire namespaces.

## Docker Compose Configuration

The repository includes pre-configured Docker Compose files that provision a Redis instance for local development. The [`scripts/local_with_uvicorn/docker-compose.yml`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/scripts/local_with_uvicorn/docker-compose.yml) defines the service:

```yaml

# scripts/local_with_uvicorn/docker-compose.yml

services:
  redis:
    image: redis:alpine
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

volumes:
  redis-data:

```

When running via `docker compose up web db redis`, the application connects to Redis using the service name `redis` as the host, matching the default configuration in `.env.example`.

## Environment Setup Checklist

Configure your local environment before starting the application:

```dotenv

# .env

REDIS_CACHE_HOST=redis
REDIS_CACHE_PORT=6379
REDIS_CACHE_DB=0

# REDIS_CACHE_PASSWORD=optional-secret

```

Verify connectivity by checking application logs during startup for successful pool creation, or test a cached endpoint and observe Redis key creation using `redis-cli monitor`.

## Summary

- **Configuration**: Set `REDIS_CACHE_HOST`, `REDIS_CACHE_PORT`, and `REDIS_CACHE_DB` in your environment or `.env` file, with the URL constructed automatically in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py).
- **Connection Management**: The application initializes a `redis.ConnectionPool` on startup via `create_redis_cache_pool()` in [`src/app/core/setup.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/setup.py) and closes it gracefully on shutdown.
- **Decorator Usage**: Apply `@cache(key_prefix="...", resource_id_name="...")` from [`src/app/core/utils/cache.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/utils/cache.py) to GET endpoints to enable automatic response caching.
- **Invalidation**: Use `to_invalidate_extra` or `pattern_to_invalidate_extra` parameters in the decorator to clear related cache entries when data changes.
- **Infrastructure**: Docker Compose files in `scripts/local_with_uvicorn/` provide a ready-to-use Redis service configured for the boilerplate's defaults.

## Frequently Asked Questions

### How do I change the Redis database number or add authentication?

Modify the environment variables in your `.env` file. Set `REDIS_CACHE_DB` to the desired integer (0-15 for standard Redis) and provide `REDIS_CACHE_PASSWORD` if your Redis instance requires authentication. The `REDIS_CACHE_URL` property in [`src/app/core/config.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/config.py) automatically incorporates these values when constructing the connection string.

### Can I use the cache decorator on non-GET endpoints?

Yes, though the behavior differs. The `@cache` decorator in [`src/app/core/utils/cache.py`](https://github.com/benavlabs/fastapi-boilerplate/blob/main/src/app/core/utils/cache.py) primarily targets GET requests for retrieval caching. When applied to POST, PUT, or DELETE endpoints, it functions as an invalidation mechanism—clearing specified cache keys after the operation completes—rather than storing the response. Use `to_invalidate_extra` to specify which keys to clear when mutating data.

### What happens if the Redis server is unavailable?

The application handles Redis unavailability gracefully during startup and runtime. If the connection pool fails to initialize in `create_redis_cache_pool()`, the application will raise a connection error on startup, preventing deployment with misconfigured cache settings. At runtime, if Redis becomes unreachable, the `@cache` decorator falls back to executing the endpoint function directly, bypassing the cache layer without crashing the request—though this results in cache misses until connectivity is restored.

### How do I monitor cache hit rates and inspect stored keys?

Connect to your Redis instance using `redis-cli` or a GUI client like RedisInsight. Run `MONITOR` to observe real-time key operations as the `@cache` decorator executes `GET`, `SET`, and `EXPIRE` commands. To list keys matching your prefix, use `KEYS {username}_post_cache_*` (replace with your actual prefix). For production monitoring, integrate Redis metrics into your observability stack using the `INFO stats` command to track hit/miss ratios and memory usage.