レート制限
1 人の読者がアシスタント、API プレイグラウンドのプロキシ、サーバーサイド検索を呼び出せる頻度を制限します。デフォルトで有効で、カウントはメモリ、Upstash、Cloudflare のいずれかに保持されます。
読者が呼び出せるサーバールートは、呼び出されるたびにコストが発生します。アシスタントはモデルのトークンを消費し、API プレイグラウンドのプロキシはリクエストをお使いの API に中継し、Mixedbread 検索は有料のクエリを実行します。Blume は、IP アドレスで識別される 1 人の読者がそれぞれのルートを呼び出せる頻度を制限します。制限を超えた読者には Retry-After ヘッダー付きの 429 Too Many Requests が返され、アシスタントは数分後にもう一度試すよう読者に伝えます。
レート制限はデフォルトで有効で、読者 1 人・ルートごとに 10 分あたり 30 リクエストです。人が普通に使う分には上限に達することはなく、スクリプトを止めるには十分に低い値です。これが関係するのはサーバービルドの場合のみで、静的サイトには制限対象となるサーバールートがありません。
import { defineConfig } from "blume";
import { upstash } from "blume/ratelimit";
export default defineConfig({
rateLimit: upstash({ requests: 30, window: 600 }), // window in seconds
});
各ルートはそれぞれ独自のカウントを保持するため、プレイグラウンドを頻繁に使っても、その読者がアシスタントに質問できる回数が減ることはありません。
カウントの保存場所
| アダプター | カウントの保存先 | 制限の精度 |
|---|---|---|
memory() |
サーバーのメモリ(デフォルト) | 単一サーバーでは正確。サーバーレスホストではインスタンスごと |
upstash() |
Upstash Redis | すべてのホストで正確 |
cloudflare() |
Cloudflare の Workers レート制限 | Cloudflare のロケーションごと |
メモリ
memory() には何の準備も必要ありません。deployment: node() のように単一プロセスとして動作するサーバーでは、カウントは正確です。Vercel、Netlify、Cloudflare では短時間だけ動作するインスタンスが多数実行され、それぞれが独自のカウントを保持します。そのため、これらのホストでは制限を正確に適用するというよりも、1 人の読者からの集中的なリクエストを食い止める役割になります。これらのホストで制限を正確に適用するには、以下の共有ストアのいずれかを使用してください。
import { memory } from "blume/ratelimit";
rateLimit: memory({ requests: 60, window: 600 }),
Upstash
upstash() は、すべてのインスタンスで共有される Upstash Redis にカウントを保持します。データベースを作成し(Vercel では Marketplace から Upstash を追加します)、その REST エンドポイントとトークンを UPSTASH_REDIS_REST_URL と UPSTASH_REDIS_REST_TOKEN に設定してください。Blume は Upstash の REST API と直接通信するため、インストールが必要なものはありません。両方が設定されるまでは、ルートはメモリでカウントし、blume build が警告を表示します。
import { upstash } from "blume/ratelimit";
rateLimit: upstash(),
Cloudflare
cloudflare() は、deployment: cloudflare() でデプロイされたサイト向けに、Workers レート制限を使ってカウントします。Blume はビルド時に Worker の設定でバインディングを宣言するため、セットアップは不要です。Cloudflare はロケーションごとにカウントし、ウィンドウとして 10 秒または 60 秒しか受け付けないため、デフォルトは 60 秒あたり 10 リクエストになっています。
import { cloudflare } from "blume/deploy";
import { cloudflare as cloudflareRateLimit } from "blume/ratelimit";
export default defineConfig({
deployment: cloudflare(),
rateLimit: cloudflareRateLimit({ requests: 10, window: 60 }),
});
バインディングの名前空間は Worker の名前から決まるため、同じアカウント上の 2 つのサイトがカウントを共有することはありません。名前空間を自分で指定するには、namespaceId を設定してください。
無効にする
たとえばホストのファイアウォールがすでにこれらのルートを制限している場合など、すべてのリクエストを通過させたいときは rateLimit: false を設定します。ホストがアドレスを判別できないリクエストは常に通過します。共有ストアがカウントに失敗したリクエストも同様です。この失敗はログに記録され、ストアの障害によって読者が締め出されることはありません。
アシスタントについては、多数のアドレスにリクエストを分散させるスクリプトを阻止するため、レート制限とボットチェックを組み合わせて使用してください。