# Como fazer rate limiting inteligente em consultas de CPF via API

> Aprenda a implementar rate limiting no lado do cliente para respeitar os limites da API de CPF e otimizar o consumo de créditos.

**Publicado:** 19/12/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-fazer-rate-limiting-inteligente-em-consultas-de-cpf-via-api

---


Rate limiting inteligente no lado do cliente é a estratégia de controlar proativamente o ritmo das requisições à API de CPF antes de atingir os limites do plano — usando algoritmos como Token Bucket e filas de prioridade para distribuir as consultas de forma eficiente, evitar custos de excedente inesperados e manter a estabilidade da integração em qualquer volume de uso.

## Introdução

Para manter o consumo de consultas sob controle, é responsabilidade da aplicação gerenciar o ritmo de requisições no lado do cliente. A [**CPFHub.io**](https://www.cpfhub.io/) não bloqueia requisições ao atingir o limite do plano — em vez disso, cobra R$0,15 por consulta adicional. Por isso, implementar rate limiting no cliente é a forma mais eficaz de evitar cobranças de excedente inesperadas e garantir previsibilidade de custos.

---

## Rate limits da CPFHub.io

Cada plano da [**CPFHub.io**](https://www.cpfhub.io/) tem um limite de consultas mensais e uma taxa de requisições por segundo:

| Plano | Rate limit | Consultas/mês |
| --- | --- | --- |
| Gratuito | 1 requisição a cada 2 segundos | 50 |
| Pro | 1 requisição por segundo | 1.000 |
| Corporativo | Personalizado | Personalizado |

Quando o volume mensal é ultrapassado, a API **não bloqueia nem retorna HTTP 429** — ela cobra automaticamente R$0,15 por consulta adicional. O controle proativo do consumo fica inteiramente no lado do cliente.

---

## Implementando rate limiter com Token Bucket em Python

O algoritmo Token Bucket é uma das formas mais eficientes de controlar a taxa de requisições no lado do cliente. Ele funciona como um balde que é preenchido com "tokens" a uma taxa constante -- cada requisição consome um token, e se o balde estiver vazio, a requisição aguarda.

```python
import requests
import time
import threading

class TokenBucket:
 def __init__(self, taxa_por_segundo, capacidade_maxima=1):
 self.taxa = taxa_por_segundo
 self.capacidade = capacidade_maxima
 self.tokens = capacidade_maxima
 self.ultimo_reabastecimento = time.monotonic()
 self.lock = threading.Lock()

 def aguardar_token(self):
 while True:
 with self.lock:
 agora = time.monotonic()
 tempo_passado = agora - self.ultimo_reabastecimento
 self.tokens = min(
 self.capacidade,
 self.tokens + tempo_passado * self.taxa
 )
 self.ultimo_reabastecimento = agora

 if self.tokens >= 1:
 self.tokens -= 1
 return

 time.sleep(0.1)

# Configurar para plano Pro: 1 requisição por segundo
rate_limiter = TokenBucket(taxa_por_segundo=1.0)

def consultar_cpf_com_rate_limit(cpf):
 rate_limiter.aguardar_token()

 url = f"https://api.cpfhub.io/cpf/{cpf}"
 headers = {
 "x-api-key": "SUA_CHAVE_DE_API",
 "Accept": "application/json"
 }

 response = requests.get(url, headers=headers, timeout=10)
 return response.json()

# Consultar múltiplos CPFs respeitando o rate limit
cpfs = ["11111111111", "22222222222", "33333333333"]
for cpf in cpfs:
 resultado = consultar_cpf_com_rate_limit(cpf)
 print(f"CPF {cpf}: {resultado}")
```

---

## Implementando rate limiter em JavaScript (Node.js)

```javascript
class RateLimiter {
 constructor(requestsPerSecond) {
 this.minInterval = 1000 / requestsPerSecond;
 this.lastRequest = 0;
 this.queue = [];
 this.processing = false;
 }

 async aguardar() {
 return new Promise(resolve => {
 this.queue.push(resolve);
 this.processarFila();
 });
 }

 async processarFila() {
 if (this.processing) return;
 this.processing = true;

 while (this.queue.length > 0) {
 const agora = Date.now();
 const tempoDesdeUltima = agora - this.lastRequest;

 if (tempoDesdeUltima < this.minInterval) {
 await new Promise(r =>
 setTimeout(r, this.minInterval - tempoDesdeUltima)
 );
 }

 this.lastRequest = Date.now();
 const resolve = this.queue.shift();
 resolve();
 }

 this.processing = false;
 }
}

// Plano Pro: 1 requisição por segundo
const limiter = new RateLimiter(1);

async function consultarCPFComRateLimit(cpf) {
 await limiter.aguardar();

 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), 10000);

 try {
 const response = await fetch(
 `https://api.cpfhub.io/cpf/${cpf}`,
 {
 headers: {
 'x-api-key': 'SUA_CHAVE_DE_API',
 'Accept': 'application/json'
 },
 signal: controller.signal
 }
 );

 clearTimeout(timeoutId);
 return await response.json();
 } catch (error) {
 clearTimeout(timeoutId);
 throw error;
 }
}

