Rebasely Beta: data may be purged

examples/MCP-tools Public

Markdown · 29 lines · 1.7 KiB · at 2090b14

---id: rate-limitstype: conceptowner: justincomponent: rate-limiterdescribes:  - src/rate-limiter/**reviewed: 2026-10-15---# Rate limitsEach client gets a token bucket: 30 tool calls to start, one more every two seconds, never more than 30. [[0004-per-client-rate-limit]] has the reasoning.## Where the pieces are- `src/rate-limiter/bucket.ts`: the arithmetic. `take(bucket, now)` refills by the time elapsed, spends one token if there is one, and returns the new bucket and a decision: `{ ok: true, remaining }` or `{ ok: false, retryAfterSeconds }`. Pure, so `test/rate-limit.test.ts` drives it with a fake clock.- `src/rate-limiter/index.ts`: the `RateLimiter` Durable Object, bound as `RATE_LIMITER`. Its one RPC method, `take()`, loads the bucket from storage, runs the arithmetic, saves the result and returns the decision.- `src/worker.ts`: names the object by the caller's `cf-connecting-ip` and turns a refusal into the message the model sees. See [[http-transport]].## Behavior worth knowing- A refused call does not spend anything, so a client that waits the time it was told always gets through.- A clock that steps backwards adds no tokens.- After each call the object sets an alarm for the moment its bucket would be full. If nothing else happens first, the alarm deletes the object's storage, and the next call starts from a fresh, full bucket, which is the same state.- Durable Objects handle one request at a time, so concurrent calls from one client cannot both spend the last token.## Changing the limitEdit `LIMIT` in `bucket.ts`. Buckets already stored keep their token count and refill toward the new capacity. Update the numbers in [[0004-per-client-rate-limit]] only by writing a new decision that supersedes it.