Last Update: 2026-07-18
Redis Cloud と接続¶
Redis Cloud は Redis 公式のクラウドサービス。クラウド上で Redis を使える(無料プランなら 30MB の RAM ストレージ)。
FastAPI Cloud のアプリからも使える。
FastAPI Cloud のダッシュボードには Neonと接続する と同じ統合機能も用意されてるけど、2026年7月時点ではエラーで接続できなかったので、このページでは接続情報を環境変数で渡す方法で。
Redis Cloud で無料データベースを作る¶
アカウントは https://cloud.redis.io/ から作る。メールアドレス+パスワードか、Google / GitHub のソーシャルログインが選べる。
GitHub ログインには公開メールが必要
Redis Cloud の GitHub ログインは、GitHub プロフィールの公開メールアドレスを読みに行く。メールを非公開(Keep my email addresses private)にしてると access_denied で失敗するので、非公開のままにしたいならメール登録か Google ログインを使う。
ログインするとプラン選択の画面になる。Essentials と Pro が大きく並んでるけど、その下の Not ready? Try 30 MB for free から無料プランを選ぶ。

設定するのは実質3か所。
Name… データベース名。ここではfastapicloud-cacheにした。Cloud vendor…Amazon Web Services・Google Cloud・Microsoft Azureの中から選ぶ。Region…US East (N. Virginia) us-east-1を選ぶのがいいと思う。FastAPI Cloud は現時点だと選択肢はなくて、us-east-1で動いてるので。レイテンシはアプリとの距離で決まるので、ここを合わせておくのがいいはず。
無料プランの内訳は 1 database・30MB RAM・30 connections・100 ops/sec。学習用途なら十分。Price $0/month になってるのを確認して Create database を押す。
作成できた。

接続情報を環境変数で渡す¶
データベース一覧の Connect ボタンで接続 URL を確認できる。
FastAPI Cloud のアプリから使う前に疎通確認しておくと安心。uv run --with redis なら、プロジェクトに依存を追加せずローカル環境で試せる。
export REDIS_URL='redis://default:<パスワード>@<ホスト>:<ポート>'
uv run --with redis python -c "
import os, redis
print(redis.from_url(os.environ['REDIS_URL']).ping())
"
True が返ってくれば Redis Cloud 側は OK。あとはこの URL を、FastAPI Cloud のアプリの Environment Variables に REDIS_URL として登録する。パスワードを含むので Secret をオンにする。

コードから使う¶
redis-py の asyncio クライアントで、環境変数 REDIS_URL から接続する。
動作確認とレイテンシ測定を兼ねて、まずは PING の往復時間を返すエンドポイントを作ってみる。
import os
import time
import redis.asyncio as redis
from fastapi import FastAPI
redis_client = redis.from_url(os.environ["REDIS_URL"], decode_responses=True)
app = FastAPI()
@app.get("/redis-ping")
async def redis_ping():
ok = await redis_client.ping()
t = time.perf_counter()
for _ in range(10):
await redis_client.ping()
avg_ms = (time.perf_counter() - t) / 10 * 1000
return {"ping": ok, "avg_rtt_ms": round(avg_ms, 2)}
計測ループの前に 1回 ping() してる(ok = await redis_client.ping())のは、TCP 接続の確立と認証をここで済ませておくため。redis-py のコネクションプールは最初のコマンドを打った瞬間に初めて接続を張るので、1発目はその分だけ値がぶれる。先に接続しておけば、後続の 10回は確立済みの接続を使い回した素の往復時間だけを測れる。
fastapi deploy でデプロイして、公開 URL の /redis-ping を開くと結果が JSON で返ってくる。
レイテンシを実測する¶
同じアプリをローカル環境と FastAPI Cloud の両方で動かして、/redis-ping の avg_rtt_ms(PING 10回の平均)を数回ずつ比べてみた。
| 実行場所 | avg RTT |
|---|---|
| ローカル環境 → Redis Cloud(us-east-1) | 182〜189 ms |
| FastAPI Cloud(us-east-1) → Redis Cloud(us-east-1) | 1.3〜1.7 ms |
- FastAPI Cloud からは 2 ms を切る。us-east-1 の Redis Cloud と同一リージョン相当の近さで、キャッシュとして十分実用的なはず。
- 手元から直結すると約100倍遅い。Redis は 1回のリクエスト処理で小さいコマンドを何度も発行しがちなので、この差はそのまま体感速度に響く。
- なので開発中はローカルに立てた Redis を使って、本番だけ
REDIS_URLを Redis Cloud に向けるのが定石。環境変数で切り替える作りにしておけば、コードは共通のまま。
Neon(PostgreSQL)と比べると
※どちらも無料プラン同士の比較(Redis Cloud は 30MB・100 ops/sec の Free、Neon も Free プラン)
キャッシュが DB より速いっていうイメージを確かめたくて、同じアプリから us-east-1 の Neon にも同じ測り方(各操作 10回の平均)で読み書きしてみた。FastAPI Cloud・Redis Cloud・Neon が全部 us-east-1 に揃ってるので条件は互角のはず、計測は15回実行した。
| 操作 | Redis Cloud | Neon |
|---|---|---|
素の往復(PING / SELECT 1) |
1.6〜2.0 ms | 1.1〜3.6 ms |
読み込み(GET / 1行 SELECT) |
1.7〜2.8 ms | 1.1〜3.4 ms |
書き込み(SET / 1行 UPDATE) |
1.7〜3.8 ms | 1.8〜4.0 ms |
予想に反する感じで、1行レベルの読み書きならそんなに値は変わらなかった。平均では Neon のほうがやや遅い(読み込みで 1.1〜1.2倍、書き込みで 1.5倍弱)けど、Neon が Redis を上回るときもある。はっきり違うのはばらつきで、Redis の素の往復が 1.6〜2.0 ms に収まるのに対して、Neon は 1.1〜3.6 ms と 3倍以上振れる。
なので同一リージョンなら 1回の読み書きの速さは大差なくて、キャッシュが効くのは JOIN や集計みたいに DB 側の仕事が重いクエリの結果や、計算済みの値を使い回すときなのかも。あと Neon はアイドルが続くと自動サスペンドするので、復帰直後の 1回目だけは数百 ms〜数秒かかる(この計測ではウォームアップで除外してる)。
測定に使ったコード
asyncpg(uv add asyncpg)で Neon に直接つないで、/redis-ping と同じ要領で各操作 10回の平均を返すエンドポイント。avg_ms() の最初の await op() は計測に入れないウォームアップで、プリペアドステートメント作成みたいな初回コストをここで済ませてる。
Neon の接続文字列は Neonと接続する と同じく環境変数 DATABASE_URL で渡す。末尾のクエリパラメータ(channel_binding=require など)には asyncpg が解釈できないものがあるので、? 以降を落として ssl="require" を明示してる。
import asyncpg
async def avg_ms(op, n=10):
await op()
t = time.perf_counter()
for _ in range(n):
await op()
return round((time.perf_counter() - t) / n * 1000, 2)
@app.get("/latency-compare")
async def latency_compare():
await redis_client.set("bench", "hello")
dsn = os.environ["DATABASE_URL"].split("?")[0]
conn = await asyncpg.connect(dsn, ssl="require")
try:
await conn.execute(
"CREATE TABLE IF NOT EXISTS kv (key text PRIMARY KEY, value text)"
)
await conn.execute(
"INSERT INTO kv VALUES ('bench', 'hello') ON CONFLICT (key) DO NOTHING"
)
return {
"redis": {
"ping": await avg_ms(redis_client.ping),
"get": await avg_ms(lambda: redis_client.get("bench")),
"set": await avg_ms(lambda: redis_client.set("bench", "hello")),
},
"neon": {
"select1": await avg_ms(lambda: conn.fetchval("SELECT 1")),
"select": await avg_ms(
lambda: conn.fetchval("SELECT value FROM kv WHERE key = 'bench'")
),
"update": await avg_ms(
lambda: conn.execute(
"UPDATE kv SET value = 'hello' WHERE key = 'bench'"
)
),
},
}
finally:
await conn.close()
ダッシュボードからの統合(2026年7月時点はエラー)¶
本来は Neonと接続する と同じように、ダッシュボードから OAuth でつないで REDIS_URL を自動で注入してもらえるはず。
cf. Redis Cloud Integration - FastAPI Cloud
アプリ詳細の Integrations タブを開いて、Connect Integration を押す。

Add Integration のダイアログで Redis Cloud を選ぶ。

認証方法は Google か GitHub のソーシャルログインだけ。メール+パスワードで作った Redis Cloud アカウントのままでは、このフローには乗れない。

Google でログインすると、アカウント連携(公式ドキュメントでいう「Connect Your Redis Cloud Account」のステップ)自体は成功する。チーム設定の Integrations に Redis Cloud が Connected として表示されて、Integration ID も発行される。
けれど、その次の「Connect a Database to Your App」で先に進めなくなる。アプリの Integrations から Redis Cloud を選んでデータベースを紐付けようとすると、サブスクリプションとデータベースを選ぶ画面に進む前に Unable to load subscriptions from Redis Cloud. Please try again. になる。

試したこと(いずれも効果なし):
- 連携の切断と再接続
- シークレットウィンドウでのやり直し
- Redis Cloud 側で REST API の有効化。
Team & APIのAPI KeysタブにEnable APIボタンがある(有効化は無料)。サブスクリプション一覧の取得は REST API 経由のはずなので試したけど、変わらず。

ブラウザの開発者ツールで見ると、api.fastapicloud.com のサブスクリプション取得エンドポイントが HTTP 500 を返してた。URL に入ってる ID は統合ごとに発行されるもので、接続をやり直すたびに変わる。
GET https://api.fastapicloud.com/api/v1/integrations/redis/12345678-abcd-abcd-abcd-123456789abc/subscriptions
HTTP/2 500
date: Tue, 14 Jul 2026 02:09:34 GMT
content-type: application/json
content-length: 77
access-control-allow-credentials: true
access-control-allow-origin: https://dashboard.fastapicloud.com
server: cloudflare
vary: Origin
x-envoy-upstream-service-time: 5102
cf-cache-status: DYNAMIC
cf-ray: a1acfc4a7ea2d3fa-KIX
X-Firefox-Spdy: h2
x-envoy-upstream-service-time: 5102、つまりバックエンドが 5 秒かかった末の失敗なので、FastAPI Cloud から Redis Cloud への呼び出しがタイムアウトかエラーになってそう。
一方、データベース自体はどこからでも正常につながるし、Redis Cloud の REST API を自分の API キー(Team & API の API Keys で発行するアカウントキーとユーザーキー)で直接叩いても、サブスクリプションは正常に返ってくる。
curl -s -H "x-api-key: <アカウントキー>" -H "x-api-secret-key: <ユーザーキー>" \
https://api.redislabs.com/v1/fixed/subscriptions
{
"accountId" : 1234567,
"subscriptions" : [ {
"id" : 7654321,
"name" : "fastapicloud-cache",
"status" : "active",
"planName" : "30MB",
"provider" : "AWS",
"region" : "us-east-1",
"price" : 0,
"maximumDatabases" : 1,
"databaseStatus" : "active"
} ]
}
Pro 用の GET /v1/subscriptions のほうは空リストが返る(エラーにはならない)。
つまり Redis Cloud の API はこのアカウントに対して完全に正常で、失敗してるのはベータ版の FastAPI Cloud 側っぽい。Pro と Essentials で一覧のエンドポイントが分かれてるから、統合が Pro 側しか見てない可能性もありそう。統合が直れば、環境変数の手動登録は統合の自動注入に置き換えられるはず。