Skip to main content
GOV.UK Notify enforces rate limits to ensure fair usage and system stability. This page explains the different types of limits and how to work within them.

Types of Limits

Notify enforces two types of limits:

Per-minute rate limit

Maximum requests per minute per API key type

Daily message limits

Maximum notifications per day by channel (SMS, email, letter)

Per-Minute Rate Limits

How It Works

The per-minute rate limit uses a token bucket algorithm that:
  1. Refills tokens at a constant rate (based on your service’s rate limit)
  2. Consumes one token per API request
  3. Rejects requests when bucket is empty
  4. Allows short bursts above the average rate

Rate Limit by Key Type

Rate limits vary by API key type:
Key TypeDefault Rate LimitBurst Capacity
Live (Normal)3,000/min1,001 tokens
Team3,000/min1,001 tokens
Test (Trial)3,000/min1,001 tokens
Rate limits are configurable per service. Contact support to request a higher rate limit if needed.

Burst Capacity

The token bucket allows bursts above the average rate:
  • Bucket max: min(ceil(rate_limit / 3) + 1, 1001)
  • Bucket min: 1 token
  • Replenish rate: rate_limit / 60 tokens per second
For a 3,000/min rate limit:
  • Replenishes at 50 tokens/second
  • Max bucket size: 1,001 tokens
  • Can burst to ~1,000 requests before throttling

Rate Limit Response

When you exceed the per-minute limit, you’ll receive a 429 Too Many Requests response:
{
  "status_code": 429,
  "errors": [
    {
      "error": "RateLimitError",
      "message": "Exceeded rate limit for key type LIVE of 3000 requests per 60 seconds"
    }
  ]
}

Daily Message Limits

Limit Types

Daily limits are enforced separately for each notification channel:
  • SMS messages (UK)
  • International SMS messages
  • Email messages
  • Letters

Default Limits

Trial Services (Restricted)

ChannelTest Key LimitTeam/Live Key Limit
SMS50/day50/day
Email50/day50/day
Letter50/day50/day

Live Services

ChannelDefault Limit
SMS250,000/day
International SMS10,000/day
Email250,000/day
Letter20,000/day
Daily limits reset at midnight UTC. Limits are configurable per service through the admin interface.

Daily Limit Response

When you exceed a daily limit, you’ll receive a 429 Too Many Requests response:
{
  "status_code": 429,
  "errors": [
    {
      "error": "TooManyRequestsError",
      "message": "Exceeded send limits (sms: 250000) for today"
    }
  ]
}

Checking Current Usage

Daily usage is tracked in Redis with a 24-hour expiry:
  • Cache key: service-{service_id}-{notification_type}-{key_type}-count
  • Expiry: 86,400 seconds (24 hours)
  • Reset: Automatic at midnight UTC
You can check your current usage through the admin interface or using internal API endpoints.

Handling Rate Limits

Retry Strategy

When you receive a 429 response, implement exponential backoff:
Python retry example
import time
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

def create_session_with_retries():
    session = requests.Session()
    
    # Configure retry strategy
    retry_strategy = Retry(
        total=3,
        status_forcelist=[429, 500, 502, 503, 504],
        backoff_factor=2,  # Wait 1s, 2s, 4s between retries
        raise_on_status=False
    )
    
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("https://", adapter)
    session.mount("http://", adapter)
    
    return session

# Usage
session = create_session_with_retries()
response = session.post(
    "https://api.notifications.service.gov.uk/v2/notifications/sms",
    headers={"Authorization": f"Bearer {token}"},
    json=payload
)
Node.js retry example
const axios = require('axios');
const axiosRetry = require('axios-retry');

const client = axios.create();

// Configure retry
axiosRetry(client, {
  retries: 3,
  retryDelay: axiosRetry.exponentialDelay,
  retryCondition: (error) => {
    return error.response?.status === 429 || 
           error.response?.status >= 500;
  }
});

// Usage
try {
  const response = await client.post(
    'https://api.notifications.service.gov.uk/v2/notifications/sms',
    payload,
    {
      headers: { Authorization: `Bearer ${token}` }
    }
  );
} catch (error) {
  console.error('Request failed:', error.message);
}

Rate Limit Best Practices

Distribute requests

Spread API calls evenly over time instead of bursting all at once. Use queuing for batch operations.

Implement backoff

Use exponential backoff when you receive 429 responses. Don’t retry immediately.

Monitor usage

Track your API usage to avoid hitting limits. Set up alerts before reaching thresholds.

Request limit increases

Contact support if you consistently need higher limits. Provide usage justification.

Bulk Sending

For sending notifications in bulk, use the CSV job upload feature instead of the API:

Advantages of CSV Jobs

  • Not subject to per-minute rate limits
  • Processes in background
  • Better for large batches (1,000+ notifications)
  • Automatic retry handling
  • Progress tracking

When to Use API vs CSV Jobs

Real-time notifications
  • Immediate delivery required
  • Single or small batches
  • Triggered by user actions
  • Need instant confirmation
  • < 100 notifications at once
See the Bulk Sending section above for more information on CSV jobs.

Rate Limit Configuration

Service-Level Settings

Rate limits are configured per service in the admin interface:
  • Per-minute rate limit - Configurable, default 3,000/min
  • SMS daily limit - Configurable, default 250,000/day
  • Email daily limit - Configurable, default 250,000/day
  • Letter daily limit - Configurable, default 20,000/day
  • International SMS limit - Configurable, default 10,000/day

Requesting Limit Increases

To request higher limits:
  1. Contact GOV.UK Notify support
  2. Provide:
    • Service details and use case
    • Expected volume
    • Traffic patterns (spikes vs. steady)
    • Justification for higher limits
  3. Limits can be increased for specific services

Monitoring Rate Limits

Metrics Available

Notify exposes Prometheus metrics for rate limiting:
# Rate limit checks
redis_exceeded_rate_limit_duration_seconds{algorithm="token_bucket"}

# Daily limit checks  
redis_daily_limit_check_duration_seconds

Logging

Rate limit events are logged:
# Per-minute rate limit exceeded
app.logger.info("service %s has been rate limited for token bucket", service.id)

# Daily limit exceeded
app.logger.info(
    "Service %(service_id)s has been rate limited for %(sent_count)s daily use "
    "sent %(notification_type)s limit %(limit)s",
    extra={
        "service_id": service.id,
        "sent_count": current_count,
        "notification_type": "sms",
        "limit": daily_limit
    }
)

FAQ

Your request will be rejected with a 429 status code. You should implement retry logic with exponential backoff to handle this gracefully.
Yes, but the limits may differ. Test keys on trial services have lower daily limits (50/day) compared to live services.
Yes, contact GOV.UK Notify support with your use case and required volume. Limits can be increased for justified use cases.
No, CSV jobs are not subject to per-minute API rate limits. They are only subject to daily message limits.
Daily limits reset at midnight UTC (00:00 UTC).

Next Steps

Authentication

Learn about API authentication

Send notifications

Start sending notifications

Notifications

Understand notification lifecycle

Error handling

Handle API errors

Build docs developers (and LLMs) love