Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

gRPC Deadlines: controle timeouts no Node.js

Atualizado em: 28 de outubro de 2026

Terminal Linux usado em desenvolvimento e administração de aplicações Node.js

gRPC Deadlines no Node.js definem até quando uma chamada pode continuar. O cliente envia um limite e o servidor deve interromper trabalho quando o tempo acabar. Sem deadline, uma requisição lenta pode ocupar conexão, pool e memória por tempo indefinido.

Deadlines são especialmente importantes em cadeias de serviços. Se uma API possui 800 ms para responder, ela não pode conceder 800 ms a cada dependência. O orçamento precisa diminuir a cada etapa.

Configurando no cliente

client.getProduct(
  { id: 'p-10' },
  { deadline: Date.now() + 800 },
  callback
);

Use valores definidos por operação. Uma consulta simples pode ter centenas de milissegundos; uma exportação pode ter minutos.

Erro DEADLINE_EXCEEDED

Quando o prazo termina, o cliente recebe grpc.status.DEADLINE_EXCEEDED. Isso não prova que o servidor não executou o efeito. A operação pode ter sido concluída e a resposta ter chegado tarde.

Para métodos de escrita, use idempotency key ou identificador fornecido pelo cliente.

Observando cancelamento no servidor

async function getProduct(call, callback) {
  const controller = new AbortController();

  call.on('cancelled', () => {
    controller.abort(new Error('deadline ou cancelamento'));
  });

  try {
    const product = await repository.findById(
      call.request.id,
      { signal: controller.signal }
    );
    callback(null, product);
  } catch (error) {
    callback(toGrpcError(error));
  }
}

Propague o cancelamento para banco, HTTP, streams e timers sempre que a biblioteca oferecer suporte.

Tempo restante

O servidor pode consultar o deadline da chamada e calcular margem:

const deadline = call.getDeadline();
const deadlineMs = deadline instanceof Date
  ? deadline.getTime()
  : Number(deadline);

const remainingMs = deadlineMs - Date.now();

Reserve tempo para serializar e enviar a resposta. Não use todo o restante em uma dependência.

Propagação para outro gRPC

const downstreamDeadline = Math.min(
  Date.now() + 300,
  deadlineMs - 50
);

catalogClient.getProduct(request, {
  deadline: downstreamDeadline
}, callback);

A margem de 50 ms é apenas exemplo. Meça rede, serialização e variação real.

Propagação para fetch

const timeoutMs = Math.max(1, downstreamDeadline - Date.now());

const response = await fetch(url, {
  signal: AbortSignal.timeout(timeoutMs)
});

Combine o timeout com o sinal de cancelamento da chamada usando AbortSignal.any().

Banco de dados

Configure timeout de query menor que o deadline:

await client.query('SET LOCAL statement_timeout = $1', [queryTimeoutMs]);
await client.query(sql, values);

Use transação quando o timeout for local à operação. Não deixe configuração de sessão vazar pelo pool.

Fila e pools

O deadline inclui espera por conexão e fila local. Antes de iniciar trabalho, verifique se ainda existe orçamento suficiente. Uma requisição que esperou 700 ms em um pool não deve iniciar uma chamada de 500 ms se restam 100 ms.

Retries

Cada tentativa consome o mesmo orçamento global. Calcule se há tempo para backoff e nova execução:

if (remainingMs < minimumAttemptMs + backoffMs) {
  throw deadlineExceeded();
}

Retries sem orçamento ampliam carga justamente durante falhas.

Hedging

Enviar uma segunda tentativa paralela pode reduzir caudas de latência, mas aumenta carga. Use somente em métodos idempotentes, depois de um atraso e com limite global.

Timeout por etapa

Uma operação pode dividir orçamento:

  • autenticação: 50 ms;
  • banco: 300 ms;
  • serviço externo: 250 ms;
  • serialização e margem: 100 ms.

Os números devem vir de métricas, não de palpite permanente.

Deadline versus idle timeout

Deadline limita duração total. Idle timeout encerra quando não há progresso. Streams longos podem precisar dos dois.

CPU síncrona

Um loop CPU-bound bloqueia o event loop e não percebe cancelamento até retornar. Divida o trabalho, verifique sinal entre lotes ou mova para Worker Threads.

Erros e status

Quando o servidor detecta que o orçamento acabou, retorne DEADLINE_EXCEEDED. Se uma dependência está indisponível antes do prazo, UNAVAILABLE pode ser mais correto.

Observabilidade

Registre:

  • deadline original;
  • tempo restante no início;
  • duração por dependência;
  • cancelamentos;
  • deadlines excedidas;
  • trabalho concluído após cancelamento;
  • retries evitados por orçamento;
  • fila antes da execução.

Crie histogramas por método, sem IDs de usuário.

SLO e deadline

O deadline do cliente deve considerar o SLO da operação. Se 99% precisam concluir em 500 ms, um deadline de 30 segundos esconde degradação e acumula trabalho.

Leia SLI e SLO no Node.js.

Testes

  • resposta dentro do prazo;
  • dependência lenta;
  • cancelamento propagado;
  • query interrompida;
  • retry sem tempo suficiente;
  • escrita concluída com resposta tardia;
  • stream ocioso;
  • CPU longa;
  • shutdown próximo ao deadline.

Erros comuns

  • chamada sem deadline;
  • timeout independente em cada serviço;
  • não cancelar dependências;
  • retry depois do orçamento acabar;
  • assumir que deadline significa rollback;
  • não reservar margem para resposta;
  • ignorar espera em pool;
  • usar deadline enorme para esconder lentidão.

Conclusão

gRPC Deadlines no Node.js transformam latência máxima em um contrato propagado pela cadeia. O objetivo não é apenas devolver erro no tempo certo, mas parar trabalho que deixou de ter valor.

Defina prazos por método, propague o tempo restante, cancele dependências e preserve idempotência em escritas. Com métricas, deadlines também protegem pools e evitam falhas em cascata.

Consulte a documentação oficial de deadlines do gRPC e o guia de cancellation.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita