All eyes on AI: 2026 predictions – The shifts that will shape your stack.

Read now

Tutorial

Using Redis with FastAPI

February 26, 202614 minute read
Andrew Brookins
Andrew Brookins
TL;DR:
In this tutorial, you'll build IsBitcoinLit, a FastAPI service that stores Bitcoin sentiment and price data in Redis Time Series, calculates rolling averages, and caches the results with async Python using redis-py.

#Introduction

FastAPI is a Python web framework based on the Starlette microframework. With deep support for asyncio, FastAPI is indeed very fast. FastAPI also distinguishes itself with features like automatic OpenAPI (OAS) documentation for your API, easy-to-use data validation tools, and more.
Of course, the best way to make your FastAPI service even faster is to use Redis. Unlike most databases, Redis excels at low-latency access because it's an in-memory database. If you're new to using Redis with Python, check out the redis-py getting started guide first.
In this tutorial, we'll walk through the steps necessary to use Redis with FastAPI. We're going to build IsBitcoinLit, an API that stores Bitcoin sentiment and price averages in Redis using a timeseries data structure, then rolls these averages up for the last three hours.
Next, let's look at the learning objectives of this tutorial.

#Learning Objectives

The learning objectives of this tutorial are:
  1. Learn how to install redis-py and connect to Redis asynchronously
  2. Learn how to integrate redis-py with FastAPI
  3. Learn how to use Redis to store and query timeseries data
  4. Learn how to use Redis as a cache with async Python
Let's get started!

#Pre-Tutorial Quiz

Want to check gaps in your knowledge of Redis and FastAPI before you continue? Take our short pre-tutorial quiz!

#Set Up the IsBitcoinLit Project

You can achieve the learning objectives of this tutorial by reading through the text and code examples that follow.
However, we recommend that you set up the example project yourself, so that you can try out some of the code as you learn. The project has a permissive license that allows you to use it freely.
Follow the README to the project running.

#Why use Redis for time series data?

Redis supports time series data. Time series is a great way to model any data that you want to query over time, like in this case, the ever-changing price of Bitcoin.
You can get started by following the setup instructions in the Redis documentation.

#How does async Redis work with FastAPI?

The IsBitcoinLit project is completely async. That means we use an asyncio-compatible Redis client and FastAPI's async features. The modern redis-py library includes built-in async support via redis.asyncio, so you no longer need the separate aioredis package (which is now deprecated and merged into redis-py).
If you aren't familiar with asyncio, take a few minutes to watch this primer on asyncio before continuing:

#How do you install the Redis client for Python?

We're going to start this tutorial assuming that you have a FastAPI project to work with. We'll use the IsBitcoinLit project for our examples.
Poetry is the best way to manage Python dependencies today, so we'll use it in this tutorial.
IsBitcoinLit includes a pyproject.toml file that Poetry uses to manage the project's directories, but if you had not already created one, you could do so like this:
Once you have a pyproject.toml file, and assuming you already added FastAPI and any other necessary dependencies, you can add redis-py to your project like this:
NOTE
This tutorial uses redis-py, the official Redis client for Python. It supports both synchronous and async usage. The async API lives under redis.asyncio and replaces the now-deprecated aioredis package.
The redis-py client is now installed. Time to write some code!

#How do you integrate redis-py with FastAPI?

We're going to use Redis for a few things in this FastAPI app:
  1. Storing 30-second averages of sentiment and price for the last 24 hours with Redis Time Series
  2. Rolling up these averages into a three-hour snapshot with Redis Time Series
  3. Caching the three-hour snapshot
Let's look at each of these integration points in more detail.

#Creating the time series

The data for our app consists of 30-second averages of Bitcoin prices and sentiment ratings for the last 24 hours. We pull these from the SentiCrypt API.
NOTE
We have no affiliation with SentiCrypt or any idea how accurate these numbers are. This example is just for fun!
We're going to store price and sentiment averages in a time series with Redis, so we want to make sure that when the app starts up, the time series exists.
We can use a startup event to accomplish this. Doing so looks like the following:
We'll use the TS.CREATE command to create the time series within our initialize_redis() function:
TIP
When you create a time series, use the DUPLICATE_POLICY option to specify how to handle duplicate pairs of timestamp and values.

#Storing Sentiment and Price Data in Redis

A /refresh endpoint exists in the app to allow a client to trigger a refresh of the 30-second averages. This is the entire function:
As is often the case with Python, a lot happens in a few lines, so let's walk through them.
The first thing we do is get the latest sentiment and price data from SentiCrypt. The response data looks like this:
Then we save the data into two time series in Redis with the persist() function. That ends up calling another helper, add_many_to_timeseries(), like this:
The add_many_to_timeseries() function takes a list of (time series key, sample key) pairs and a list of samples from SentiCrypt. For each sample, it reads the value of the sample key in the SentiCrypt sample, like "btc_price," and adds that value to the given time eries key.
Here's the function:
This code is dense, so let's break it down.
We're using the TS.MADD command to add many samples to a time series. We use TS.MADD because doing so is faster than TS.ADD for adding batches of samples to a time series.
This results in a single large TS.MADD call that adds price data to the price time series and sentiment data to the sentiment timeseries. Conveniently, TS.MADD can add samples to multiple time series in a single call.

#How do you calculate time series averages with Redis?

Clients use IsBitcoinLit to get the average price and sentiment for each of the last three hours. But so far, we've only stored 30-second averages in Redis. How do we calculate the average of these averages for the last three hours?
When we run /refresh, we call calculate_three_hours_of_data() to do so. The function looks like this:
There is more going on here than we need to know for this tutorial. As a summary, most of this code exists to support calls to get_hourly_average().
That function is where the core logic exists to calculate averages for the last three hours, so let's see what it contains:
Here, we use the TS.RANGE command to get the samples in the timeseries from the "top" of the hour three hours ago, until the latest sample in the series. With the AGGREGATE parameter, we get back the averages of the samples in hourly buckets.
So where does this leave us? With averages of the averages, one for each of the last three hours.

#How do you cache data with Redis in FastAPI?

Let's review. We have code that achieves the following:
  1. Gets the latest sentiment and price data from SentiCrypt.
  2. Saves the data into two time series in Redis.
  3. Calculates the average of the averages for the last three hours.
The snapshot of averages for the last three hours is the data we want to serve clients when they hit the /is-bitcoin-lit endpoint. We could run this calculation every time a client requests data, but that would be inefficient. Let's cache it in Redis!
First, we'll look at writing to the cache. Then we'll see how FastAPI reads from the cache.

#How do you write cache data to Redis?

Take a closer look at the last line of the refresh() function:
In FastAPI, you can run code outside of a web request after returning a response. This feature is called background tasks.
This is not as robust as using a background task library like Celery. Instead, Background Tasks are a simple way to run code outside of a web request, which is a great fit for things like updating a cache.
When you call add_task(), you pass in a function and a list of arguments. Here, we pass in set_cache(). This function saves the three-hour averages summary to Redis. Let's look at how it works:
First, we serialize the three-hour summary data to JSON and save it to Redis. We use the ex parameter to set the expiration time for the data to two minutes.
TIP: You need to provide a default serializer for the json.dumps() function so that dumps() knows how to serialize datetime objects.
This means that after every refresh, we've primed the cache. The cache isn't primed for long -- only two minutes -- but it's something!

#How do you read cached data from Redis?

We haven't even seen the API endpoint that clients will use yet! Here it is:
To use this endpoint, clients make a GET request to /is-bitcoin-lit. Then we try to get the cached three-hour summary from Redis. If we can't, we calculate the three-hour summary, return it, and then save it outside of the web request.
We've already seen how calculating the summary data works, and we just explored saving the summary data to Redis. So, let's look at the get_cache() function, where we read the cached data:
Remember that when we serialized the summary data to JSON, we needed to provide a default serializer for json.dumps() that understood datetime objects. Now that we're deserializing that data, we need to give json.loads() an "object hook" that understands datetime strings. That's what datetime_parser() does.
Other than parsing dates, this code is relatively straightforward. We get the current hour's cache key, and then we try to get the cached data from Redis. If we can't, we return None.

#Summary

Putting all the pieces together, we now have a FastAPI app that can retrieve Bitcoin price and sentiment averages, store the averages in Redis, cache three-hour summary data in Redis, and serve the data to clients. Not too shabby!
Here are a few notes to consider:
  1. We manually controlled caching in this tutorial, but you can also use a library like aiocache to cache data in Redis.
  2. We ran Redis commands like TS.MADD using the execute_command() method in redis-py. The same commands work in both synchronous and async contexts.

#Next steps

Now that you've built a FastAPI app with Redis, here are some ways to keep learning:
  • Try Redis OM for Python — If you want a higher-level, declarative way to model and query data in Redis, check out the Getting Started with Redis OM for Python tutorial.
  • Explore redis-py — Dive deeper into the official Python client with the redis-py documentation.
  • Learn more about Redis Time Series — Read the Redis Time Series documentation to explore advanced aggregation and filtering options.
  • Add session management — Use Redis as a session store for your FastAPI app to handle user authentication at scale.