Skip to content

Add configurable rate limit option#67

Open
sethconvex wants to merge 2 commits intomainfrom
configurable-rate-limit
Open

Add configurable rate limit option#67
sethconvex wants to merge 2 commits intomainfrom
configurable-rate-limit

Conversation

@sethconvex
Copy link
Copy Markdown
Contributor

@sethconvex sethconvex commented Jan 26, 2026

Summary

  • Allow users to configure a custom rate limit via the new rateLimitMs option
  • Default remains 600ms (uses existing rate limiter for most users)
  • Custom rates use timestamp-based rate limiting for accounts with higher limits approved by Resend

Test plan

  • All existing tests pass (27/27)
  • Build succeeds
  • Lint passes with no warnings
  • Manual testing with default rate limit (should use existing rate limiter)
  • Manual testing with custom rate limit (should use timestamp-based limiting)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an optional rateLimitMs parameter to allow customizing API call rate limits.
    • Improved rate-limiting behavior to support both the default and custom rates for more flexible request throttling.

✏️ Tip: You can customize this high-level summary in your review settings.

Allow users to configure a custom rate limit (in milliseconds between API
calls) via the new `rateLimitMs` option. This is useful for accounts that
have a higher rate limit approved by Resend.

- Default remains 600ms for most users (uses existing rate limiter)
- Custom rates use timestamp-based rate limiting stored in lastOptions table
- Added JSDoc documentation explaining when to change this value

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 26, 2026

📝 Walkthrough

Walkthrough

A new runtime option rateLimitMs was added and threaded from ResendOptions through runtime config into the component rate-limiting logic; getDelay now supports default fixed-window behavior or a timestamp-based custom rate with jitter and last-call tracking.

Changes

Cohort / File(s) Summary
Client & Public Types
src/client/index.ts
Exposed optional rateLimitMs?: number on ResendOptions and wired it into runtime config conversion and the Resend constructor.
Runtime Options
src/component/shared.ts
Added rateLimitMs to vOptions, updating the inferred RuntimeConfig to include the new numeric option.
Schema
src/component/schema.ts
Added lastApiCallTime: v.optional(v.number()) to the lastOptions table to store timestamp of the last API call for custom-rate logic.
Rate-limiting Logic
src/component/lib.ts
getDelay(ctx, rateLimitMs) refactor: preserves default fixed-window limiter when using default rate, otherwise uses timestamp-based delay with jitter and reserves a slot by updating lastApiCallTime. Callers updated to pass rateLimitMs.
Tests / Test Config
src/component/lib.test.ts, src/component/setup.test.ts
Added rateLimitMs: 600 to test option blocks and test runtime config to exercise custom-rate paths in tests.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Resend
  participant Component as "Component.makeBatch"
  participant Store as "lastOptions Store"
  participant API as "External API"

  Client->>Resend: sendEmail(options with rateLimitMs)
  Resend->>Component: makeBatch(options, runtimeConfig)
  Component->>Store: read lastApiCallTime (if custom rate)
  alt default rate (fixed-window)
    Component->>Component: use fixed-window rate limiter -> may delay
  else custom rate
    Component->>Component: compute elapsed, jitter, delay
    Component->>Store: update lastApiCallTime (reserve slot)
  end
  Component->>API: perform API call(s) after delay
  API-->>Component: response
  Component-->>Resend: result
  Resend-->>Client: deliver response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through timestamps, jitter in tow,
A tiny delay makes the calls flow,
I nudged the clock, reserved a slot,
Faster or gentler—I've got the plot! 🎩✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add configurable rate limit option' accurately and concisely summarizes the main change: introducing a new configurable rateLimitMs option. It aligns with all file changes and the PR objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Jan 26, 2026

Open in StackBlitz

npm i https://pkg.pr.new/get-convex/resend/@convex-dev/resend@67

commit: eee2480

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/component/lib.ts`:
- Around line 445-447: Guard against undefined rateLimitMs by defaulting
options.rateLimitMs (or lastOptions.options.rateLimitMs) to a safe number before
calling getDelay so it never receives undefined and returns NaN; also when
updating lastApiCallTime after computing delay, include the reserved jitter (the
same jitter used by getDelay) so the stored lastApiCallTime = now +
reservedDelay (delay including jitter) to avoid under‑reservation—update
references to getDelay(ctx, options.rateLimitMs), lastOptions.options, and
lastApiCallTime accordingly to apply the default and add the jitter when saving
the timestamp.

Comment thread src/component/lib.ts
- Default rateLimitMs to 600ms if undefined to prevent NaN
- Include jitter when storing lastApiCallTime to avoid under-reservation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant