# Como Processar Múltiplas Consultas de CPF em Paralelo Usando Node.js

> Aprenda a processar múltiplas consultas de CPF em paralelo usando Node.js, com Promise.allSettled, controle de concorrência e tratamento de erros.

**Publicado:** 27/07/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/processar-multiplas-consultas-cpf-paralelo-nodejs

---


Para processar múltiplas consultas de CPF em paralelo com Node.js, use `Promise.allSettled` combinado com a biblioteca `p-limit` para controlar a concorrência. Essa abordagem reduz o tempo de execução de centenas de segundos para poucos segundos, mantendo o respeito aos limites da API e a resiliência do processo.

## Introdução

Em cenários como validação de lotes de clientes, migração de bases de dados ou rotinas de compliance, é comum a necessidade de consultar centenas ou milhares de CPFs de uma só vez. Fazer isso sequencialmente pode levar horas, enquanto o processamento paralelo com Node.js reduz drasticamente o tempo de execução.

## Consulta sequencial vs. paralela

A diferença de performance entre consultas sequenciais e paralelas é significativa.

| Abordagem | 100 CPFs (200ms/req) | 1.000 CPFs (200ms/req) | 10.000 CPFs (200ms/req) |
|---|---|---|---|
| Sequencial | 20 segundos | 200 segundos | 2.000 segundos |
| Paralela (10 conc.) | 2 segundos | 20 segundos | 200 segundos |
| Paralela (50 conc.) | 0,4 segundos | 4 segundos | 40 segundos |

**Sequencial** -- cada consulta espera a anterior terminar antes de iniciar; simples, mas lento.

**Paralela sem limite** -- todas as consultas disparam simultaneamente; rápido, mas sobrecarrega a API e pode causar rate limiting.

**Paralela com controle** -- um número controlado de consultas roda em paralelo; rápido e respeitoso com os limites da API.

---

## Implementação básica com Promise.allSettled

A abordagem mais simples usa `Promise.allSettled` para disparar todas as consultas e coletar os resultados.

```javascript
const fetch = (...args) =>
 import("node-fetch").then(({ default: f }) => f(...args));

const API_KEY = process.env.CPFHUB_API_KEY;
const BASE_URL = "https://api.cpfhub.io/cpf";

async function consultarCPF(cpf) {
 const response = await fetch(`${BASE_URL}/${cpf}`, {
 headers: { "x-api-key": API_KEY }
 });

 if (!response.ok) {
 throw new Error(`HTTP ${response.status} para CPF ${cpf}`);
 }

 return response.json();
}

async function consultarLoteSimples(cpfs) {
 const promessas = cpfs.map((cpf) => consultarCPF(cpf));
 const resultados = await Promise.allSettled(promessas);

 return resultados.map((resultado, index) => ({
 cpf: cpfs[index],
 sucesso: resultado.status === "fulfilled",
 dados: resultado.status === "fulfilled" ? resultado.value.data : null,
 erro: resultado.status === "rejected" ? resultado.reason.message : null
 }));
}

// Uso
const cpfs = ["12345678901", "98765432100", "11122233344"];
const resultados = await consultarLoteSimples(cpfs);
console.log(resultados);
```

---

## Controle de concorrência com p-limit

Para evitar sobrecarregar a API, utilize a biblioteca `p-limit` para controlar o número de requisições simultâneas.

```javascript
import pLimit from "p-limit";

const limite = pLimit(10); // Máximo de 10 requisições simultâneas

async function consultarLoteControlado(cpfs) {
 const promessas = cpfs.map((cpf) =>
 limite(async () => {
 try {
 const resultado = await consultarCPF(cpf);
 return { cpf, sucesso: true, dados: resultado.data };
 } catch (erro) {
 return { cpf, sucesso: false, erro: erro.message };
 }
 })
 );

 return Promise.all(promessas);
}

// Processar 1000 CPFs com no máximo 10 em paralelo
const cpfsGrandes = gerarListaCPFs(1000);
const inicio = Date.now();
const resultados = await consultarLoteControlado(cpfsGrandes);
const duracao = Date.now() - inicio;

const sucessos = resultados.filter((r) => r.sucesso).length;
const falhas = resultados.filter((r) => !r.sucesso).length;

console.log(`Processados: ${resultados.length}`);
console.log(`Sucessos: ${sucessos}, Falhas: ${falhas}`);
console.log(`Duração: ${duracao}ms`);
```

