Config
erpc.yaml

Complete config example

This example config demonstrates all features of eRPC in one place. For more explanation of each section, refer to dedicated pages:

  • Database: to configure caching and database.
  • Projects: to define multiple projects with different rate limit budgets.
  • Networks: to configure failsafe policies for each network.
  • Upstreams: to configure upstreams with failsafe policies, rate limiters, allowed/rejected methods, etc.
  • Rate limiters: to configure various self-imposed budgets to prevent pressure on upstreams.
  • Failsafe: explains different policies such as retry, timeout, and hedges, used for networks and upstreams.

By default erpc binary will look for ./erpc.yaml file in the current directory. You can change this path by passing an argument to the binary:

$ erpc /path/to/your/erpc.yaml

Minimal erpc.yaml

eRPC will auto-detect or use sane defaults for various configs such as retries, timeouts, circuit-breaker, hedges, node architecture etc.

eRPC is Multi-chain
A single instance of eRPC can server multiple projects (frontend, indexer, etc) and multiple chains.

erpc.yaml
logLevel: debug
projects:
 - id: main
   upstreams:
   # Put all your RPC endpoints for any network here.
   # You don't need to define architecture (e.g. evm) or chain id (e.g. 42161)
   # as they will be detected automatically by eRPC.
   - endpoint: https://xxxxx.matic.quiknode.pro/xxxxxxxxxx/
   - endpoint: drpc://XXX_MY_DRPC.ORG_API_KEY_XXX # Add all supported chains of drpc.org
   - endpoint: blastapi://XXX_MY_BLASTAPI.IO_API_KEY_XXX # Add all supported chains of blastapi.io
   - endpoint: alchemy://XXX_MY_ALCHEMY.COM_API_KEY_XXX # Add all supported chains of alchemy.com
   - endpoint: envio://rpc.hypersync.xyz # Add all supported methods and chains of envio.dev HyperRPC

Full erpc.yaml

To have more control over the configuration, you can use the example below.

erpc.yaml
# Log level helps in debugging or error detection:
# - debug: information down to actual request and responses, and decisions about rate-liming etc.
# - info: usually prints happy paths and might print 1 log per request indicating of success or failure.
# - warn: these problems do not cause end-user problems, but might indicate degredataion or an issue such as cache databse being down.
# - error: these are problems that have end-user impact, such as misconfigurations.
logLevel: warn
 
# There are various use-cases of database in erpc, such as caching, dynamic configs, rate limit persistence, etc.
database:
  # `evmJsonRpcCache` defines the destination for caching JSON-RPC cals towards any EVM architecture upstream.
  # This database is non-blocking on critical path, and is used as best-effort.
  # Make sure the storage requirements meet your usage, for example caching 70m blocks + 10m txs + 10m traces on Arbitrum needs 200GB of storage.
  evmJsonRpcCache:
    # Refer to "Database" section for more details.
    # Note that table, schema and indexes will be created automatically if they don't exist.
    driver: postgresql
    postgresql:
      connectionUri: >-
        postgres://YOUR_USERNAME_HERE:YOUR_PASSWORD_HERE@your.postgres.hostname.here.com:5432/your_database_name
      table: rpc_cache
 
# The main server for eRPC to listen for requests.
server:
  listenV4: true
  httpHostV4: "0.0.0.0"
  listenV6: false
  httpHostV6: "[::]"
  httpPort: 4000
 
# Optional Prometheus metrics server.
metrics:
  enabled: true
  listenV4: true
  hostV4: "0.0.0.0"
  listenV6: false
  hostV6: "[::]"
  port: 4001
 
