Rate Limits
Mailzeno enforces rate limits to protect infrastructure and ensure fair usage. Limits are applied per API key and vary by plan.
Default limits
| Plan | Per Minute | Per Day | Retention | Bulk Sending |
|---|---|---|---|---|
| Free | 5 requests | 100 emails | 7 days | No |
| Pro | 30 requests | 2,000 emails | 30 days | Yes |
How rate limiting works
Mailzeno uses a dual-window rate limiting strategy powered by Redis:
- Per-minute window — Sliding window based on the current minute bucket
- Daily window — Based on the current UTC date
Both windows are checked on every request. If either limit is exceeded, the request is rejected with a 429 status.
Rate limit headers
Every API response includes rate limit information in the response headers:
| Header | Description |
|---|---|
x-ratelimit-limit | Maximum requests allowed per window |
x-ratelimit-remaining | Remaining requests in the current window |
x-ratelimit-reset | Unix timestamp when the rate limit resets |
retry-after | Seconds to wait before retrying (only on 429) |
Example response headers
HTTP/1.1 200 OK
x-ratelimit-limit: 5
x-ratelimit-remaining: 3
x-ratelimit-reset: 1708000060When limits are exceeded
When you exceed a rate limit, the API returns a 429 status code with a retry-after header indicating how long to wait (in seconds):
{
"error": "Rate limit exceeded",
"code": "rate_limit_exceeded"
}HTTP/1.1 429 Too Many Requests
retry-after: 30
x-ratelimit-limit: 5
x-ratelimit-remaining: 0
x-ratelimit-reset: 1708000060Daily usage check
In addition to per-request rate limits, the email service layer performs a daily usage check before sending. Even if rate limit headers show remaining capacity, exceeding the daily send limit will block sends.
The @mailzeno/client SDK automatically handles rate limiting. It detects 429 responses, reads the Retry-After header, waits the specified duration, and retries up to the configured retry count.
Fail-open policy
If the Redis rate limiting service is unavailable, Mailzeno fails open — requests are allowed through rather than blocked. This ensures legitimate traffic isn't disrupted during infrastructure issues.
Handling rate limits
Best practices for handling rate limits:
- Use the SDK — It handles
429responses andRetry-Afterautomatically - Monitor headers — Check
x-ratelimit-remainingto preemptively slow down - Implement queuing — For bulk sends, queue emails and send at a controlled rate
- Upgrade your plan — If you consistently hit limits, consider upgrading to Pro
- Use idempotency keys — Prevent duplicates when retrying after rate limits
import { MailZeno } from "@mailzeno/client"
const mz = new Mailzeno(process.env.MAILZENO_API_KEY!, {
retries: 2, // Retry up to 2 times (default)
retryDelay: 500, // Base delay between retries (default)
})