I want to store data on chain that is not needed within a smart contract but should be retrieved easily and particularly quickly from outside. I know that storing the data within an indexed event is much cheaper than within a mapping inside a contract in terms of cost and storage but does the access also stay fast if the chain and data is growing and there are millions of events I have to filter that one out I want to read?

We are talking about a geth based private poa network.

  • 1
    Reading the events is not an onchain operation, the speed is then limited only by the how fast can the data from the local HD be read. The same applies for reading storage values. I do not mean these to operation are the same but the differences should be neglegible. In your case do not look like storage cost is a limitation, if that is the case, I would put everything in a mapping.
    – Jaime
    Mar 1, 2019 at 14:34
  • In general you are right. In particular it could be possible that geth needs 15 minutes to return a log filter on an indexed topic when the log file becomes very long. That also depends on the implementation. I read somewhere that geth is not that good at this. But the information was from 2017, so this could have changed. Maybe I have to try and compare the options by myself.
    – heinob
    Mar 1, 2019 at 14:53

1 Answer 1


This is a design pattern question. So, its kind of subjective. I am not sure the solution I am going to present here matches exactly with your conditions or not but it is worth to have a look.

The idea is in every events along with your important data, a lastBlock parameter is also emitted which points to the previous block in which your previous transactions are mined. The latest block number of your latest transaction is required to be stored in a contract. To fetch the required event, get the last block number from contract and loop to all events given by the lastBlock to find yours.

contract Test {

    event Event1(bytes data, uint256 updatedAt);
    event Event2(bytes data, uint256 updatedAt);

    // other metadata
    uint256 public lastBlock;

    function dosomething1(bytes data) public {
        emit Event1(data, lastBlock);
        lastBlock = block.number;

    function dosomething2(bytes data) public {
        emit Event2(data, lastBlock);
        lastBlock = block.number;

Now, in your application you can get last block from lastBlock() function to start. Loop and get the previous block number updatedAt from your events Event1 and Event2 and continue until you get the one you require. That means you do not have to loop all over the blockchain but you can jump from one block to another directly.

Hope it helps.

  • 1
    Looping even over this chained list like in your solution is no option. I want to get the data with one request. That's why I think about using an indexed event and filter it out. The question was how fast a filtered read on an indexed topic is if there a > 1 Mio events within the log.
    – heinob
    Mar 1, 2019 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.