Google PlayGoogle Play
Temp Mail Logo

Temp Mail safeguards your privacy while keeping your inbox free from spam.

← Back to Blog
Privacy

Rate Limits, Bursts and Concurrent Waits: Reading the Headers

Best-TempMail Team2026-09-25
Rate Limits, Bursts and Concurrent Waits: Reading the Headers

Rate Limits, Bursts and Concurrent Waits: Reading the Headers

To handle rate limits in an automated email testing pipeline, your code must parse the response headers (such as X-RateLimit-Limit or X-RateLimit-Remaining) to implement exponential backoff or delay requests before a 429 error occurs.

When automating OTP verification in end-to-end tests, the primary bottleneck is rarely the application logic itself, but the infrastructure's protective layers. Developers frequently encounter "flaky" tests that pass in isolation but fail in CI/CD. This is usually the result of hitting api rate limit headers during a burst of parallel test executions. If your test runner spawns twenty headless browsers simultaneously, each requesting a new inbox, the API will interpret this as a denial-of-service attempt rather than a legitimate test suite.

The Mechanics of API Rate Limit Headers

Most modern APIs use a variation of the Token Bucket or Leaky Bucket algorithm to manage traffic. When you make a request, the server evaluates your IP address or API key against a quota. The result of this evaluation is appended to the HTTP response headers.

To build a resilient test suite, you must monitor three specific headers:

X-RateLimit-Limit

Label: The total quota. This header defines the maximum number of requests allowed within a specific window (e.g., 150 requests per hour). It is a static value based on your current tier.

X-RateLimit-Remaining

Label: The current balance. This is the most critical header for logic branching. It tells you exactly how many requests you can make before the server returns a 429 status code. If this number hits zero, any subsequent request will be rejected.

X-RateLimit-Reset

Label: The cooldown timer. This is typically a Unix timestamp indicating when the current window resets. If you hit a limit, your code should calculate the difference between the current time and this timestamp to determine exactly how long to sleep.

Implementation: Handling Limits in Node.js

Using the fetch API, you can intercept these headers to create a self-throttling request wrapper. This prevents your CI/CD pipeline from crashing when it hits the free tier limits (150 requests per hour).

const API_BASE = 'https://api.best-tempmail.com/v1';

async function createInboxWithThrottling() {
    const response = await fetch(`${API_BASE}/inboxes`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' }
    });

    const remaining = response.headers.get('X-RateLimit-Remaining');
    const resetTime = response.headers.get('X-RateLimit-Reset');

    if (response.status === 429) {
        const waitTime = (parseInt(resetTime) * 1000) - Date.now();
        console.warn(`Rate limit exceeded. Sleeping for ${waitTime}ms`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
        return createInboxWithThrottling(); // Retry
    }

    if (remaining && parseInt(remaining) < 10) {
        console.warn('Approaching rate limit. Slowing down execution.');
    }

    return await response.json();
}

Implementation: Handling Limits in Python

For QA engineers using Pytest or Robot Framework, the requests library provides a straightforward way to inspect headers. The following logic demonstrates how to handle the /wait endpoint, which is essential for reducing request volume.

import requests
import time

def get_message_with_backoff(inbox_id):
    url = f"https://api.best-tempmail.com/v1/inboxes/{inbox_id}/wait"
    
    # The /wait endpoint holds for 55s, reducing the need for polling
    response = requests.get(url)
    
    if response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 60))
        time.sleep(retry_after)
        return get_message_with_backoff(inbox_id)
        
    data = response.json()
    if data.get("message") is None:
        # 200 OK but message: null means the 55s timeout was reached
        print("No message received yet. Retrying...")
        return get_message_with_backoff(inbox_id)
        
    return data["message"]

Polling vs. Long-Polling (The /wait Endpoint)

A common mistake in email automation is aggressive polling. If your code checks for a new message every 2 seconds, you will exhaust a 150-request quota in exactly five minutes.

Standard Polling

