GSN Gas overhead? 10%?

I was curious to know what the gas overhead is for Dapps using the GSN . Im not considering the cost to the developer, only the EVM costs when a given function is called in both non-GSN and GSN enabled contract. I deployed two instances of a SimpleStorage contract that stores an integer on the Ganache test chain:

instance 1: simple storage contract with no OZ library:
Set function Gas usage: 26684

instance 2: same contract with OZ libs (GSNRecipient.sol" Initializable.sol";):
Set function Gas usage: 29364 or 10.043% more

I think for now that it is a reasonable overhead when one considers the benefits of GSN. Did anyone get similar results and or do such tests?

1 Like

Hi @Steeve,

Thanks for sharing. :pray:

I haven’t tried this test. I assume that you were calling the RelayHub contract when you tested with GSN.

On top of this will also be the gas cost of the GSN Strategy being used to determine whether to accept the relayed call:

Hi @Steeve,

Using Building a GSN-powered DApp guide (but with regular contracts rather than upgradeable)

I ran a simple test to call the increase function of the Counter contract. No GSN strategies were used (all relayed calls were accepted).

This is a simple function call, so would consider the overhead more of a fixed amount rather than a percentage.

Direct transaction

Calling increase via the CLI

$ npx oz send-tx
? Pick a network rinkeby
? Pick an instance Counter at 0x9839516a22b383267c4d31DCFD66b4794Df94527
? Select which function increase()
✓ Transaction successful. Transaction hash: 0x620e598d4a40b3a5bdd61e269b2e34e46ec8d62472c54ae890d8bc8af75043ed
Gas Used by Transaction: 27,107

Relayed via the GSN
Gas Used by Transaction: 82,691

When i did it i used Ganache. Would the cases you ran, result in the same each time? 3x ?

My example was for a simple storage that stores an integer. My result i guess didn’t show the relaying overhead.

Is your analysis for the function + the relay?
Or two separate calls : one to function without relay and the other same with relay call?

1 Like

Hi @Steeve,

The direct transaction was a single call directly to the increase function.
The GSN transaction was via a Relayer and the cost shown by Etherscan to call the increase function via the GSN.

I suggest trying it yourself on a public testnet using the Building a GSN-powered DApp guide. You can then modify the contract to experiment with different options.

The increase function is very basic, so I would expect more complex functions to be a greater part of the gas cost of a GSN transaction.


// contracts/Counter.sol
pragma solidity ^0.5.0;

import "@openzeppelin/contracts-ethereum-package/contracts/GSN/GSNRecipient.sol";

contract Counter is GSNRecipient {
    uint256 public value;

    function increase() public {
        value += 1;

    function acceptRelayedCall(
        address relay,
        address from,
        bytes calldata encodedFunction,
        uint256 transactionFee,
        uint256 gasPrice,
        uint256 gasLimit,
        uint256 nonce,
        bytes calldata approvalData,
        uint256 maxPossibleCharge
    ) external view returns (uint256, bytes memory) {
        return _approveRelayedCall();

    // We won't do any pre or post processing, so leave _preRelayedCall and _postRelayedCall empty
    function _preRelayedCall(bytes memory context) internal returns (bytes32) {

    function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal {