Rate Limits

Understanding and configuring rate limiting for form submissions

configuration
rate-limits throttling security abuse-prevention

Rate Limits

Understanding and configuring rate limiting for form submissions.

Overview

Rate limiting prevents abuse and ensures fair usage of FormFeeder's resources. Different types of limits apply at various levels to protect both the service and your forms from spam and automated attacks.

Types of Rate Limits

Global Rate Limits

Applied to all requests from a single IP address:

  • Default: 100 requests per minute per IP address
  • Applies to: All endpoints including form submissions
  • Reset: Rolling window (not fixed intervals)
  • Headers: Rate limit information included in responses

Form-Specific Rate Limits

Applied per form per IP address:

  • Default: 10 submissions per minute per IP per form
  • Configurable: Can be adjusted per form
  • Privacy Mode: Same limits apply
  • Bypass: Not possible without API key authentication

File Upload Rate Limits

Additional limits for file uploads:

  • File Size: 5MB per file (default)
  • Total Size: 10MB per submission (default)
  • File Count: 5 files per submission (default)
  • Upload Rate: Bandwidth throttling for large files

Rate Limit Headers

All responses include rate limiting headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
X-RateLimit-Type: global

Header Descriptions

Header Description
X-RateLimit-Limit Maximum requests allowed in time window
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when limit resets
X-RateLimit-Type Type of limit (global or form)

Handling Rate Limits

HTTP Response

When rate limited, you'll receive a 429 Too Many Requests response:

{
  "success": false,
  "message": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "retryAfter": 30
}

JavaScript Error Handling

async function submitForm(formData) {
  try {
    const response = await fetch('https://api.formfeeder.io/v1/form/abc123', {
      method: 'POST',
      body: formData
    });
    
    if (response.status === 429) {
      const data = await response.json();
      const retryAfter = data.retryAfter || 60;
      
      // Show user-friendly message
      showError(`Too many requests. Please wait ${retryAfter} seconds and try again.`);
      
      // Optionally implement automatic retry
      setTimeout(() => submitForm(formData), retryAfter * 1000);
      return;
    }
    
    // Handle other responses...
    
  } catch (error) {
    console.error('Submission error:', error);
  }
}

Retry Logic Implementation

async function submitWithRetry(formData, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch('https://api.formfeeder.io/v1/form/abc123', {
        method: 'POST',
        body: formData
      });
      
      if (response.ok) {
        return await response.json();
      }
      
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
        console.log(`Rate limited. Retrying in ${retryAfter} seconds (attempt ${attempt})`);
        
        if (attempt < maxRetries) {
          await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
          continue;
        }
      }
      
      throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      
    } catch (error) {
      if (attempt === maxRetries) throw error;
      
      // Exponential backoff for network errors
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

Best Practices

Client-Side Rate Limiting

Prevent hitting server limits by implementing client-side controls:

class FormSubmissionManager {
  constructor() {
    this.lastSubmission = 0;
    this.minimumInterval = 1000; // 1 second between submissions
  }
  
  canSubmit() {
    const now = Date.now();
    return (now - this.lastSubmission) >= this.minimumInterval;
  }
  
  async submit(formData) {
    if (!this.canSubmit()) {
      throw new Error('Please wait before submitting again');
    }
    
    this.lastSubmission = Date.now();
    // Proceed with submission...
  }
}

Button Debouncing

Prevent accidental rapid clicks:

function debounceSubmit(button, delay = 2000) {
  const originalText = button.textContent;
  
  button.disabled = true;
  button.textContent = 'Sending...';
  
  setTimeout(() => {
    button.disabled = false;
    button.textContent = originalText;
  }, delay);
}

User Feedback

Provide clear feedback when rate limits are encountered:

function showRateLimitMessage(retryAfter) {
  const message = document.createElement('div');
  message.className = 'alert alert-warning';
  message.innerHTML = `
    <strong>Slow down!</strong>
    Too many submissions. Please wait ${retryAfter} seconds.
    <div class="countdown" data-remaining="${retryAfter}"></div>
  `;
  
  document.getElementById('form-messages').appendChild(message);
  
  // Countdown timer
  startCountdown(message.querySelector('.countdown'));
}

function startCountdown(element) {
  let remaining = parseInt(element.dataset.remaining);
  
  const timer = setInterval(() => {
    element.textContent = `${remaining} seconds remaining`;
    remaining--;
    
    if (remaining < 0) {
      clearInterval(timer);
      element.parentElement.remove();
    }
  }, 1000);
}

Configuration Options

Dashboard Configuration

For forms created through the dashboard, rate limits can be configured:

  1. Form Settings: Access form configuration
  2. Rate Limiting: Adjust per-minute limits
  3. File Limits: Configure file upload restrictions
  4. IP Whitelist: Bypass limits for trusted IPs (enterprise)

API Configuration

{
  "rateLimit": {
    "requests": 10,
    "window": 60,
    "burstLimit": 20
  },
  "fileUpload": {
    "maxFileSize": 5242880,
    "maxTotalSize": 10485760,
    "maxFiles": 5
  }
}

Configuration Parameters

Parameter Description Default Range
requests Max requests per window 10 1-100
window Time window in seconds 60 30-300
burstLimit Temporary burst allowance 20 1-200
maxFileSize Max size per file (bytes) 5MB 1MB-10MB
maxFiles Max files per submission 5 1-20

Monitoring and Analytics

Rate Limit Metrics

Dashboard users can view rate limiting metrics:

  • Requests: Total requests and rate-limited requests
  • Top IPs: Most active IP addresses
  • Patterns: Time-based submission patterns
  • Abuse Detection: Potential spam or bot traffic

Alerting

Set up alerts for unusual activity:

  • High Rate Limit Hit Rate: When >50% requests are rate limited
  • Unusual Traffic Spikes: Sudden increases in submission volume
  • Geographic Anomalies: Traffic from unexpected locations
  • Bot Detection: Automated submission patterns

Troubleshooting Rate Limits

Common Issues

  1. Legitimate Users Hit Limits: Adjust form-specific limits
  2. Development Testing: Use separate form IDs for testing
  3. CDN/Proxy Issues: May show single IP for multiple users
  4. Mobile Networks: Carrier-grade NAT may group users

Solutions

  1. Increase Limits: For high-traffic forms
  2. IP Whitelisting: For trusted sources (enterprise)
  3. Geographic Distribution: Use multiple forms for different regions
  4. Authentication: API keys bypass some limits

Debugging Commands

# Check current rate limit status
curl -I "https://api.formfeeder.io/v1/form/abc123" \
  -H "Origin: https://example.com"

# Test rate limits
for i in {1..15}; do
  echo "Request $i:"
  curl -X POST "https://api.formfeeder.io/v1/form/abc123" \
    -H "Content-Type: application/json" \
    -H "Origin: https://example.com" \
    -d '{"test": "data"}' \
    -w "Status: %{http_code}\n" \
    -s
done

Enterprise Features

Advanced Rate Limiting

Enterprise plans include additional features:

  • Custom Rate Limits: Per-form customization
  • IP Whitelisting: Bypass limits for trusted sources
  • Geographic Rate Limits: Different limits by region
  • Burst Protection: Advanced burst detection and handling

Priority Processing

  • Fast Lane: Priority queue for enterprise forms
  • Dedicated Resources: Separate processing pools
  • SLA Guarantees: Response time commitments
  • 24/7 Monitoring: Proactive issue detection

Contact [email protected] for enterprise rate limiting options.