# Como fazer throttling progressivo em consultas de CPF para evitar bloqueios

> Aprenda a implementar throttling progressivo em consultas de CPF via API para respeitar rate limits e evitar bloqueios.

**Publicado:** 29/11/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/throttling-progressivo-consultas-cpf-evitar-bloqueios

---


Throttling progressivo em consultas de CPF é uma técnica de controle proativo de consumo que ajusta automaticamente a cadência de requisições para manter os custos previsíveis. Na CPFHub.io, a API nunca bloqueia — ao superar o limite do plano, cada consulta adicional é cobrada a R$0,15 — portanto, o objetivo do throttling é responsabilidade financeira, não evitar erros de bloqueio.

## Introdução

Quando sua aplicação processa grandes volumes de CPFs, a falta de controle sobre o ritmo de requisições pode resultar em custos inesperados no fim do mês. O throttling progressivo resolve isso ajustando dinamicamente a taxa de consultas com base no consumo observado — mais rápido quando há margem, mais lento quando o orçamento está próximo do limite. A ferramenta `get_quota_info` do servidor MCP da CPFHub.io e o painel em `app.cpfhub.io/settings/billing` são os meios recomendados para monitorar o consumo em tempo real.

---

## Throttling fixo vs. progressivo

* **Throttling fixo** -- Intervalo constante entre requisições (ex: sempre 2 segundos). Simples, mas não se adapta à situação.

* **Throttling progressivo** -- Começa rápido e desacelera ao detectar que o orçamento ou a cota estão próximos do limite. Retorna à velocidade normal quando há margem disponível.

---

## Implementação básica: token bucket

O algoritmo token bucket controla a taxa de requisições permitindo um "balde" que se enche de tokens a uma taxa fixa:

```python
import time
import threading

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

    def consumir(self, tokens=1):
        with self.lock:
            agora = time.monotonic()
            decorrido = agora - self.ultimo_reabastecimento
            self.tokens = min(
                self.capacidade,
                self.tokens + decorrido * self.taxa
            )
            self.ultimo_reabastecimento = agora

            if self.tokens >= tokens:
                self.tokens -= tokens
                return True
            return False

    def aguardar_token(self, tokens=1):
        while not self.consumir(tokens):
            time.sleep(0.05)

# Plano Pro: 1 req/seg
bucket = TokenBucket(taxa_por_segundo=1.0, capacidade_maxima=1)
```

---

## Throttling progressivo com controle de consumo

A implementação completa monitora o consumo acumulado e desacelera conforme a cota mensal se aproxima:

```python
import requests
import time
import threading

class ThrottleProgressivo:
    def __init__(self, api_key, taxa_base=0.5, limite_mensal=50):
        self.api_key = api_key
        self.taxa_base = taxa_base  # requisicoes por segundo
        self.taxa_atual = taxa_base
        self.intervalo_minimo = 1.0 / taxa_base
        self.intervalo_atual = self.intervalo_minimo
        self.multiplicador_cautela = 2.0
        self.fator_recuperacao = 0.9
        self.intervalo_maximo = 30.0
        self.consultas_realizadas = 0
        self.limite_mensal = limite_mensal
        self.consecutivos_ok = 0
        self.lock = threading.Lock()
        self.session = requests.Session()
        self.session.headers.update({
            'x-api-key': api_key,
            'Accept': 'application/json'
        })

    def consultar(self, cpf):
        with self.lock:
            intervalo = self.intervalo_atual

        time.sleep(intervalo)

        try:
            response = self.session.get(
                f'https://api.cpfhub.io/cpf/{cpf}',
                timeout=15
            )

            self._ajustar_taxa(response.status_code)

            if response.status_code == 200:
                with self.lock:
                    self.consultas_realizadas += 1
                return response.json()
            else:
                return {'error': f'http_{response.status_code}'}

        except requests.exceptions.Timeout:
            self._aumentar_intervalo()
            return {'error': 'timeout'}

    def _ajustar_taxa(self, status_code):
        with self.lock:
            percentual_consumido = self.consultas_realizadas / self.limite_mensal

            if percentual_consumido > 0.8:
                # Acima de 80% da cota: dobrar intervalo para conter custos extras
                self.intervalo_atual = min(
                    self.intervalo_atual * self.multiplicador_cautela,
                    self.intervalo_maximo
                )
                print(f'Consumo: {percentual_consumido:.0%}. Intervalo: {self.intervalo_atual:.2f}s')

            elif status_code == 200:
                self.consecutivos_ok += 1
                # Recuperacao gradual apos 5 respostas OK consecutivas
                if self.consecutivos_ok >= 5:
                    self.intervalo_atual = max(
                        self.intervalo_atual * self.fator_recuperacao,
                        self.intervalo_minimo
                    )
                    self.consecutivos_ok = 0

    def _aumentar_intervalo(self):
        with self.lock:
            self.intervalo_atual = min(
                self.intervalo_atual * 1.5,
                self.intervalo_maximo
            )

    @property
    def status(self):
        return {
            'intervalo_atual': round(self.intervalo_atual, 2),
            'taxa_efetiva': round(1.0 / self.intervalo_atual, 2),
            'consultas_realizadas': self.consultas_realizadas,
            'consecutivos_ok': self.consecutivos_ok
        }
```

---

## Uso prático para processamento em lote

```python
throttle = ThrottleProgressivo('SUA_CHAVE_DE_API', taxa_base=0.5, limite_mensal=50)

cpfs = ['12345678900', '98765432100', '11122233344']
resultados = []

for cpf in cpfs:
    resultado = throttle.consultar(cpf)
    resultados.append({'cpf': cpf, 'resultado': resultado})
    print(f'CPF: {cpf} | Status: {throttle.status}')

print(f'\nProcessados: {len(resultados)}')
```