// Consultar múltiplos CPFs em paralelo (o rate limiter enfileira)
async function consultarLote(cpfs) {
 const resultados = await Promise.all(
 cpfs.map(cpf => consultarCPFComRateLimit(cpf))
 );
 return resultados;
}
```

---

## Controlando o consumo mensal com contador local

Além do controle de taxa por segundo, é recomendável manter um contador local de consultas mensais para antecipar quando o limite do plano será atingido. O painel em [app.cpfhub.io/settings/billing](https://app.cpfhub.io/settings/billing) exibe o consumo acumulado, mas alertas programáticos permitem agir antes de gerar excedente.

```python
import requests
import time
import threading
from datetime import datetime

rate_limiter = TokenBucket(taxa_por_segundo=1.0)

LIMITE_MENSAL = 1000  # Plano Pro
consultas_este_mes = 0
mes_atual = datetime.now().month

def consultar_cpf_resiliente(cpf, max_tentativas=3):
 global consultas_este_mes, mes_atual

 # Resetar contador se mudou o mês
 if datetime.now().month != mes_atual:
 consultas_este_mes = 0
 mes_atual = datetime.now().month

 # Alerta de consumo
 if consultas_este_mes >= LIMITE_MENSAL * 0.9:
 print(f"Atenção: {consultas_este_mes}/{LIMITE_MENSAL} consultas usadas este mês.")

 for tentativa in range(max_tentativas):
 rate_limiter.aguardar_token()

 url = f"https://api.cpfhub.io/cpf/{cpf}"
 headers = {
 "x-api-key": "SUA_CHAVE_DE_API",
 "Accept": "application/json"
 }

 try:
 response = requests.get(url, headers=headers, timeout=10)

 if response.status_code == 200:
 consultas_este_mes += 1
 return response.json()

 return {"erro": f"HTTP {response.status_code}"}

 except requests.exceptions.Timeout:
 if tentativa < max_tentativas - 1:
 time.sleep(2 ** tentativa)
 continue
 return {"erro": "Timeout"}

 return {"erro": "Todas as tentativas falharam"}
```

---

## Estratégias avançadas de rate limiting

### Rate limiting por prioridade

Nem todas as consultas de CPF têm a mesma urgência. Um sistema de filas com prioridade permite que consultas críticas (onboarding em tempo real) passem na frente de consultas menos urgentes (atualização cadastral em lote):

* **Prioridade alta** -- Consultas no fluxo de cadastro do usuário, que estão esperando resposta em tempo real.

* **Prioridade média** -- Verificações periódicas de dados existentes.

* **Prioridade baixa** -- Processos batch que podem ser executados durante a madrugada.

### Rate limiting distribuído

Quando múltiplas instâncias da aplicação compartilham a mesma API key, o rate limiting precisa ser coordenado. O Redis é ideal para esse cenário, pois permite que todas as instâncias compartilhem o mesmo contador de tokens.

### Suavização de picos

Em vez de enviar 100 consultas no primeiro segundo do minuto, distribua as requisições uniformemente ao longo do período disponível. Isso evita picos de carga tanto na sua aplicação quanto na API.

---

## Monitorando o rate limiting

Para ajustar o rate limiting ao longo do tempo, monitore as seguintes métricas:

* **Taxa de requisições por segundo** -- Confirme que está dentro do limite do seu plano.

* **Tempo médio de espera na fila** -- Se as consultas estão aguardando muito tempo, considere um upgrade de plano.

* **Consumo mensal acumulado** -- Acompanhe o consumo em relação ao limite mensal para evitar cobranças de excedente. A OWASP recomenda [monitoramento contínuo de APIs](https://owasp.org/API-Security/) como boa prática de segurança e controle operacional.

* **Tendência de crescimento** -- Se o volume cresce semana a semana, planeje o upgrade antes de atingir o limite.

---

## Perguntas frequentes

### A API CPFHub.io bloqueia requisições quando o limite mensal é atingido?
Não. A CPFHub.io nunca retorna HTTP 429 nem bloqueia consultas por limite mensal. Quando o volume do plano é ultrapassado, a API continua respondendo normalmente e cobra R$0,15 por consulta adicional. O controle de consumo é responsabilidade do cliente — por isso implementar rate limiting e alertas no lado da aplicação é essencial para evitar cobranças inesperadas.

### Qual algoritmo de rate limiting é mais recomendado para integrar com a API de CPF?
O Token Bucket é o mais adequado para a maioria dos casos: ele permite rajadas controladas de requisições enquanto mantém a taxa média dentro do limite do plano. Para cenários com múltiplas instâncias da aplicação, combine Token Bucket com um contador centralizado no Redis para coordenar o consumo entre todos os processos.

### Como posso ser alertado antes de atingir o limite mensal do plano?
Implemente um contador local de consultas mensais e configure alertas quando o consumo ultrapassar 80% do limite (por exemplo, 40 de 50 no plano gratuito ou 800 de 1.000 no plano Pro). O painel em app.cpfhub.io/settings/billing também exibe o consumo acumulado em tempo real, mas alertas programáticos permitem agir antes de gerar excedente.

### Como funciona o rate limiting quando múltiplas instâncias da aplicação compartilham a mesma API key?
Cada instância tem seu próprio rate limiter local, o que pode fazer com que o limite seja ultrapassado em cenários de alta concorrência. A solução é usar um rate limiter distribuído com Redis: todas as instâncias consultam e decrementam o mesmo contador de tokens, garantindo que o limite agregado seja respeitado independentemente de quantos processos estão em execução simultaneamente.

### Leia também

- [Como implementar retry com backoff exponencial em consultas de API de CPF](https://cpfhub.io/blog/como-implementar-retry-backoff-exponencial-consultas-api-cpf)
- [Como fazer throttling progressivo em consultas de CPF para evitar bloqueios](https://cpfhub.io/blog/como-fazer-throttling-progressivo-em-consultas-de-cpf-para-evitar-bloqueios)
- [API de CPF: como monitorar consumo e custos com observabilidade](https://cpfhub.io/blog/api-cpf-monitorar-consumo-custos-observabilidade)
- [SLA de API de CPF: níveis de disponibilidade e o que exigir do seu provedor](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)

---

## Conclusão

O rate limiting inteligente no lado do cliente é uma prática essencial para manter uma integração saudável com APIs de CPF. Ao respeitar proativamente os limites de taxa, sua aplicação distribui as consultas de forma eficiente, mantém a experiência do usuário fluida e evita cobranças de excedente inesperadas — já que a CPFHub.io nunca bloqueia, apenas cobra R$0,15 por consulta adicional ao ultrapassar o limite do plano.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e implemente sua estratégia de rate limiting com Token Bucket e alertas de consumo já no primeiro dia de integração.

