---
title: "Como reconstruímos os logs históricos para mais velocidade"
description: "Reconstruímos o storage e o query engine por trás do eth_getLogs, tornando as leituras de logs históricos em grandes intervalos mais de 2x mais rápidas no p99 em todas as regiões."
---

# Como reconstruímos os logs históricos para mais velocidade

<ImageBlock
  src="https://media.alchemy.com/blog/how-we-rebuilt-historical-logs-for-speed-16x9-20260821.png"
  alt="Como reconstruímos logs históricos para velocidade"
  width={1920}
  height={1080}
  priority
/>

Pergunte a qualquer equipe que constrói um indexador, um agregador de DEX ou um sistema de monitoramento onchain onde a aplicação deles fica lenta, e a resposta é quase sempre a mesma: `eth_getLogs` com ranges grandes.

É a chamada que varre milhares ou centenas de milhares de blocos para responder uma única pergunta. Quais transfers atingiram esse contrato no mês passado? Quais pools mudaram de estado nesse range? Quais eventos foram disparados para esse endereço desde o lançamento? Essas leituras são a espinha dorsal de aplicações reais, e também são as leituras com maior probabilidade de travar. Por isso reconstruímos o engine que serve essas chamadas, e tornamos o método mais de 2x mais rápido no p99 em todas as regiões. Veja como.

## O que é eth_getLogs e por que isso importa?

`eth_getLogs` é o método JSON-RPC que retorna os eventos que smart contracts emitem durante a execução: um transfer de token, um swap, uma approval, ou qualquer evento customizado definido por um contrato. Você filtra por endereço de contrato, por assinatura de evento ou valores de topic indexados (como `Transfer` ou `Approval`), e por um range de blocos com um `fromBlock` e um `toBlock`. Em termos simples: você diz o que procurar e até onde olhar, e ele retorna todo evento correspondente.

