Resolved

Hardcoded rate limits in Python API require code changes for tuning

Python
API
Rate Limiting
DevOps
Configuration
Redis
Backend
Technical Debt

Stripe and SNS webhook endpoints used hardcoded rate limits (100/minute) preventing environment-specific tuning | Required code changes and redeploys for simple configuration adjustments

Issue

The Python API, which processes Stripe payment webhooks and SNS email notifications, had hardcoded rate limits enforced via decorator annotations. These hardcoded values (e.g., 100 requests per minute) could not be adjusted without modifying the source code and redeploying the application. This limitation created operational challenges, particularly when:

  • Different environments (development, staging, production) required different rate limits.
  • Payment traffic spikes necessitated temporary increases in rate limits.
  • External webhook providers (e.g., SNS) required more conservative limits.

Culprit

The root cause was a violation of the 12-factor app principle, which advocates for storing configuration in environment variables rather than embedding it in code. Five hardcoded values were identified across the codebase:

  • A default rate limit of 100 requests per minute for all endpoints.
  • A rate limit of 100 requests per minute for Stripe webhooks.
  • A rate limit of 10 requests per minute for SNS webhooks.
  • A 5-minute (300-second) time-to-live (TTL) for Redis deduplication.
  • Hardcoded log messages referencing specific rate limits.

This approach required code changes and redeployments for any adjustments, creating unnecessary operational overhead.

Solution

To address these issues, a centralized configuration approach was implemented:

Centralized Configuration via Environment Variables

Four configurable environment variables were introduced to replace hardcoded values:

  • RATE_LIMIT_DEFAULT: Default rate limit for all endpoints.
  • RATE_LIMIT_SNS_WEBHOOK: Conservative limit for external SNS webhooks.
  • RATE_LIMIT_STRIPE_WEBHOOK: Higher limit for Stripe webhooks to accommodate payment bursts.
  • REDIS_DEDUP_TTL: Configurable TTL for Redis deduplication.

Dynamic Rate Limiting Implementation

The code was refactored to load rate limits dynamically from environment variables, enabling environment-specific tuning without code changes:

  • Rate limits are now defined as environment variables with fallback defaults.
  • Rate limit strings use dynamic composition (e.g., f"{VAR}/minute") to support environment-specific values.
  • The Redis deduplication TTL was converted from a hardcoded integer to an environment variable.

Operational Benefits

  • Environment-Specific Tuning: Rate limits can now be adjusted per environment (dev, staging, production) by modifying environment variables.
  • No Code Changes Required: Updates to rate limits no longer necessitate source code modifications or redeployments.
  • Safe Fallbacks: Default values ensure the application remains functional if environment variables are missing.
  • Centralized Documentation: Environment variables are documented with rationale comments for clarity.

This change improved operational flexibility and aligned the application with best practices for configuration management.