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
maxTimeout: 30s
enableGzip: true
tls:
enabled: false
certFile: "/path/to/cert.pem"
keyFile: "/path/to/key.pem"
caFile: "/path/to/ca.pem" # Optional, for client cert verification
insecureSkipVerify: false # Optional, defaults to false
# 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.