theRPC
Ethereum

Ethereum

eth_getLogs

eth_getLogs returns all event logs that match a filter object. It's the foundational call for indexers, analytics pipelines, and any one-shot backfill that doesn't need a live subscription. Pair it with batching and you have a complete pull-based indexing strategy.

Filter shape

The filter is a single JSON object:

FieldTypeDescription
fromBlockstringLower bound — hex block number or tag (earliest, latest, pending, safe, finalized).
toBlockstringUpper bound — same shape as fromBlock.
addressstring | string[]One contract address or an array of addresses to filter on.
topics(string | string[] | null)[]Position-indexed topic filters. null matches anything in that slot.
blockHashstringRestrict to a single block by hash. Cannot be combined with fromBlock/toBlock.

The topics array is positional. Each slot holds either a single 32-byte topic hash, an array of alternatives (OR), or null (any). Topic 0 is conventionally the event signature hash.

Response shape

An array of log objects:

{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"blockHash": "0x...",
"blockNumber": "0x14a3b27",
"data": "0x000000000000000000000000000000000000000000000000000000003b9aca00",
"logIndex": "0x12",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000a1...",
"0x000000000000000000000000b2..."
],
"transactionHash": "0x...",
"transactionIndex": "0x3"
}
]
}

Sizing the request

eth_getLogs is one of the most expensive RPC methods in terms of upstream load. Keep these limits in mind:

  1. Block range: TheRPC caps a single call at ~10,000 blocks. Larger windows return query exceeds max block range. Paginate.
  2. Result size: Responses over 1 MB are truncated. If a single block returns many matches, narrow address or topics.
  3. Indexing: Filter by address and topics[0] when you can. Filtering by topics alone scans every contract.

Anti-patterns

  1. Don't poll eth_getLogs with fromBlock: "latest" in a tight loop. Use eth_newFilter + eth_getFilterChanges, or subscribe via eth_subscribe over a WebSocket endpoint.
  2. Don't pass huge address arrays. A long address: [...] array isn't a free win — providers serialize it linearly. Bucket and parallelise instead.
  3. Don't forget about reorgs. Logs from non-finalized blocks can disappear. For systems of record, re-query after a few blocks of confirmation or query against the finalized tag.

See also

Parameters

JSON filter object: { fromBlock?, toBlock?, address?, topics? }

curl https://ethereum.therpc.io \
-X POST \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"latest","toBlock":"latest","address":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}'

Ready to call this in production?

Free tier covers personal projects. Pay-as-you-go scales without a card.