Comparación de dos enfoques de throttling con scope en DRF: ScopedRateThrottle vs herencia de UserRateThrottle

En DRF, al aplicar throttling basado en scope, suelen aparecer dos patrones comunes.

  • Enfoque A: Heredar de UserRateThrottle (o SimpleRateThrottle) y crear una clase personalizada con scope fijado, luego asignarla directamente a throttle_classes de la vista.
  • Enfoque B: Registrar ScopedRateThrottle en DEFAULT_THROTTLE_CLASSES y en la vista solo indicar throttle_scope = "login".

Para responder a la pregunta “¿son esencialmente iguales?”:

Si el objetivo es limitar la tasa por user ID (o IP sin autenticar) + scope, los resultados son casi idénticos. La diferencia radica en la forma de aplicación (prevención de errores, extensibilidad, estructura de código) y, por tanto, en la elección del patrón.


Puntos en común: ambos crean la clave con “scope + (user id o IP)”



  • ScopedRateThrottle construye la clave con scope + userID/IP cuando la vista tiene throttle_scope, y busca la tasa correspondiente en DEFAULT_THROTTLE_RATES.
  • UserRateThrottle también limita por user id para usuarios autenticados y por IP para no autenticados; para usar varias tasas, DRF sugiere heredar la clase y cambiar el scope.

Diferencia 1) ¿Dónde colocar el scope?: atributo de la vista vs atributo de la clase

Enfoque A: scope fijo en la clase (explícito)

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class CustomDomainSaveThrottle(UserRateThrottle):
    scope = "custom_domain_save"

class SaveCustomDomainView(APIView):
    throttle_classes = [CustomDomainSaveThrottle]
  • El scope está fijado en la clase.
  • La vista solo declara que usará esa clase.
  • Se reducen los errores tipográficos en el scope, ya que el nombre de la clase actúa como documentación.

Enfoque B: scope en la vista, throttling común (centrado en la configuración)

REST_FRAMEWORK = {
  "DEFAULT_THROTTLE_CLASSES": [
    "rest_framework.throttling.ScopedRateThrottle",
  ],
  "DEFAULT_THROTTLE_RATES": {
    "login": "5/min",
  }
}

from rest_framework.views import APIView

class LoginView(APIView):
    throttle_scope = "login"
  • El scope se coloca directamente en la vista.
  • El ScopedRateThrottle común interpreta que la vista pertenece al scope y aplica la tasa desde la configuración.
  • El código es más corto y la política se gestiona en un solo lugar.

Diferencia 2) ¿Quién garantiza la aplicación?: registro por defecto vs equipamiento por vista



Puntos clave del Enfoque B (mucha confusión)

Incluso si ScopedRateThrottle está en DEFAULT_THROTTLE_CLASSES, no se aplica a las vistas sin throttle_scope. No hay riesgo de bloquear toda la API al registrar globalmente.

Ventaja del Enfoque A

Se puede equipar un throttle específico a una vista sin tocar la configuración global, útil cuando el entorno no permite cambios masivos o cuando solo ciertos endpoints deben ser restringidos.


Diferencia 3) Escalabilidad: cuando se supera el “un solo límite” el Enfoque A gana ventaja

La similitud se mantiene hasta “una vista, un scope, una tasa”. Más allá, las diferencias se hacen evidentes.

1) Aplicar múltiples throttles (burst + sustained) a una vista

DRF muestra un patrón con varias UserRateThrottle:

class Burst(UserRateThrottle):
    scope = "burst"

class Sustained(UserRateThrottle):
    scope = "sustained"

class SearchView(APIView):
    throttle_classes = [Burst, Sustained]

Con ScopedRateThrottle solo, es difícil expresar “dos scopes en una vista”; se necesita una clase adicional o una implementación personalizada.

2) Cambiar el criterio de limitación

ScopedRateThrottle se basa en user id / IP. En la práctica surgen necesidades como:

  • IP + nombre de usuario para proteger contra ataques dirigidos a cuentas.
  • tenant_id para limitar por organización.
  • API key para limitar por clave.

Estas situaciones requieren sobrescribir get_cache_key() y, por tanto, heredar y personalizar el throttle (Enfoque A). DRF también recomienda crear throttles personalizados en estos casos.


Dos llaves para abrir la conexión API

¿Cuál elegir?

Para la mayoría de los “rate limits por vista” → Enfoque B (ScopedRateThrottle)

  • Código mínimo.
  • Política gestionada en settings.
  • Solo se aplica a vistas con throttle_scope.

Si se cumple al menos una de las siguientes condiciones → Enfoque A (herencia/Clase personalizada)

  • Se necesitan múltiples límites (burst + sustained) en la misma vista.
  • El criterio de limitación no es user/IP sino algo personalizado (usuario+IP, tenant, API key, etc.).
  • Se desea evitar cambios globales y equipar throttles solo a vistas específicas.
  • Se quiere que el nombre de la clase sirva como documentación de la política.

Artículo relacionado: