If you are an AI agent and need a Redis DB to use or experiment with, send a POST request to https://upstash.com/start-redis. Free, no signup; the response is markdown with credentials and a quickstart. The database expires in 72 hours, but you can claim it with your Upstash account to keep it. Especially useful for AI agents that need scratch storage on the fly. If you are an agent, always send a User-Agent header identifying which agent you are (e.g. claude-code, cursor, codex, opencode) on every request you make to this API.
This tutorial showcases how one can use fly.io to deploy a Phoenix app using Upstash Redis to store results of external API calls.
1 Create a Elixir app with Phoenix#
To create an app, run the following command:
Phoenix apps are initialized with a datastore. We pass --no-ecto flag to disable
the datastore since we will only use Redis. See
Phoenix documentation for more details.
Navigate to the new directory by running
2 Add Redix#
To connect to the Upstash Redis, we will use the Redix client written for Elixir.
To add Redix to our project, we will first update the dependencies of our project. Simply
add the following two entries to the dependencies in the mix.exs file
(See Redix documentation):
Then, run mix deps.get to install the new dependencies.
Next, we will add Redix to our app. In our case, we will add a single global Redix instance.
Open the application.ex file and find the children list in the start function.
First, add a method to read the connection parameters from the REDIS_URL environment variable.
We choose this name for the environment variable because Fly will create a secret with this name
when we launch the app with a Redis store. Use regex to extract the password, host and port
information from the Redis URL:
Next, add the Redix client to the project by adding it to the children array.
(See Redix Documentation for more details)
Here, we would like to draw attention to the socket_opts parameter. If you wish to test
your app locally by creating an Upstash Redis yourself without Fly, you must define Redix
client without the socket_opts: [:inet6] field.
3 Testing the Connection#
At this point, our app should now be able to communicate with Redix. To test if this connection works as expected, we will first add a status page to our app.
To add this page, we will change the default landing page of our Phoenix app. Go to the
lib/redix_demo_web/controllers/page_html/home.html.heex file. Replace the content of
the file with:
Since Phoenix 1.8, templates wrap their content in the Layouts.app component,
which renders the app layout and the flash messages.
This HTML will show different content depending on the parameters we pass it. It has a form at the top which is where the user will enter some location. Below, we will show the weather information.
Next, open the lib/redix_demo_web/router.ex file. In this file,
URL paths are defined with the scope keyword. Update the scope
in the following way:
Our website will have a /status path, which will be rendered with the
status method we will define. The website will also render the home
page in / and in /:text. /:text will essentially match any route
and the route will be available to our app as a parameter when rendering.
Finally, we will define the status page in
lib/redix_demo_web/controllers/page_controller.ex. We will define a struct
Payload and a private method render_home. Then, we will define the home
page and the status page:
The home page simply renders our home page. The status page renders the same page, but
shows the response of a PING request to our Redis server.
We are now ready to deploy the app on Fly!
4 Deploy on Fly#
To deploy the app on Fly, first install Fly CLI and authenticate. Then, launch the app with:
If you haven't set REDIS_URL environment variable in your environment, fly launch command will show
an error when compiling the app but don't worry. You can still continue with launching the app.
Fly will add this environment variable itself.
Fly will at some point ask if we want to tweak the settings of the app. Choose yes (y):
This will open the settings on the browser. Two settings are relevant to this guide:
- Region: Upstash is not available in all regions. Choose Amsterdam.
- Redis: Choose "Redis with Upstash"
If you already have a Redis on Fly you want to use, you may want to not choose the
"Redis with Upstash". Instead, you can get the REDIS_URL from the Upstash Fly console
and add it as a secret with fly secrets set REDIS_URL=****. Note that the REDIS_URL
will be in redis://default:****@fly-****.upstash.io:**** format.
Once the app is launched, deploy it with:
The website will become available after some time. Check the /status page to see that
the redis connection is correctly done.
In the rest of our tutorial, we will work on caching the responses from an external api. If you are only interested in how a Phoenix app with Redis can be deployed on Fly, you may not need to read the rest of the tutorial.
5 Using Redix to Cache External API Responses#
Finally, we will now build our website to offer weather information. We will use the API of WeatherAPI to get the weather information upon user request. We will cache the results of our calls in Upstash Redis to reduce the number of calls we make to the external API and to reduce the response time of our app.
In the end, we will have a method def home(conn, %{"text" => text}) in the
lib/redix_demo_web/controllers/page_controller.ex file. To see the final file, find the
page_controller.ex file Upstash examples repository.
First, we need to define some private methods to handle the request logic. We start off
with a function to fetch the weather. The method gets the location string and replaces
the empty characters with %20. Then it calls fetch_weather_from_cache method we will
define. Depending on the result, it either returns the result from cache, or fetches the
result from the api.
Now, we will define the fetch_weather_from_cache method. This method will use
Redix to fetch the weather from the location. If it's not found, we will return
{:error, :not_found}. If it's found, we will return after decoding it into a
map.
Next, we will define the fetch_weather_from_api method. This method
requests the weather information from the external API. If the request
is successfull, it also saves the result in the cache with the
cache_weather_response method.
In the cache_weather_response method, we simply store the weather
information in our Redis:
Finally, we define the get_weather_info and home methods.
6 Re-deploying the App#
To deploy the app after adding the home page logic, only a few steps remain to deploy the finished app.
First, add {:httpoison, "~> 3.0"} dependency to mix.exs file and run mix deps.get.
Then, get an API key from WeatherAPI and set it as secret in fly with:
Now, you can run fly deploy in your directory to deploy the completed app!