Essa é a base da indexação orientada a eventos na Ethereum. Sem ela, você teria que varrer cada transação manualmente para encontrar as que te interessam. Com ela, você constrói feeds de atividade e de transfers, monitoramento de approvals, e qualquer indexador de eventos em tempo real ou histórico. É um dos métodos mais usados e operacionalmente críticos que servimos. Se você é novo em logs e topics, nosso [deep dive sobre `eth_getLogs`](https://www.alchemy.com/docs/reference/eth-getlogs) percorre a estrutura de request e response com um exemplo prático.

O restante do método molda o problema de engenharia. Muitos providers limitam quantos blocos você pode consultar de uma vez. Indexadores precisam lidar com reorgs da chain esperando confirmações. Filtros de topic só correspondem a campos indexados, então argumentos não indexados precisam ser decodificados a partir do raw data. E chamadas próximas ao head da chain são sensíveis a latência, onde rotear para o tipo errado de node pode causar erros ou respostas vazias.

A parte que mais molda a latência é o tamanho do range. Pedir um único bloco é instantâneo. Para um indexador reproduzindo histórico, ou um monitor observando um contrato ao longo de semanas, os ranges ficam largos rapidamente, e o custo da query sobe junto. É aí que a latência deixa de ser um erro de arredondamento e passa a limitar a velocidade com que um cliente consegue construir.

Todo mundo oferece o método. Poucos falam sobre o engine por baixo dele, porque reconstruir esse engine é caro e a maioria dos providers não fez isso.

## Por que a latência p99 importa mais do que a latência média?

O número que dói não é a média. É o p99: ordene cada request do mais rápido ao mais lento, e o p99 é o mais lento entre cem. Médias escondem isso. Você pode servir 99 requests em 60 milissegundos e ainda ver a centésima levar um segundo inteiro.

Esse request mais lento é o que trava um dashboard ou faz um indexador ficar para trás da chain, e é o que o seu usuário está olhando naquele momento. A latência média pode parecer boa enquanto a cauda quietamente quebra a carga de trabalho. Para equipes rodando indexadores e monitores, a cauda é a carga de trabalho.

## Como otimizamos o eth_getLogs?

Reconstruímos o storage e o query engine que servem o método, em vez de ajustar o que já existia.

Há algumas maneiras de deixar uma chamada como essa mais rápida. Você pode ajustar parâmetros de query, adicionar um cache, limitar os ranges aceitos, ou jogar mais do mesmo hardware nela. A maioria dessas opções compra um pouco de fôlego sem mudar os fundamentos.

Fomos mais a fundo. Em vez de depender de um banco de dados gerenciado de propósito geral que trata leituras de logs históricos como qualquer outra carga de trabalho, rodamos uma camada de storage e query ajustada especificamente para o padrão de acesso de `getLogs`: varreduras filtradas rápidas sobre datasets muito grandes, em infraestrutura dedicada que operamos nós mesmos.

Não ajustamos um botão nem plugamos um cache no sistema antigo. Investimos no nível do método, no engine por baixo de uma das chamadas mais críticas que nossos clientes fazem. É um trabalho de infraestrutura caro, por método, e é por isso que a melhoria aparece na cauda, não só na média.

## Quais são os resultados?

O destaque é simples: mais de 2x mais rápido no p99, em todas as regiões.

Se você roda um indexador ou um monitor, o p99 é a latência que quebra sua carga de trabalho. Uma média melhor é bom. Uma cauda melhor é o que mantém um dashboard responsivo e um indexador atualizado com a chain.

Equipes rodando isso em escala séria já estão vendo o efeito. Uma das maiores exchanges de cripto fez benchmark das leituras históricas de logs delas no nosso engine contra rodar seus próprios nodes, e mediu uma grande melhora de p99 na própria carga de trabalho. Isso é prova em produção, na instrumentação do próprio cliente, não só nos nossos dashboards.

## O que isso significa para você?

Se sua aplicação depende de leituras de logs históricos para indexação, agregação ou monitoramento, você ganha leituras mais rápidas e uma cauda de p99 dramaticamente melhor, em todas as regiões, em infraestrutura que reconstruímos especificamente para esse método. Algumas coisas que vale a pena saber ao colocar isso em prática:

1. Nos planos pay-as-you-go e enterprise, `eth_getLogs` suporta ranges de blocos ilimitados em uma única query na Ethereum, Base, Optimism, Arbitrum, Polygon, Robinhood e outras chains principais, então reproduzir histórico não exige paginação manual.
2. Para logs no head da chain, [WebSocket subscriptions](https://www.alchemy.com/docs/reference/subscription-api) enviam novos logs para você assim que chegam, então você reserva `eth_getLogs` para as leituras históricas para as quais ele foi construído.
3. Nada muda na sua integração. É o mesmo método, o mesmo formato de request, servido por um engine mais rápido.

O sentido de investir no nível do método é que as leituras que definem sua carga de trabalho são exatamente as que ajustamos o engine para atender. [Crie uma conta gratuita na Alchemy](https://dashboard.alchemy.com/signup) e aponte seu indexador para nós para ver a diferença na sua própria instrumentação.

## Perguntas frequentes

### O que o eth_getLogs retorna?

Um array de logs de eventos que correspondem ao seu filtro: endereço de contrato, assinatura de evento e valores de topic indexados, e um range de blocos. Cada log inclui o endereço emissor, os topics, o payload de dados, e o bloco e a transação de onde veio. Veja a [referência da API](https://www.alchemy.com/docs/reference/eth-getlogs) para a especificação completa de request e response.

### Por que a latência p99 é mais importante do que a latência média para indexadores?

Porque um indexador processa requests em sequência ou em lotes, os requests mais lentos ditam o ritmo. Uma média baixa com uma cauda longa significa que o indexador regularmente trava no um por cento mais lento, fica para trás do head da chain, e serve dados desatualizados. O p99 mede exatamente esses requests.

### Quais ranges de blocos posso consultar em uma única chamada eth_getLogs na Alchemy?

No plano gratuito, 10 blocos por query. Nos planos pay-as-you-go e enterprise, os ranges de blocos são ilimitados na Ethereum, Base, Optimism, Arbitrum, Polygon, Worldchain, BNB, e várias outras chains, com respostas limitadas a 150MB. A tabela completa por chain está na [referência de `eth_getLogs`](https://www.alchemy.com/docs/reference/eth-getlogs).

### Como mantenho queries históricas grandes rápidas?

Filtre o máximo que puder: especifique o endereço de contrato e os topics de evento que você precisa, não apenas um range de blocos. Para ranges muito largos em chains sem suporte a range ilimitado, divida a query em pedaços menores. E para novos logs daqui para frente, use [WebSocket subscriptions](https://www.alchemy.com/docs/reference/subscription-api) em vez de polling.