---

## Implementação em Node.js

```javascript
class ThrottleProgressivo {
    constructor(apiKey, taxaBase = 0.5, limiteMensal = 50) {
        this.apiKey = apiKey;
        this.intervaloAtual = 1000 / taxaBase; // em ms
        this.intervaloMinimo = 1000 / taxaBase;
        this.intervaloMaximo = 30000;
        this.multiplicadorCautela = 2.0;
        this.fatorRecuperacao = 0.9;
        this.consecutivosOk = 0;
        this.consultasRealizadas = 0;
        this.limiteMensal = limiteMensal;
    }

    async consultar(cpf) {
        await this._aguardar(this.intervaloAtual);

        try {
            const response = await fetch(`https://api.cpfhub.io/cpf/${cpf}`, {
                method: 'GET',
                headers: {
                    'x-api-key': this.apiKey,
                    'Accept': 'application/json'
                },
                signal: AbortSignal.timeout(15000)
            });

            this._ajustarTaxa(response.status);

            if (response.ok) {
                this.consultasRealizadas++;
                return await response.json();
            }
            return { error: `http_${response.status}` };

        } catch (error) {
            this.intervaloAtual = Math.min(
                this.intervaloAtual * 1.5,
                this.intervaloMaximo
            );
            return { error: error.message };
        }
    }

    _ajustarTaxa(status) {
        const percentualConsumido = this.consultasRealizadas / this.limiteMensal;

        if (percentualConsumido > 0.8) {
            // Acima de 80% da cota: desacelerar para conter custos extras
            this.intervaloAtual = Math.min(
                this.intervaloAtual * this.multiplicadorCautela,
                this.intervaloMaximo
            );
        } else if (status === 200) {
            this.consecutivosOk++;
            if (this.consecutivosOk >= 5) {
                this.intervaloAtual = Math.max(
                    this.intervaloAtual * this.fatorRecuperacao,
                    this.intervaloMinimo
                );
                this.consecutivosOk = 0;
            }
        }
    }

    _aguardar(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

// Uso
const throttle = new ThrottleProgressivo(process.env.CPFHUB_API_KEY, 0.5, 50);
const resultado = await throttle.consultar('12345678900');
```

---

## Estrategias complementares

### Retry com jitter

Adicionar aleatoriedade ao intervalo evita que múltiplas instâncias sincronizem seus retries:

```python
import random

def intervalo_com_jitter(intervalo_base):
    jitter = random.uniform(0, intervalo_base * 0.3)
    return intervalo_base + jitter
```

### Circuit breaker de custo

Se o consumo acumulado ultrapassar o limite planejado, suspenda o lote até revisão manual:

```python
if self.consultas_realizadas >= self.limite_mensal:
    print('Cota mensal atingida. Pausando processamento para revisão de custos.')
    print('Verifique o consumo em app.cpfhub.io/settings/billing')
    raise SystemExit('Limite de consultas atingido')
```

---

## Monitorando o consumo

Registre métricas para entender o comportamento do throttle e planejar upgrades de plano:

* **Intervalo médio** -- Quanto tempo, em média, entre cada chamada.

* **Percentual de cota consumido** -- Acompanhe via `get_quota_info` (MCP) ou no painel `app.cpfhub.io/settings/billing`.

* **Custo projetado** -- Consultas acima da cota custam R$0,15 cada; monitore antes de atingir o limite.

* **Throughput efetivo** -- Quantas consultas por minuto estão sendo processadas.

A [OWASP](https://owasp.org/) recomenda o monitoramento contínuo de consumo de APIs externas como parte das boas práticas de segurança e governança de custos.

---

## Perguntas frequentes

### A API da CPFHub.io bloqueia requisições quando a cota é ultrapassada?
Não. A CPFHub.io nunca retorna HTTP 429 nem bloqueia a aplicação. Ao superar o limite do plano, cada consulta adicional é cobrada a R$0,15. O throttling progressivo existe para controlar proativamente esse custo, não para evitar bloqueios.

### Como monitorar o consumo de cota em tempo real?
Use a ferramenta `get_quota_info` do servidor MCP da CPFHub.io para consultar o consumo atual programaticamente, ou acesse `app.cpfhub.io/settings/billing` para visualizar o histórico e o saldo do mês.

### Qual a diferença entre throttling fixo e progressivo no contexto da CPFHub.io?
O throttling fixo aplica um intervalo constante entre requisições, independentemente do consumo. O throttling progressivo monitora a cota consumida e desacelera automaticamente quando o percentual se aproxima do limite — reduzindo o risco de cobranças inesperadas sem sacrificar o throughput quando há margem disponível.

### Quando faz sentido fazer upgrade para o plano Pro?
Quando o volume mensal de consultas ultrapassa 50 com frequência, o plano Pro (R$149/mês, 1.000 consultas + R$0,15/extra) se torna mais econômico. O throttling progressivo ajuda a quantificar esse volume antes de decidir pelo upgrade.

### Leia também

- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Onboarding digital em fintechs: como validar CPF em menos de 30 segundos](https://cpfhub.io/blog/onboarding-digital-em-fintechs-como-validar-cpf-em-menos-de-30-segundos)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

Throttling progressivo é a abordagem inteligente para controlar o custo de processamento em lote com a CPFHub.io. Ao ajustar automaticamente a cadência de requisições com base no consumo acumulado, sua aplicação processa o máximo possível dentro do orçamento planejado — sem surpresas no faturamento e sem interrupções no fluxo.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.