Label: Request Efficiency: Low. Label: Rate Limit Risk: High. Label: Implementation: A loop that sends a GET request, sleeps for 5 seconds, and repeats. This wastes bandwidth and quota on empty responses.

Long-Polling (/wait)

Label: Request Efficiency: High. Label: Rate Limit Risk: Low. Label: Implementation: A single request to the /wait endpoint. The server holds the connection open for up to 55 seconds. It returns the message immediately if it arrives, or a 200 OK with message: null if the timer expires. This uses one request instead of twenty.

For automated email tools, infrastructure like Best-TempMail is designed to handle these long-held connections, allowing your test suite to remain idle while waiting for the SMTP server to deliver the verification code. We use standard protocols like SPF and DKIM to ensure deliverability to our infrastructure.

Strategies for High-Concurrency Testing

When running tests in parallel, the api rate limit headers are shared across all threads originating from the same IP. To prevent a "thundering herd" problem, implement these three strategies:

  1. Global Throttler: Use a singleton pattern or a shared state (like a Redis counter) to track the X-RateLimit-Remaining value across all test workers.
  2. Jittered Retries: When a 429 is hit, do not have every worker retry at the exact same second. Add a random "jitter" (1-5 seconds) to the sleep duration to stagger the load.
  3. Pre-Provisioning: If your test suite requires 50 inboxes, provision them sequentially before starting the parallel execution of the browser tests. This separates the "setup" rate limits from the "execution" rate limits.

When to Use Dedicated Email Testing Infrastructure

Choosing the right approach depends on the scale of your QA operations.

Use this infrastructure when:

  • You need to verify the content of transactional emails (links, OTPs, HTML rendering).
  • You are running tests in a CI/CD environment where manual inbox access is impossible.
  • You need to isolate test data by using a unique temp mail address for every single test run.

Do NOT use this infrastructure when:

  • You need to send outbound emails (the API is receive-only).
  • You are testing deliverability to specific consumer providers like Gmail or Outlook.
  • You require permanent storage for emails (inboxes expire after 2 hours on the free tier).

Honest Limitations and Constraints

No API is infinite. To maintain stability for all users, the following constraints are enforced on the free tier:

  • Inbox Creation: Limited to 3 new inboxes per day per IP address. This prevents automated account creation abuse.
  • Request Quota: 150 requests per hour. This is sufficient for small to medium test suites but will require optimization (like using the /wait endpoint) for larger pipelines.
  • Data Retention: Messages and inboxes are automatically purged after 2 hours. Your tests must be designed to complete within this window.
  • No Custom Domains: The API does not support custom domain mapping for incoming mail.

If you need a reliable testing tier, Best-TempMail offers plans that increase these limits for enterprise-level CI/CD requirements.

FAQ

Why does the /wait endpoint return a 200 status code with a null message?

This is a successful timeout. It means the connection was held for the full 55 seconds, but no email was delivered to that address. Your code should interpret this as a signal to either retry the wait or fail the test.

How do I handle the "Retry-After" header?

The Retry-After header is often returned with a 429 status code. It is an integer representing the number of seconds you must wait before the server will accept another request. Always prioritize this value over your own internal sleep timers.

Can I bypass the 3-inbox-per-day limit?

No. This limit is strictly enforced to prevent platform abuse. For higher volume requirements, you must upgrade to a tier that supports professional testing volumes.

What happens to my rate limit if I use multiple API keys?

Rate limits are typically tied to the source IP address for the free tier. Using multiple keys from the same CI/CD runner will not increase your quota.

Is there a way to see my current usage without making a request?

Currently, the only way to check your status is by inspecting the api rate limit headers returned in your last successful or failed request.

By integrating these header-parsing strategies, you can transform a fragile test suite into a resilient one. Using Best-TempMail's API effectively requires moving away from aggressive polling and toward a header-aware, wait-based architecture.

Free · Instant · Anonymous

Your temp mail is ready right now

No signup, no password. A disposable inbox waiting the moment you open the page.

Get My Free Temp Mail →