JSON RPC batch requests load balancing

Hi.

Is there any load-balancing magic behind handling of batch JSON RPC requests (https://www.jsonrpc.org/specification#batch) at Infura? Can I assume that all requests from the batch will be routed and processed by the same RPC node standing behind the load balancer?

Hi @k1rill-fedoseev, and welcome to the Infura community! That should be the case in a batch - are you seeing something else occurring?

Yes. I have tried sending 30 eth_blockNumber requests at a time in a single batch. If I do that close to the latest block mining time, I can receive block X in some of the results and block X + 1 in the remaining results.

I don’t think this can be due to race condition, since I didn’t see such behaviour with direct Geth or OpenEthereum node RPC interaction.

This is how I came up with the original question.

Got it - thanks for the additional information! We’re having some trouble replicating the issue - can you share a code snippet with us from the code that’s producing this behaviour? Thanks!

Here is the curl request I just made:

curl --request POST \
  --url https://mainnet.infura.io/v3/PROJECT_ID \
  --header 'Content-Type: application/json' \
  --data '[
	{"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 2, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 3, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 4, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 5, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 6, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 7, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 8, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 9, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 10, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 12, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 13, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 14, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 15, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 16, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 17, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 18, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 19, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 20, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 21, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 22, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 23, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 24, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 25, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 26, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 27, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 28, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 29, "method": "eth_blockNumber", "params": []},
	{"jsonrpc": "2.0", "id": 30, "method": "eth_blockNumber", "params": []}
]'

And here is the result I got:

[
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 2,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 3,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 4,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 5,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 6,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 7,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 8,
    "result": "0xc6697e"
  },
  {
    "jsonrpc": "2.0",
    "id": 9,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 10,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 12,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 13,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 14,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 15,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 16,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 17,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 18,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 19,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 20,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 21,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 22,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 23,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 24,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 25,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 26,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 27,
    "result": "0xc6697e"
  },
  {
    "jsonrpc": "2.0",
    "id": 28,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 29,
    "result": "0xc6697f"
  },
  {
    "jsonrpc": "2.0",
    "id": 30,
    "result": "0xc6697f"
  }
]

Here I can see that two different block numbers: 0xc6697e and 0xc6697f, while I expect to see the same block number.

Thanks so much for the additional context! We’re digging into this and will let you know once we have something to share.

What was the outcome of the digging? I can’t find any details about infura’s load balancer which is pretty important for most applications. Seems like infura’s nodes can be completely out of sync, particularly in a re-org situation meaning you can get conflicting responses between RPC calls to the same RPC.

can you confirm or deny this please?