> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are the docs for Sevalla, a platform for deploying applications, databases, static sites, object storage and load balancers. The dashboard is at https://app.sevalla.com.
> Bold text in steps is an exact dashboard label.
> To act on a Sevalla account, prefer the Sevalla MCP server (https://mcp.sevalla.com/mcp, see https://docs.sevalla.com/ai-agents/overview.md), then the Sevalla CLI (https://docs.sevalla.com/developer-tools/cli.md), then the REST API (https://api-docs.sevalla.com, OpenAPI spec at https://api.sevalla.com/v3/openapi.json).
> Every page index is at https://docs.sevalla.com/llms.txt.

# Cache Flask with Redis

> Use a Sevalla Redis database as Flask-Caching's backend over an internal connection, cache views with cache.cached, and control the CDN and edge cache with Cache-Control.

Flask-Caching keeps computed views and values in a cache backend. On Sevalla, the backend is a Redis database that the application reaches over an internal connection, so every instance of the web process shares one cache.

## Before you begin

* A Flask project deployed on Sevalla, as in [Deploy Flask](/guides/python/flask/deploy).

## Create a Redis database

<Steps>
  <Step title="Create the database">
    In the sidebar, click **Databases**, then click **Create database**. Under **Database**, choose **Redis**, or **Valkey**: the code in this guide works with both. Enter `storefront-redis` as the **Display name**, choose the same **Data center** as the application and a **Size**, then click **Create database**.
  </Step>

  <Step title="Connect it to the application">
    In the sidebar, click **Applications**, then click the application. Click the **Networking** tab. Under **Connected services**, click **Add internal connection**. Choose `storefront-redis` as the **Service**, turn on **Add environment variables to the application**, and click **Add internal connection**. Sevalla adds `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD` and `REDIS_URL`. See [Connect an application](/databases/connect#connect-an-application).
  </Step>
</Steps>

<Frame>
  <img className="block dark:hidden" src="https://assets.sevalla.com/screenshots/light/app-networking-internal-connection-add.png" alt="The Add internal connection sheet with the Service field and the Add environment variables to the application switch" width="576" />

  <img className="hidden dark:block" src="https://assets.sevalla.com/screenshots/dark/app-networking-internal-connection-add.png" alt="The Add internal connection sheet with the Service field and the Add environment variables to the application switch" width="576" />
</Frame>

## Configure the cache

Install Flask-Caching and redis-py, and update `requirements.txt`:

```bash theme={null}
pip install flask-caching redis
pip freeze > requirements.txt
```

Create the extension next to the others:

```python storefront/extensions.py theme={null}
from flask_caching import Cache

cache = Cache()
```

In the application factory, configure the Redis backend with the URL from the internal connection, before `init_app`:

```python storefront/__init__.py theme={null}
from storefront.extensions import alembic, cache, db


def create_app() -> Flask:
    app = Flask(__name__)
    app.config["SQLALCHEMY_ENGINES"] = {"default": database_url()}
    app.config["CACHE_TYPE"] = "RedisCache"
    # A Valkey database's URL starts with valkey://, which redis-py doesn't accept.
    redis_url = os.environ.get("REDIS_URL", "redis://localhost:6379/0")
    app.config["CACHE_REDIS_URL"] = redis_url.replace("valkey://", "redis://", 1)
    app.config["CACHE_DEFAULT_TIMEOUT"] = 300
    app.config.from_prefixed_env()

    db.init_app(app)
    alembic.init_app(app)
    cache.init_app(app)

    # ...the routes...
    return app
```

## Cache a view

Cache a view's response for 2 minutes with `cache.cached`, below the route decorator:

```python storefront/__init__.py theme={null}
from datetime import datetime, timezone


def create_app() -> Flask:
    # ...the configuration and init_app calls...

    @app.get("/cached")
    @cache.cached(timeout=120)
    def cached():
        return f"Generated at {datetime.now(timezone.utc):%H:%M:%S}"

    return app
```

The same `cache` object caches function results with `@cache.memoize()` and works directly with `cache.get()` and `cache.set()`. Commit and push the changes. If **Auto-deploy** is off, click **Deploy now** on the application's **Overview** tab.

## Verify

Request the page twice, with your application's domain:

```bash theme={null}
curl https://storefront-x7k2m.sevalla.app/cached
curl https://storefront-x7k2m.sevalla.app/cached
```

Both responses show the same time. After 2 minutes, the next request shows a new time. To look at the keys, open the Redis database and click the **Redis studio** tab. See [Database studio](/databases/studio).

## Control the CDN and edge cache

Sevalla can also cache responses at Cloudflare's edge, in front of the application. Turn on the CDN and edge caching on the application's **Networking** tab; see [CDN and edge caching](/applications/caching).

* The CDN caches static files by file extension, such as `.css`, `.js` and images, including the files Flask serves from its `static` folder.
* Edge caching caches pages and other responses too. It caches only `GET` requests, skips requests with an `Authorization` header, and doesn't store responses that set a cookie, such as pages that change the session.
* When a response has no `Cache-Control` header, Sevalla adds one. With edge caching on, a `200` response without its own header can stay cached for up to 30 days, unless a deployment or a purge clears the cache first. See [Control caching from your application](/applications/caching#control-caching-from-your-application).

So with edge caching on, set `Cache-Control` on every view. `no_store` keeps a response out of every cache, and `max_age` sets how long it may be kept:

```python storefront/__init__.py theme={null}
from flask import Flask, make_response


def create_app() -> Flask:
    # ...the configuration and init_app calls...

    @app.get("/account")
    def account():
        response = make_response("Your account")
        response.cache_control.no_store = True
        return response

    @app.get("/catalog")
    def catalog():
        response = make_response("Catalog")
        response.cache_control.public = True
        response.cache_control.max_age = 600
        return response

    return app
```

To set the same header on many views, use an `@app.after_request` function. To check what a page sends, run `curl -sI https://storefront-x7k2m.sevalla.app/catalog` and read the `Cache-Control` header.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.