Cloudflare KV vs Upstash Redis:実世界パフォーマンスベンチマーク徹底比較
デプロイプラットフォームを選ぶ際、実際の運用環境におけるパフォーマンスを公平に比較するのは非常に難しいものです。とりわけサーバーレスプラットフォームは、グローバルエッジ配置による超低レイテンシを売りにしているため、なおさらです。しかし、肝心のデータ取得が遅ければ、低レイテンシにどんな意味があるのでしょうか?APIがユーザーのすぐ近くで動作していても、データ取得のために地球の裏側へのネットワーク往復が発生するようでは、快適なユーザー体験は望めません。
従来、コンピュートとストレージは単一のサーバー上、あるいはせいぜい同一データセンター内に共存していました。しかしサーバーレスやエッジ関数の台頭により、コンピュートとストレージの分離(デカップリング)が進みました。これはスケーラビリティと可用性の面で大きなメリットがありますが、同時に「レイテンシ」という新たな課題も生み出しました。近年はAPIをグローバルエッジネットワークへ展開することが簡単になりましたが、データについてはどうでしょうか。データはまだ後れを取っており、しかし確実に追い上げてきています。
本記事では、2つのサーバーレスデータストア「Cloudflare KV」と「Upstash Redis」のパフォーマンスを比較します。どちらもサーバーレスかつグローバル分散型ですが、そのアプローチは大きく異なります。Cloudflare KVはプル型キーバリューストアであり、Upstashはアクティブレプリケーションを採用したRedis互換サービスです。
2つのアーキテクチャ
プル型(Pull-based):データは基本的に中央の場所に保存され、ユーザーからのリクエスト時にのみエッジノードへ移動します。これがCloudflare KVの採用する方式です。
アクティブレプリケーション(Active replication):データはすべてのエッジロケーションに保存され、データストア自身が同期を維持します。更新内容は即座に全リージョンへ複製されます。これがUpstash、ひいてはVercelの採用する方式です。
キャッシングとは、要するにキーと値のペアを保存することです。シンプルな概念でありながら非常に一般的であり、2つのデータストアのパフォーマンスを比較するうえで絶好の題材でもあります。ここではシンプルなキャッシュシナリオを使って、両者の性能を比べていきます。
ベンチマークの条件
何を測定しているのか?
Cloudflare WorkerがCloudflare KVおよびUpstash Redisから1つの値を読み取る際のレイテンシを計測します。
- Cloudflare Worker × 1
- キー数:1,000個
- データサイズ:4KB〜64KB(ランダム)
- 全キーに60秒のTTL
- Workerを呼び出すリージョン:20地域
- 約10リクエスト/秒
RPSを過度に上げなくてもキャッシュヒットが得られるよう、意図的に小さめのキースペースを選びました。
Workerコード
Worker自体は非常にシンプルで、Redisから読み取り、KVから読み取り、それぞれのレイテンシを返して後から評価できるようにしています。
app.get("/test", async (c) => {
const redis = Redis.fromEnv(c.env);
const key = Math.floor(Math.random() * 1_000).toString();
const minValueSize = 4 * 1024;
const maxValueSize = 64 * 1024;
const ttlSeconds = 60;
const randomValue = new TextDecoder().decode(
crypto.getRandomValues(
new Uint8Array(
Math.floor(Math.random() * (maxValueSize - minValueSize)) +
minValueSize,
),
),
);
const beforeRedis = performance.now();
const redisResponse = await redis.get(key);
const redisLatency = performance.now() - beforeRedis;
if (!redisResponse) {
await redis.set(key, randomValue, {
ex: ttlSeconds,
});
}
const beforeKV = performance.now();
const kvResponse = await c.env.ANDREAS_KV_BENCHMARK.get(key);
const kvLatency = performance.now() - beforeKV;
if (!kvResponse) {
await c.env.ANDREAS_KV_BENCHMARK.put(key, randomValue, {
expirationTtl: ttlSeconds,
});
}
return c.json({
kvLatency,
redisLatency,
});
});
結果:グローバルレイテンシ
約30分間ベンチマークを実行したところ、2つのデータストアの間には早くも顕著な差が見られました。

画像クリックで拡大表示
ご覧のとおり、Cloudflare KVは一貫してUpstash Redisより低速でした。これは意外な結果です。CloudflareはKVを低レイテンシとして宣伝しており、Workerと同じプラットフォーム上で動作しているからです。デフォルトでは全リージョンにデータを保持しないとはいえ、数分経過すれば、Workerが稼働しているリージョンにデータがキャッシュされるはずだと考えていました。
もしかすると、システムがデータをコロケーションするほどの負荷がかかっていないのかもしれません。そこで特定のリージョンを切り出し、負荷を大幅に増やして変化があるか確認してみましょう。
シングルリージョンでの検証
次に、はるかに高いRPSでの単一リージョンの結果を見てみます。理論的には、このリージョンのキャッシュをすべてウォームアップし、宣伝文句どおりの超低レイテンシを実現できるはずです。
このテストは最初のものと同一ですが、Workerを単一リージョンから約400 RPSで呼び出している点だけが異なります。

画像クリックで拡大表示
KVのレイテンシは大幅に改善しました:
- P90: 742ms → 115ms
- P99: 1,336ms → 560ms
どうやら、Cloudflareが実際にデータを稼働中のWorkerの近くへ複製するには、かなりの高負荷が必要なようです。それでもなお、Upstash Redisのレイテンシにはるかに及ばないというのが実情です。P90レイテンシ115msなら決して悪くありませんが、0.5秒を超えるP99レイテンシは明確に体感できるレベルでしょう。しかも、データを確実に複製させるために毎秒約400リクエストという負荷をかけている点に注意してください。これは中小規模のAPIが通常受けるトラフィックをすでに上回っています。
興味深いことに、CloudflareがデータをWorkerに近づけたり遠ざけたりしたタイミングを、下記の画像内で確認できます。

画像クリックで拡大表示
料金比較
コストに触れずに公平な比較とは言えません。
ここで最大のコスト要因となるのは、各データストアへのアクセスにかかるリクエスト単価です。
CloudflareはKV読み取り100万回あたり0.50ドル、一方UpstashはRedisコマンド100万回あたり1ドルです。その他にも違いがあり、ストレージ料金はCloudflareが高く、帯域幅料金はUpstashが高い傾向にあります。ただし、このシナリオにおいてはいずれも主要なコスト要因ではありません。
- Cloudflare Pricing
- Upstash Pricing
Upstashはあなたに合っているか?
これは自分自身でしか答えられない問いです。
当然ながら私たちにはバイアスがあり、自社製品とその価値を心から信じています。その点は割り引いてお読みください。
小規模〜中規模のAPIを運用しているなら、コストはほぼ無視できるレベルのため、レイテンシを最優先で考えるべきです。APIのトラフィックが多い場合は、Upstashの固定料金プランの方がCloudflare KVよりも安くなります。
必要な操作がset、get、list程度のシンプルさで、Workersプラットフォームから離れる予定がなく、アプリケーションとして高レイテンシが許容できるのであれば、Cloudflare KVが適しているかもしれません。すべてが同じ場所で完結し、余計な心配が不要だからです。
これらの質問にひとつでも「いいえ」と答えたなら、Upstashを試してみることをおすすめします。Redisにはpub/sub、ソート済みセット、ハッシュなど、Cloudflare KVにはない豊富な機能があり、Upstashはそのすべてをサポートしています。すでにRedisを使用しているのであれば、アプリケーションの接続先をUpstashに向けるだけで、そのまま動作します。コードの変更は一切不要です。
まとめ
Cloudflare KVは優れた製品ですが、Redisのような本格的なデータベースの代替品ではありません。レイテンシが問題にならないシンプルなユースケースには適しています。
ご質問などがあれば、DiscordまたはXでお気軽にお声がけください。
-
UpstashがPlanTripAIの急成長を支える技術戦略と成功事例を徹底解説
本記事では、AI駆動型の旅行プランニングスタートアップ「PlanTripAI」の開発において、Upstashが果たした重要な役割について詳しく解説します。Upstash Redisの活用は、ユーザーアクセス用のライセンスキーの保存や、旅行コンテンツの効率的な保存・キャッシュといった重要な要素の管理に不可欠でした。さらに、UpstashのRate Limit機能はシステム保護において重要な役割を担っています。リクエスト頻度を適切に制御することで、潜在的なセキュリティ脅威から堅牢に守り、ユーザーへ快適で中断のないサービスを提供することを可能にしています。 plantripai.comは、目的地、滞
-
Redis GETRANGEコマンドの使い方 – 文字列値から部分文字列を取得する方法
このチュートリアルでは、Redisデータストア内の指定したキーに保存された文字列値の部分文字列(サブストリング)を取得する方法を解説します。この操作には、RedisのGETRANGEコマンドを使用します。 GETRANGEコマンドとは GETRANGEコマンドは、start(開始位置・範囲に含まれる)とend(終了位置・範囲に含まれる)という2つのオフセットを受け取り、取得する部分文字列の開始インデックスと終了インデックスを指定します。 インデックスは0ベースで、0が最初の文字、1が2番目の文字を表します。また、負の数値を使うことで、文字列の末尾からのオフセットも指定できます。-1は最後の文字