Skip to main content
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.

At a glance

Environment variables

This guide adds one variable to the ones in Deploy a Flask application:

Before you begin

  • The storefront project from Deploy Flask, deployed on Sevalla. This guide updates its app/extensions.py and replaces its app/__init__.py.

Create a Redis database

1

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.
2

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.
The Add internal connection sheet with the Service field and the Add environment variables to the application switchThe Add internal connection sheet with the Service field and the Add environment variables to the application switch

Configure the cache

In the project folder, with the virtual environment active, install Flask-Caching and redis-py, and update requirements.txt:
Create the cache extension next to the others:
app/extensions.py

Cache a view

Replace app/__init__.py. It configures the Redis backend with the URL from the internal connection, before cache.init_app, and adds three views: /cached, cached in Redis for 2 minutes with cache.cached, and /account and /catalog, which set their own Cache-Control header for the CDN and edge cache:
app/__init__.py
cache.cached goes below the route decorator. 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:
Both responses show the same time, such as Generated at 16:11:31: the second one comes from Redis. 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: the view is stored as flask_cache_view//cached. See Database 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.
  • 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.
So with edge caching on, set Cache-Control on every view, as /account and /catalog do: no_store keeps a response out of every cache, and max_age sets how long it may be kept. Sevalla passes the header through unchanged:
The response includes cache-control: public, max-age=600; for /account, it’s cache-control: no-store. To set the same header on many views, use an @app.after_request function.

Deploy with the API

These calls create the Redis database, connect it and deploy the code, as the dashboard steps on this page do. APP_ID, CLUSTER_ID and DB1_ID come from Deploy with the API in the deploy guide, which also turned on auto-deploy, and SEVALLA_API_KEY holds the same API key. Commit the code from this page first, without pushing it, and run the commands in the project folder: the push comes last, so the deployment starts with REDIS_URL in place.
1

Create the Redis database

Create database (createDatabaseV3), with a password you choose, because the API never returns it. The API requires db_name for every engine; a Redis database reports it as 0:
CLI: sevalla databases create --name storefront-redis --type redis --db-version 8.6 --cluster "$CLUSTER_ID" --resource-type "$DB1_ID" --db-name storefront --db-password "$REDIS_PASSWORD". MCP: create_database with type redis, connect_to_application_id set to the application and env_var_name set to REDIS_URL does this step and the next three: it generates the password, connects the database and adds REDIS_URL as redis://:<password>@<host>:<port>, which uses database 0 too.
2

Wait for the database

Get database (getDatabaseV3) until its status is ready, then keep its internal hostname and port:
CLI: sevalla databases get "$REDIS_ID" --json. MCP: get_database.
3

Connect the database

Create internal connection (createApplicationInternalConnectionV3):
CLI: sevalla databases connections internal-create "$REDIS_ID" --target-id "$APP_ID" --target-type app. MCP: sevalla_api_create with createApplicationInternalConnectionV3 and the same body.
4

Add the Redis URL

The API doesn’t add the connection’s variables. Create environment variable (createEnvironmentVariableV3) adds REDIS_URL in the dashboard’s format, available during runtime only:
It prints {"key":"REDIS_URL","is_runtime":true,"is_buildtime":false}. If the application already has a REDIS_URL, from another of these guides, the call fails with 400 and Environment variable with key "REDIS_URL" already exists: use that Redis database instead of a new one, or replace the value with Update environment variable (updateEnvironmentVariableV3). CLI: sevalla apps env-vars create "$APP_ID" --key REDIS_URL --value "redis://:$REDIS_PASSWORD@$REDIS_HOST:$REDIS_PORT/0", which makes it available during build and runtime. MCP: set_environment_variables with runtime true and buildtime false.
5

Push and find the deployment

Push the commit. Auto-deploy starts a deployment of it, and List deployments (listDeploymentsV3), newest first, returns it once it exists:
With auto-deploy off, start it with Trigger deployment (triggerDeploymentV3) instead. CLI: sevalla apps deployments list --app-id "$APP_ID". MCP: list_deployments.
6

Wait for the deployment

Get deployment (getDeploymentV3) until status is success or failed:
It prints success when the deployment finishes, or failed; after 30 minutes without either, it prints the status it last read. CLI: sevalla apps deployments get "$DEPLOYMENT_ID" --app-id "$APP_ID". MCP: get_deployment, then get_deployment_logs if it failed.
Then run the checks in Verify, with the domain from List application domains (listApplicationDomainsV3) as in the deploy guide.