---

## Implementação manual de pool de concorrência

Para cenários onde não se deseja adicionar dependências, é possível implementar um pool de concorrência manualmente.

```javascript
async function poolConcorrencia(tarefas, concorrenciaMaxima) {
 const resultados = new Array(tarefas.length);
 let indiceAtual = 0;

 async function worker() {
 while (indiceAtual < tarefas.length) {
 const indice = indiceAtual++;
 try {
 resultados[indice] = {
 sucesso: true,
 dados: await tarefas[indice]()
 };
 } catch (erro) {
 resultados[indice] = { sucesso: false, erro: erro.message };
 }
 }
 }

 const workers = Array.from(
 { length: Math.min(concorrenciaMaxima, tarefas.length) },
 () => worker()
 );

 await Promise.all(workers);
 return resultados;
}

// Uso
const tarefas = cpfs.map((cpf) => () => consultarCPF(cpf));
const resultados = await poolConcorrencia(tarefas, 15);
```

| Parâmetro | Valor Recomendado | Justificativa |
|---|---|---|
| Concorrência máxima | 10-20 | Equilibra velocidade e respeito ao rate limit |
| Timeout por requisição | 5.000ms | Evita que uma requisição lenta trave o pool |
| Retentativas | 2-3 | Recupera erros transitórios sem excesso |
| Delay entre retentativas | 1.000ms | Dá tempo para o servidor se recuperar |

---

## Retry com backoff exponencial

Erros transitórios são comuns em operações de lote. Implementar retry com backoff exponencial aumenta a resiliência.

```javascript
async function consultarComRetry(cpf, tentativas = 3) {
 for (let i = 0; i < tentativas; i++) {
 try {
 const resultado = await consultarCPF(cpf);
 return resultado;
 } catch (erro) {
 if (i === tentativas - 1) throw erro;

 const delay = Math.pow(2, i) * 1000 + Math.random() * 500;
 console.log(
 `Tentativa ${i + 1} falhou para CPF ${cpf}. ` +
 `Retentando em ${Math.round(delay)}ms...`
 );
 await new Promise((resolve) => setTimeout(resolve, delay));
 }
 }
}

async function consultarLoteResilient(cpfs, concorrencia = 10) {
 const limite = pLimit(concorrencia);

 const promessas = cpfs.map((cpf) =>
 limite(async () => {
 try {
 const resultado = await consultarComRetry(cpf);
 return { cpf, sucesso: true, dados: resultado.data };
 } catch (erro) {
 return { cpf, sucesso: false, erro: erro.message };
 }
 })
 );

 return Promise.all(promessas);
}
```

---

## Perguntas frequentes

### O que é necessário para implementar validação de CPF neste contexto?
A validação de CPF exige uma chamada à API com o número do documento e a chave de autenticação. A CPFHub.io retorna o status do CPF, nome do titular e data de nascimento em menos de 200ms, permitindo a verificação em tempo real durante o cadastro ou transação.

### A API CPFHub.io funciona para todos os volumes de consulta?
Sim. O plano gratuito oferece 50 consultas por mês sem cartão de crédito — ideal para testes e projetos pequenos. Para volumes maiores, o plano Pro inclui 1.000 consultas mensais por R$149. Se o limite for ultrapassado, a API não bloqueia: cobra R$0,15 por consulta adicional.

### Como garantir conformidade com a LGPD ao usar uma API de CPF?
Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário (não guarde o CPF cru se um token bastar), implemente controle de acesso aos logs de consulta e documente a base legal para o tratamento. A [ANPD](https://www.gov.br/anpd) orienta que dados de identificação devem ser tratados com o princípio da necessidade.

### Quanto tempo leva para integrar a API CPFHub.io?
A integração básica leva menos de 30 minutos: crie uma conta em cpfhub.io, gere a API key no painel e faça uma chamada GET para `https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`. A documentação inclui exemplos em Python, Node.js, PHP, Java e outras linguagens.

### 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

O processamento paralelo de consultas de CPF em Node.js é uma técnica essencial para lidar com operações em lote de forma eficiente. A combinação de controle de concorrência, retry com backoff exponencial e tratamento robusto de erros garante que o processo seja rápido, resiliente e respeitoso com os limites da API. Escolha a concorrência adequada ao seu plano e monitore as métricas de sucesso para ajustar os parâmetros ao longo do tempo.

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

