---
title: "Como fazemos o benchmark de desempenho de RPC"
description: "Números de benchmark são fáceis de citar e fáceis de interpretar errado. Veja exatamente como o benchmark público de leitura EVM da Alchemy mede latência, taxa de sucesso, falhas e timeouts sob condições controladas."
---

# Como fazemos o benchmark de desempenho de RPC

<ImageBlock
  src="https://media.alchemy.com/blog/how-we-benchmark-rpc-performance-hero-v2.png"
  alt="Imagem principal da metodologia de benchmark"
  width={1024}
  height={480}
  priority
/>

[Números de benchmark](https://www.alchemy.com/benchmarks) são fáceis de citar e fáceis de interpretar mal. Isso vale especialmente para [desempenho de RPC](https://www.alchemy.com/overviews/rpc-node). Um único gráfico de latência pode esconder várias perguntas diferentes: onde a requisição começou, qual método foi executado, qual payload foi enviado, o que contou como sucesso, como as falhas foram tratadas, e se o teste mediu uma única chamada RPC ou um fluxo completo de aplicação.

Construímos nosso [benchmark público de leitura EVM](https://www.alchemy.com/benchmarks) para tornar esses detalhes visíveis. O objetivo é mostrar como os provedores se comparam sob uma configuração de teste controlada e repetível.

Nosso benchmark responde como os provedores se comparam em métodos comuns de leitura JSON-RPC EVM, em determinadas chains, regiões e janelas de tempo.

Estes são benchmarks de infraestrutura no nível de método: uma metodologia controlada executada separadamente para cada método, chain, provedor e região. Eles medem requisições RPC individuais, não fluxos completos de aplicação como carregar o portfólio de uma wallet, preparar um swap, ou fazer polling do status de uma transação ao longo de várias chamadas. Essa distinção importa: resultados no nível de método ajudam desenvolvedores a comparar o comportamento dos provedores, mas não são um modelo completo de nenhuma aplicação em produção.

## O que é o benchmark público de leitura EVM da Alchemy?

O [benchmark público de leitura EVM](https://www.alchemy.com/benchmarks) da Alchemy é um teste controlado que mede como os provedores de RPC respondem a requisições de leitura JSON-RPC EVM configuradas. Ele captura latência de respostas bem-sucedidas (média, p50 e p95), taxa de sucesso e contagem de requisições com falha, agrupadas por provedor, chain, método, região e janela de tempo.

Calculamos a latência apenas a partir de respostas bem-sucedidas. Tentativas com falha e timeouts são rastreados separadamente, por meio da taxa de sucesso e da contagem de requisições com falha. Isso mantém o benchmark focado tanto em velocidade quanto em confiabilidade, em vez de tratar qualquer uma das métricas isoladamente.

## Definições e regras de medição

As definições, a configuração e as regras sobre as quais o restante deste post se apoia. Cada linha é detalhada nas seções abaixo.

<EmbeddedTable
  table={{
    columns: [
      {
        key: "concept",
        width: 260,
        title: "Concept or rule",
        dataType: "object",
      },
      {
        key: "meaning",
        width: 680,
        title: "What it means",
        dataType: "object",
      },
    ],
    data: [
      {
        concept: { title: "What the benchmark measures", tooltip: "", icon: "" },
        meaning: {
          title:
            "Successful-response latency (average, p50, p95), success rate, and failed-request counts for configured EVM JSON-RPC read requests. Results are grouped by provider, chain, method, region, and time window.",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        concept: { title: "JSON-RPC", tooltip: "", icon: "" },
        meaning: {
          title:
            'The standard message format apps use to ask blockchain nodes for data. In plain English, the app sends a structured request like "get this wallet balance" or "return this transaction receipt," and the node sends back a structured answer.',
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        concept: { title: "Method-level benchmark", tooltip: "", icon: "" },
        meaning: {
          title:
            "A test of one configured RPC request with one payload, such as eth_getBalance, eth_getBlockByNumber, eth_getLogs, or eth_getTransactionReceipt.",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        concept: { title: "What is not measured", tooltip: "", icon: "" },
        meaning: {
          title:
            "Full app workflows, write transactions, customer-specific traffic mixes, first-request connection setup, block freshness, every chain, every provider, and every possible payload shape.",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
      {
        concept: { title: "Request origin", tooltip: "", icon: "" },
        meaning: {
          title:
            "The benchmark runs from controlled AWS ECS regions: US East, US West, EU Central, and AP Southeast. This describes benchmark traffic only, not all Alchemy production traffic.",
          tooltip: "",
          icon: "",
        },
        id: 4,
      },
      {
        concept: { title: "Test frequency", tooltip: "", icon: "" },
        meaning: {
          title: "Common public EVM read methods run approximately every 10 seconds.",
          tooltip: "",
          icon: "",
        },
        id: 5,
      },
      {
        concept: { title: "Success criteria", tooltip: "", icon: "" },
        meaning: {
          title:
            "A request succeeds only if it returns before the 8-second timeout, returns HTTP 2xx, parses as JSON, and does not contain a JSON-RPC error object.",
          tooltip: "",
          icon: "",
        },
        id: 6,
      },
      {
        concept: { title: "Latency calculation", tooltip: "", icon: "" },
        meaning: {
          title:
            "Latency is measured only for successful responses. It is runner-side wall-clock time for the measured JSON-RPC POST request and response over a warmed, reused HTTP connection.",
          tooltip: "",
          icon: "",
        },
        id: 7,
      },
      {
        concept: { title: "Timeout handling", tooltip: "", icon: "" },
        meaning: {
          title:
            "Timeouts count as failures. They are not inserted into latency calculations as 8,000 ms responses.",
          tooltip: "",
          icon: "",
        },
        id: 8,
      },
      {
        concept: { title: "Retries", tooltip: "", icon: "" },
        meaning: {
          title:
            "None. The benchmark makes one attempt. If that attempt fails, the failure is counted.",
          tooltip: "",
          icon: "",
        },
        id: 9,
      },
      {
        concept: { title: "Latency with success rate", tooltip: "", icon: "" },
        meaning: {
          title:
            "Latency shows how quickly valid responses return. Success rate shows how often they return successfully at all.",
          tooltip: "",
          icon: "",
        },
        id: 10,
      },
    ],
  }}
/>

## O que o benchmark cobre?

O benchmark cobre as mainnets de Ethereum, Optimism, Arbitrum, Base e World Chain, e o conjunto de provedores públicos inclui Alchemy, dRPC, Infura e QuickNode. Selecionamos esses para cobrir as mainnets EVM mais usadas e os provedores de RPC que os desenvolvedores mais costumam avaliar, com espaço para expandir o conjunto ao longo do tempo. Para um dado método, todos os provedores recebem a mesma requisição JSON-RPC configurada.

Executamos cada teste a partir de regiões AWS ECS controladas: US East, US West, EU Central e AP Southeast. Dentro de uma região, todos os provedores são testados a partir do mesmo local do runner, porque a distância de rede pode mudar a latência. Se testássemos um provedor a partir da Virgínia e outro de Singapura, o resultado diria tanto sobre geografia quanto sobre o desempenho do provedor.

Cada resultado é agrupado por:

- Provedor
- Chain
- Método
- Região
- Janela de tempo móvel

## O que o benchmark envia para cada provedor?

Um método é a operação chamada, como `eth_getBalance` ou `eth_getLogs`. Um payload é a requisição completa que enviamos para exercitar esse método, incluindo seus parâmetros. A distinção importa porque o desempenho depende de ambos: uma consulta barata e uma varredura de intervalo grande impõem cargas muito diferentes a um provedor, e até um único método pode variar conforme suas entradas.

Para um dado método, todos os provedores recebem o mesmo payload JSON-RPC configurado, em uma conta paga padrão. Essa é a regra de imparcialidade: mesmo método, mesmos parâmetros, mesma chain, mesma região, mesmo timeout, mesmos critérios de sucesso, e nenhum tratamento especial para nenhum provedor.

Hoje isso significa sete testes configurados na maioria das chains, e oito na Ethereum:

- `eth_getBalance`: uma consulta de saldo de conta
- `eth_getBlockByNumber` no bloco `earliest`: uma leitura de cabeçalho no início da chain
- `eth_getBlockByNumber` no bloco `latest`: uma leitura de cabeçalho na ponta da chain
- `eth_getLogs` em um intervalo de 1 bloco
- `eth_getLogs` em um intervalo de 10 blocos
- `eth_getLogs` em um intervalo de 100 blocos
- `eth_getLogs` em um intervalo de 1.000 blocos (somente Ethereum)
- `eth_getTransactionReceipt`: uma consulta de recibo de transação única

Alguns payloads se movem junto com a chain. Chamadas que usam a tag de bloco `latest`, por exemplo, mudam conforme a chain avança. Outras usam entradas históricas fixas: os testes de `eth_getLogs` da Ethereum usam intervalos de blocos históricos configurados para o contrato do token LINK.

A combinação é intencional:

- Entradas fixas tornam partes do teste repetíveis.
- Entradas móveis fazem com que partes do teste reflitam o estado ao vivo da chain.
- Entradas históricas fixas podem ser mais fáceis de cachear pelos provedores.

O desempenho de RPC pode variar bastante dependendo do método, dos parâmetros, do intervalo de blocos, do tamanho da resposta, do comportamento de cache e do estado da chain. Ao ler o benchmark, foque no método e nos parâmetros mais próximos da sua própria carga de trabalho.

## Como o desempenho é medido?

Medimos o desempenho por meio de dois sinais, cada um respondendo a uma pergunta diferente: latência, a velocidade com que respostas bem-sucedidas retornam (reportada como média, p50 e p95), e taxa de sucesso, a frequência com que as requisições têm sucesso (com a contagem de requisições com falha por trás disso).

Os dois estão relacionados, mas são distintos: uma resposta bem-sucedida rápida não é a mesma coisa que uma resposta confiável. Reportamos os dois lado a lado para que nenhum esconda o outro.

## Como a latência é medida?

Latência é o tempo medido pelo runner para uma requisição e resposta bem-sucedida de um POST JSON-RPC. O cronômetro começa quando o runner envia a requisição e para quando recebe a resposta. Se um provedor retorna uma resposta válida em 120 milissegundos, essa requisição tem 120 ms de latência.

Usamos conexões HTTP aquecidas e reutilizadas. Em termos simples, não cronometramos as etapas iniciais de configuração necessárias para abrir uma nova conexão, como consulta DNS, estabelecimento de conexão TCP ou handshake TLS. O runner prepara a conexão primeiro, e só depois mede o próprio POST sobre uma conexão keep-alive reutilizada de um pool.

Isso aproxima o número de latência do tráfego repetido de uma aplicação real, onde os clientes costumam reutilizar conexões. Também significa que você não deve ler esses números como latência de primeira requisição a frio.

Somente respostas bem-sucedidas entram na distribuição de latência. Se uma requisição expira, retorna um erro HTTP, retorna um objeto de erro JSON-RPC, falha ao fazer parse, ou sofre um erro de rede, contamos como uma tentativa com falha.

Timeouts não são tratados como respostas lentas de 8.000 ms. Nós os excluímos da latência e os contamos na taxa de sucesso, o que mantém a latência focada em velocidade de resposta e a taxa de sucesso focada em confiabilidade.

## O que é taxa de sucesso?

Taxa de sucesso é a parcela de requisições tentadas que retornaram com sucesso sob as regras do benchmark: requisições bem-sucedidas dividido pelo total de requisições tentadas.

Uma requisição conta como bem-sucedida somente se todas as condições a seguir forem atendidas:

1. Ela completa antes do timeout do benchmark.
2. Ela retorna um status HTTP 2xx.
3. O corpo da resposta faz parse como JSON.
4. A resposta JSON-RPC não contém um objeto `error` não nulo.

Não usamos retries para esconder tentativas com falha. Uma requisição tentada tem uma chance. Se ela falha, a falha é contada.

## Como o benchmark trata timeouts?

O runner do benchmark aguarda até 8 segundos por uma resposta válida de cada provedor. Se nenhuma resposta válida chega a tempo, registramos a tentativa como falha por timeout.

O limite de 8 segundos faz parte da nossa configuração de teste. Ele não é definido pela chain, e não é o timeout que um provedor possa usar internamente.

O limite de 8 segundos se aplica hoje a todos os métodos públicos de leitura EVM. Um método específico poderia ser configurado com um timeout diferente, mas nenhum atualmente é.

## O que conta como requisição com falha?

Rastreamos tentativas com falha separadamente da latência. Uma requisição é contada como falha se ela:

- retorna um status HTTP não-2xx, como 403, 429, 500, 502, 503 ou 504
- retorna um objeto de erro JSON-RPC
- expira após 8 segundos
- falha no nível de rede, ou
- falha ao fazer parse como JSON válido

Respostas de rate limit contam como falhas, e nunca usamos retries para converter tentativas com falha em sucessos. Cada falha reduz a taxa de sucesso do provedor e soma à sua contagem de requisições com falha para aquele método, chain, região e janela.

## Como as métricas são definidas?

<EmbeddedTable
  table={{
    columns: [
      { key: "metric", width: 200, title: "Metric", dataType: "object" },
      {
        key: "technicalDefinition",
        width: 320,
        title: "Technical definition",
        dataType: "object",
      },
      {
        key: "plainEnglishMeaning",
        width: 280,
        title: "Plain-English meaning",
        dataType: "object",
      },
      {
        key: "importantCaveat",
        width: 280,
        title: "Important caveat",
        dataType: "object",
      },
    ],
    data: [
      {
        metric: { title: "Average latency", tooltip: "", icon: "" },
        technicalDefinition: {
          title:
            "Sum of successful response times divided by count of successful responses.",
          tooltip: "",
          icon: "",
        },
        plainEnglishMeaning: {
          title: "On successful calls, how long did the provider take on average?",
          tooltip: "",
          icon: "",
        },
        importantCaveat: {
          title: "Excludes failures, so it must be read with success rate.",
          tooltip: "",
          icon: "",
        },
        id: 0,
      },
      {
        metric: { title: "p50 latency", tooltip: "", icon: "" },
        technicalDefinition: {
          title:
            "Median latency across successful responses in the same provider, chain, method, region, and window group.",
          tooltip: "",
          icon: "",
        },
        plainEnglishMeaning: {
          title: "The typical successful response time.",
          tooltip: "",
          icon: "",
        },
        importantCaveat: {
          title: "Can hide slower tail behavior.",
          tooltip: "",
          icon: "",
        },
        id: 1,
      },
      {
        metric: { title: "p95 latency", tooltip: "", icon: "" },
        technicalDefinition: {
          title:
            "The latency point where 95% of successful responses were faster and 5% were slower.",
          tooltip: "",
          icon: "",
        },
        plainEnglishMeaning: {
          title: "How slow successful requests get outside the normal case.",
          tooltip: "",
          icon: "",
        },
        importantCaveat: {
          title:
            "Timeouts are not included as 8-second samples; they count as failures.",
          tooltip: "",
          icon: "",
        },
        id: 2,
      },
      {
        metric: { title: "Success rate", tooltip: "", icon: "" },
        technicalDefinition: {
          title: "Successful requests divided by total attempted requests.",
          tooltip: "",
          icon: "",
        },
        plainEnglishMeaning: {
          title: "How often the provider returned successfully under the test rules.",
          tooltip: "",
          icon: "",
        },
        importantCaveat: {
          title: "The reliability companion to latency.",
          tooltip: "",
          icon: "",
        },
        id: 3,
      },
      {
        metric: { title: "Failed requests", tooltip: "", icon: "" },
        technicalDefinition: {
          title: "Count of attempts that did not meet the success criteria.",
          tooltip: "",
          icon: "",
        },
        plainEnglishMeaning: {
          title: "How many requests failed.",
          tooltip: "",
          icon: "",
        },
        importantCaveat: {
          title: "Shown as counts per method; the flip side of success rate.",
          tooltip: "",
          icon: "",
        },
        id: 4,
      },
    ],
  }}
/>

## Por que reportar latência e taxa de sucesso juntas?

Respostas rápidas só importam quando as respostas realmente retornam. Um provedor pode mostrar baixa latência nas requisições que têm sucesso ao mesmo tempo em que expira ou falha com mais frequência, então reportamos a latência ao lado da taxa de sucesso: a latência mostra a velocidade com que respostas válidas retornam, a taxa de sucesso mostra a frequência com que elas retornam.

Por exemplo, se enviamos 1.000 tentativas e 990 retornam com sucesso antes do timeout de 8 segundos, a taxa de sucesso é de 99%. As 10 tentativas com falha não entram no p50, p95 ou na latência média; elas aparecem como falhas de confiabilidade.

Isso evita duas leituras equivocadas: um provedor com baixa latência mas mais falhas não deve ser julgado apenas pela velocidade, e um provedor com alta taxa de sucesso mas latência de cauda mais lenta não deve ser julgado apenas pela confiabilidade.

## Por que o benchmark usa uma janela móvel?

O benchmark roda continuamente. Os métodos comuns de leitura pública EVM rodam aproximadamente a cada 10 segundos, e atualizamos a [página pública do benchmark](https://www.alchemy.com/benchmarks) a cada 5 minutos a partir de uma janela móvel de 24 horas.

Com uptime total, um método que roda a cada 10 segundos produz cerca de 8.640 tentativas por provedor, método, rede e região a cada dia. Uma janela móvel de 24 horas dá a cada número público amostras suficientes para suavizar oscilações pontuais mantendo a página atualizada.

Então leia a página pública como um resumo diário móvel, não como uma única requisição, um teste único, ou um instantâneo momentâneo.

## O que o benchmark não mede?

Hoje, o benchmark mede desempenho de leitura de método único a quente, sob condições controladas. Ele não mede:

- Fluxos de usuário com múltiplas chamadas
- Transações de escrita ou envio de transações
- Comportamento de WebSocket ou de subscription
- Combinações de requisições específicas de clientes
- Configuração de conexão a frio na primeira requisição
- Todos os provedores, chains, regiões, métodos ou formatos de payload
- O comportamento exato da sua própria arquitetura, nível de tráfego ou geografia de implantação

Esse limite é o que torna o benchmark útil: ele mostra onde os números se aplicam e onde você deveria rodar seus próprios testes específicos de carga de trabalho.

Velocidade e confiabilidade são perguntas relacionadas, mas separadas:

- Velocidade pergunta com que rapidez requisições bem-sucedidas retornam.
- Confiabilidade pergunta com que frequência as requisições retornam com sucesso.

Projetamos o benchmark para mostrar essa distinção, em vez de achatá-la em uma única afirmação de "provedor mais rápido".

## Como os desenvolvedores devem usar os resultados?

Use o [benchmark público](https://www.alchemy.com/benchmarks) como ponto de partida para avaliar provedores. Um padrão prático de leitura:

1. Escolha a chain e o método mais próximos da sua carga de trabalho.
2. Compare a região que melhor corresponde a onde seus usuários ou infraestrutura estão.
3. Observe o p95, não apenas a média ou o p50.
4. Verifique a taxa de sucesso ao lado da latência.
5. Se sua carga de trabalho usa payloads diferentes, maior concorrência, escritas, WebSockets ou fluxos com múltiplas chamadas, execute um benchmark específico para sua carga de trabalho antes de decidir.

Benchmarks transparentes ajudam você a fazer perguntas melhores. Eles facilitam ver o que foi testado, o que foi contado, o que foi excluído, e quais partes do resultado mais importam para uma aplicação real.

## Perguntas frequentes

### O que é o benchmark público de leitura EVM da Alchemy?

É um teste controlado que mede como os provedores de RPC lidam com requisições comuns de leitura JSON-RPC EVM. Ele registra latência de respostas bem-sucedidas (média, p50, p95), taxa de sucesso e contagem de requisições com falha em determinados provedores, chains, métodos e regiões, permitindo que desenvolvedores comparem provedores sob condições idênticas e repetíveis, em vez de alegações de marketing.

### Como a latência de RPC é medida?

Latência é o tempo medido pelo runner para um POST JSON-RPC e sua resposta, sobre uma conexão aquecida e reutilizada. O cronômetro começa quando a requisição é enviada e para quando uma resposta válida chega. Somente respostas bem-sucedidas contam, então a latência reflete a velocidade de resposta, não a configuração de conexão nem as falhas.

### O que conta como requisição bem-sucedida?

Uma requisição tem sucesso somente se retorna dentro do timeout de 8 segundos, retorna um status HTTP 2xx, faz parse como JSON, e não contém nenhum objeto de erro JSON-RPC. Qualquer outra coisa, incluindo timeouts, erros HTTP e respostas de rate limit, é contada como uma tentativa com falha e excluída da latência.

### Como o benchmark trata timeouts?

O runner aguarda até 8 segundos por uma resposta válida. Se nenhuma chega, a tentativa é registrada como falha por timeout, não como uma resposta lenta de 8.000 ms. Timeouts reduzem a taxa de sucesso, mas nunca inflam a latência, o que mantém velocidade e confiabilidade como medições separadas.

### O benchmark usa retries?

Não. Cada medição é uma única tentativa. Se essa tentativa falha, a falha é contada em vez de ser refeita. Isso mantém a taxa de sucesso honesta, já que retries esconderiam as falhas intermitentes que as aplicações reais de fato enfrentam.

### Quais chains e provedores o benchmark inclui?

O benchmark público cobre as mainnets de Ethereum, Optimism, Arbitrum, Base e World Chain. O conjunto de provedores inclui Alchemy, dRPC, Infura e QuickNode. Cada provedor recebe a mesma requisição configurada para um dado método, a partir da mesma região, sob as mesmas regras de timeout e sucesso.

### Quais métodos de RPC o benchmark testa?

O benchmark executa sete testes de leitura configurados, construídos a partir de quatro métodos EVM: `eth_getBalance`; `eth_getBlockByNumber` nos blocos mais antigo e mais recente; `eth_getLogs` em intervalos de 1, 10 e 100 blocos; e `eth_getTransactionReceipt`. A Ethereum adiciona um teste de `eth_getLogs` de 1.000 blocos, totalizando oito. Cada um usa um payload fixo, mantendo os resultados comparáveis entre provedores.

### O que o benchmark não mede?

Ele não mede fluxos completos de aplicação, transações de escrita, subscriptions de WebSocket, combinações de tráfego específicas de clientes, ou configuração de conexão a frio. Também não cobre todas as chains, provedores, regiões, métodos ou payloads. Para esses casos, execute um benchmark específico que corresponda ao seu próprio tráfego.

### Como devo interpretar um número de latência p95?

Leia o p95 assim: para esse método, chain, região e janela de tempo, 95% das respostas bem-sucedidas foram pelo menos tão rápidas quanto esse valor. Ele expõe o comportamento de cauda que a média esconde. Leia-o sempre ao lado da taxa de sucesso, já que respostas rápidas só importam quando as respostas de fato retornam.