# Each project is a collection of networks and upstreams.
# For example "backend", "indexer", "frontend", and you want to use only 1 project you can name it "main"
# The main purpose of multiple projects is different failsafe policies (more aggressive and costly, or less costly and more error-prone)
projects:
  - id: main
 
    # Optionally you can define a self-imposed rate limite budget for each project
    # This is useful if you want to limit the number of requests per second or daily allowance.
    rateLimitBudget: frontend-budget
 
    # This array configures network-specific (a.k.a chain-specific) features.
    # For each network "architecture" and corresponding network id (e.g. evm.chainId) is required.
    # Remember defining networks is OPTIONAL, so only provide these only if you want to override defaults.
    networks:
      - architecture: evm
        evm:
          chainId: 1
        # Refer to "Failsafe" section for more details.
        # On network-level "timeout" is applied for the whole lifecycle of the request (including however many retries)
        failsafe:
          timeout:
            duration: 30s
          retry:
            maxCount: 3
            delay: 500ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
          # Defining a "hedge" is highly-recommended on network-level because if upstream A is being slow for
          # a specific request, it can start a new parallel hedged request to upstream B, for whichever responds faster.
          hedge:
            delay: 3000ms
            maxCount: 2
          circuitBreaker:
            failureThresholdCount: 30
            failureThresholdCapacity: 100
            halfOpenAfter: 60s
            successThresholdCount: 8
            successThresholdCapacity: 10
      - architecture: evm
        evm:
          chainId: 42161
        failsafe:
          timeout:
            duration: 30s
          retry:
            maxCount: 5
            delay: 500ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 200ms
          hedge:
            delay: 1000ms
            maxCount: 2
 
    # Each upstream supports 1 or more networks (chains)
    upstreams:
      - id: blastapi-chain-42161
        type: evm
        endpoint: https://arbitrum-one.blastapi.io/xxxxxxx-xxxxxx-xxxxxxx
        # Defines which budget to use when hadnling requests of this upstream.
        rateLimitBudget: global-blast
        # chainId is optional and will be detected from the endpoint (eth_chainId) but it is recommended to set it explicitly, for faster initialization.
        evm:
          chainId: 42161
        # Which methods must never be sent to this upstream:
        ignoreMethods:
          - "alchemy_*"
          - "eth_traceTransaction"
        # Refer to "Failsafe" section for more details:
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
      - id: blastapi-chain-1
        type: evm
        endpoint: https://eth-mainnet.blastapi.io/xxxxxxx-xxxxxx-xxxxxxx
        rateLimitBudget: global-blast
        evm:
          chainId: 1
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
      - id: quiknode-chain-42161
        type: evm
        endpoint: https://xxxxxx-xxxxxx.arbitrum-mainnet.quiknode.pro/xxxxxxxxxxxxxxxxxxxxxxxx/
        rateLimitBudget: global-quicknode
        # You can disable auto-ignoring unsupported methods, and instead define them explicitly.
        # This is useful if provider (e.g. dRPC) is not consistent with "unsupported method" responses.
        autoIgnoreUnsupportedMethods: false
        # To allow auto-batching requests towards the upstream, use these settings.
        # Remember if "supportsBatch" is false, you still can send batch requests to eRPC
        # but they will be sent to upstream as individual requests.
        jsonRpc:
          supportsBatch: true
          batchMaxSize: 10
          batchMaxWait: 100ms
        evm:
          chainId: 42161
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
 
        # "id" is a unique identifier to distinguish in logs and metrics.
      - id: alchemy-multi-chain-example
        # For certain known providers (such as Alchemy) you use a custom protocol name
        # which allows a single upstream to import "all chains" supported by that provider.
        # Note that these chains are hard-coded in the repo, so if they support a new chain eRPC must be updated.
        endpoint: alchemy://XXXX_YOUR_ALCHEMY_API_KEY_HERE_XXXX
        rateLimitBudget: global
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
 
# Rate limiter allows you to create "shared" budgets for upstreams.
# For example upstream A and B can use the same budget, which means both of them together must not exceed the defined limits.
rateLimiters:
  budgets:
    - id: default-budget
      rules:
        - method: "*"
          maxCount: 10000
          period: 1s
    - id: global-blast
      rules:
        - method: "*"
          maxCount: 1000
          period: 1s
    - id: global-quicknode
      rules:
        - method: "*"
          maxCount: 300
          period: 1s
    - id: frontend-budget
      rules:
        - method: "*"
          maxCount: 500
          period: 1s

Roadmap

On some doc pages we like to share our ideas for related future implementations, feel free to open a PR if you're up for a challenge:


  • Support a Typescript-based config to allow injecting env variables and code reusability.