Config
Database
Drivers

Drivers

AIOpen as plain markdown for AI

Depending on your use-case storage and performance requirements, you can use different drivers.

Memory

Mainly useful when you want fast access for limited amount of cached data. Use this driver for high-frequency RPC calls.

databaseevmJsonRpcCacheconnectors[]
erpc.yaml
database:  evmJsonRpcCache:    connectors:      - id: memory-cache        driver: memory        memory:          maxItems: 10000          maxTotalSize: '1GB'          # For debugging purposes, enable metrics collection (expect 10% performance hit)          emitMetrics: false    policies:      - network: '*'        method: '*'        finality: finalized        connector: memory-cache

Redis

Redis is useful when you need to store cached data temporarily with eviction policy (e.g. certain amount of memory).

databaseevmJsonRpcCacheconnectors[]
erpc.yaml
database:  evmJsonRpcCache:    connectors:      - id: redis-cache        driver: redis        redis:          # Connection URI (Required)          # Format: redis://[username]:[password]@[host][:port][/database][?dial_timeout=...&pool_size=...]          # Example: redis://:some-secret@redis.svc.cluster.local:6379/?pool_size=10          uri: 'redis://username:password@host:port/db?dial_timeout=5s&read_timeout=1s&write_timeout=2s&pool_size=10'          tls:            enabled: false # or true if redis is configured with TLS            certFile: /path/to/client.crt # Optional            keyFile: /path/to/client.key # Optional            caFile: /path/to/ca.crt # Optional    policies:      - network: '*'        method: '*'        finality: finalized        connector: redis-cache

TLS options

The tls block uses the shared TLSConfig struct. See TLS configuration for the full field reference.

When your Redis endpoint already uses rediss:// (for example, Railway or Upstash), TLS is negotiated automatically and you can omit the entire tls: block.
Add the tls: section only when you need mutual‑TLS (client certificate/key) or your server uses a private CA:

redis:
  uri: rediss://user:pass@redis.internal:6380/0
  tls:
    enabled: true
    certFile: /secrets/redis-client.crt   # sent to server (mTLS)
    keyFile:  /secrets/redis-client.key
    caFile:   /secrets/redis-rootCA.pem   # trust this CA instead of system roots

Redis URI Format

The Redis URI format follows this pattern:

redis://[[username]:[password]@][host][:port][/database][?dial_timeout=value1&read_timeout=value2&write_timeout=value3&pool_size=value4]

Examples:

  • redis://localhost:6379/0 - Basic connection to localhost
  • redis://user:pass@redis.example.com:6379/0 - Connection with authentication
  • redis://:password@redis.example.com:6379/0 - Connection with password only (no username)
  • redis://redis.example.com:6379 - Connection without database number (defaults to 0)
  • redis://redis.example.com:6379/0?dial_timeout=5s&read_timeout=1s&write_timeout=2s&pool_size=10 - Connection with timeouts and pool size
  • redis://global-shared-states-redis-master.redis.svc.cluster.local:6379 - Kubernetes service deployed via Bitnami charts (opens in a new tab)

You can include these parameters directly in the URI:

  • dial_timeout - Timeout for initial connection (e.g., 5s)
  • read_timeout - Timeout for read operations (e.g., 1s)
  • write_timeout - Timeout for write operations (e.g., 2s)
  • pool_size - Connection pool size (e.g., 10)

Configuration Notes

maxmemory 2000mb
maxmemory-policy allkeys-lru

PostgreSQL

Useful when you need to store cached data permanently without TTL i.e. forever.

You don't need to create the table, the driver will automatically create the table and requried indexes.

databaseevmJsonRpcCacheconnectors[]
erpc.yaml
database:  evmJsonRpcCache:    connectors:      - id: postgres-cache        driver: postgresql        postgresql:          connectionUri: postgres://YOUR_USERNAME_HERE:YOUR_PASSWORD_HERE@your.postgres.hostname.here.com:5432/your_database_name          table: rpc_cache          initTimeout: 5s          getTimeout: 1s          setTimeout: 2s    policies:      - network: '*'        method: '*'        finality: finalized        connector: postgres-cache

DynamoDB

When you need to have scalable (compared to Postgres) permanent caching and are happy with the costs.

databaseevmJsonRpcCacheconnectors[]
erpc.yaml
database:  evmJsonRpcCache:    connectors:      - id: dynamodb-cache        driver: dynamodb        dynamodb:          table: erpc_json_rpc_cache          region: eu-west-1          initTimeout: 5s          getTimeout: 1s          setTimeout: 2s          endpoint: https://dynamodb.eu-west-1.amazonaws.com # Optional          # Auth is optional if you are running within AWS.          auth:            mode: secret # file, or env            accessKeyId: YOUR_ACCESS_KEY_ID # Only if mode is secret            secretAccessKey: YOUR_SECRET_ACCESS_KEY # Only if mode is secret            profile: xxxxx # Only if mode is file            credentialsFile: xxxx # Only if mode is file    policies:      - network: '*'        method: '*'        finality: finalized        connector: dynamodb-cache

IAM Permissions

Make sure the IAM role/user has the necessary permissions to create and/or access the DynamoDB table:

  • Table Management:
    • dynamodb:CreateTable - For creating the table if it doesn't exist
    • dynamodb:DescribeTable - For checking table existence and configuration
    • dynamodb:UpdateTable - For adding the global secondary index
    • dynamodb:UpdateTimeToLive - For configuring TTL attributes
  • Data Operations:
    • dynamodb:PutItem - For storing data and creating locks
    • dynamodb:GetItem - For retrieving data (certain cache queries such as eth_getBlockByNumber with a hex block number)
    • dynamodb:Query - For querying with the reverse index (certain cache queries such as eth_getBlockReceipts by blockHash)
    • dynamodb:DeleteItem - For removing locks
    • dynamodb:UpdateItem - For counter operations with conditions

You can create the table and the reverse GSI index manually and avoid "Table management" permissions:

  • Table name: erpc_json_rpc_cache
  • Reverse GSI index name: idx_requestKey_groupKey with primary key requestKey and sort key groupKey and projection type ALL
Copy for your AI assistant — full driver referenceExpand for every option, default, and edge case — or copy this entire section into your AI assistant.

Common connector fields (all drivers)

FieldNotes
idUnique identifier; referenced from policies[].connector.
driverOne of memory, redis, postgresql, dynamodb.
failsafeForGets[]Optional. Failsafe policies (matchMethod, timeout, retry, ...) applied to read operations on this connector. Useful for short-timeout best-effort reads.
failsafeForSets[]Optional. Failsafe policies applied to write operations on this connector. Useful for stricter retry on writes.

memory driver

connectors:
  - id: hot
    driver: memory
    memory:
      maxItems: 100000
      maxTotalSize: 1GB
      emitMetrics: false   # default; turning on incurs ~10% performance hit
FieldDefaultNotes
maxItemsnoneMax entries in the LRU. Either this or maxTotalSize (or both) should be set.
maxTotalSizenoneMax total cache size (100MB, 1GB). Evicts LRU entries when exceeded.
emitMetricsfalseEmit per-key hit/miss metrics. ~10% perf hit; intended for debugging.

redis driver

connectors:
  - id: redis-cache
    driver: redis
    redis:
      # Connection — pick ONE of these two ways:
      uri: redis://user:pass@host:6379/0?dial_timeout=5s&pool_size=10
      # OR explicit fields:
      addr: host:6379
      username: user
      password: pass
      db: 0
      connPoolSize: 10
 
      # Operation timeouts
      initTimeout: 5s
      getTimeout: 1s
      setTimeout: 2s
 
      # Lock retry interval (for shared-state lock semantics, if used here)
      lockRetryInterval: 100ms
 
      # TLS — only needed for mTLS or private CA;
      # rediss:// URIs negotiate TLS automatically.
      tls:
        enabled: true
        certFile: /secrets/redis-client.crt
        keyFile: /secrets/redis-client.key
        caFile: /secrets/redis-rootCA.pem
        insecureSkipVerify: false
FieldNotes
uriFull Redis URI. When set, takes precedence over individual fields below. URI query-string params (dial_timeout, read_timeout, write_timeout, pool_size) override the equivalent fields.
addrHost:port — explicit alternative to uri.
username, password, dbAuth + database number; alternatives to embedding in uri.
connPoolSizeMaximum number of TCP connections to keep open. Default 10.
tlsTLS configuration. See TLS configuration for all fields.
initTimeoutHow long startup waits for the connection to become healthy.
getTimeoutTimeout for a single GET operation.
setTimeoutTimeout for a single SET operation.
lockRetryIntervalInterval between lock-acquisition retries. Applies when this Redis connector backs sharedState or when the cache uses optimistic locking on writes. Default 500ms.

Recommended Redis server config for cache use cases:

maxmemory 2000mb
maxmemory-policy allkeys-lru

postgresql driver

connectors:
  - id: postgres-cache
    driver: postgresql
    postgresql:
      connectionUri: postgres://user:pass@host:5432/erpc
      table: rpc_cache
      minConns: 2
      maxConns: 20
      initTimeout: 5s
      getTimeout: 1s
      setTimeout: 2s
FieldDefaultNotes
connectionUrirequiredStandard postgres:// URI. Driver creates the table + indexes on first connect; no manual schema work needed.
tableerpc_json_rpc_cacheTable name.
minConns0Minimum connections kept open in the pool. Useful to keep a warm pool ready.
maxConns100Maximum connections in the pool. Tune based on your Postgres max_connections.
initTimeout5sConnection-pool startup timeout.
getTimeout1sPer-GET timeout.
setTimeout2sPer-SET timeout.

PostgreSQL is the recommended permanent-cache backend when you want forever TTLs and operational simplicity.

dynamodb driver

connectors:
  - id: dynamodb-cache
    driver: dynamodb
    dynamodb:
      table: erpc_json_rpc_cache
      region: eu-west-1
      endpoint: https://dynamodb.eu-west-1.amazonaws.com   # optional
 
      # Schema attribute overrides (only set these if you provisioned the table manually)
      partitionKeyName: requestKey
      rangeKeyName: groupKey
      reverseIndexName: idx_requestKey_groupKey
      ttlAttributeName: ttl
 
      # AWS SDK behavior
      maxRetries: 3
 
      # Timing
      initTimeout: 5s
      getTimeout: 1s
      setTimeout: 2s
      statePollInterval: 250ms
      lockRetryInterval: 100ms
 
      # Auth (optional when running inside AWS with an instance role)
      auth:
        mode: secret           # secret | file | env
        accessKeyId: AKIA...
        secretAccessKey: ...
        # OR for mode: file
        profile: erpc-prod
        credentialsFile: /home/erpc/.aws/credentials
FieldDefaultNotes
tableerpc_json_rpc_cacheTable name. Driver auto-creates if it doesn't exist (requires dynamodb:CreateTable).
regionrequiredAWS region.
endpointnoneOverride the default DynamoDB endpoint. Set when using DynamoDB Local or a regional override.
auth.modeuses AWS SDK default chainsecret = use accessKeyId/secretAccessKey; file = read from credentialsFile/profile; env = AWS_* env vars. Omit auth entirely to use the instance-role / IAM-role chain.
partitionKeyNamerequestKeyDynamoDB partition key attribute. Only override if you provisioned the table manually with different schema.
rangeKeyNamegroupKeySort/range key attribute. Same caveat.
reverseIndexNameidx_requestKey_groupKeyName of the reverse GSI; used for eth_getBlockReceipts and similar block-hash → block-number lookups.
ttlAttributeNamettlTTL attribute name. eRPC writes Unix epoch (seconds) values into this attribute and DynamoDB sweeps expired rows.
maxRetries3Max retries for transient AWS errors (throttling, 5xx).
statePollInterval5sHow often the DynamoDB connector polls for counter-value updates when watching shared-state keys (e.g. latest/finalized block numbers).
lockRetryInterval100msBackoff between lock-acquisition attempts.
initTimeoutStartup timeout.
getTimeoutPer-GET timeout.
setTimeoutPer-SET timeout.

auth sub-config (DynamoDB and other AWS-backed clients)

FieldNotes
modesecret, file, or env. Determines how credentials are sourced.
accessKeyIDWhen mode: secret.
secretAccessKeyWhen mode: secret. Redacted in erpc_config output.
profileWhen mode: file. AWS shared-credentials profile name.
credentialsFileWhen mode: file. Path to the credentials file.

Omit the auth block entirely to use the AWS SDK's default credentials chain (instance role → IRSA → env vars → shared file). This is the recommended path for production deployments.

IAM permissions (DynamoDB)

OperationPermission
Table managementdynamodb:CreateTable, dynamodb:DescribeTable, dynamodb:UpdateTable, dynamodb:UpdateTimeToLive
Data opsdynamodb:PutItem, dynamodb:GetItem, dynamodb:Query, dynamodb:DeleteItem, dynamodb:UpdateItem

You can skip table-management permissions by provisioning the table manually:

  • Table name matches dynamodb.table (default erpc_json_rpc_cache)
  • Reverse GSI with name matching reverseIndexName (default idx_requestKey_groupKey), partition key requestKey, sort key groupKey, projection type ALL
  • TTL enabled on attribute matching ttlAttributeName (default ttl)

Per-connector failsafe (read vs write asymmetry)

connectors:
  - id: remote-redis
    driver: redis
    redis: { uri: redis://... }
    failsafeForGets:           # reads are best-effort: short timeout, no retry
      - matchMethod: "*"
        timeout: { duration: 50ms }
    failsafeForSets:           # writes can wait longer + retry
      - matchMethod: "*"
        timeout: { duration: 500ms }
        retry: { maxAttempts: 2, delay: 100ms }

Cache reads being slow shouldn't slow the request path (cache is best-effort fall-through); cache writes can afford longer timeouts because they're async to the response.

Common pitfalls

  • Setting both uri and explicit fieldsuri query-string params win; explicit fields without a counterpart in the URI still apply. Avoid the mix; prefer one source of truth.
  • auth.mode missing — DynamoDB tries the SDK default chain and may fail silently if no chain provides creds. Set explicit auth for non-AWS environments.
  • PostgreSQL maxConns higher than the server's max_connections — Postgres rejects new connections once its global limit is hit. Size maxConns relative to your total client fleet.
  • Memory driver without bounds — set maxItems or maxTotalSize (or both). Without either, the cache grows unbounded.
  • emitMetrics: true on a hot memory connector — adds per-key labels and can balloon /metrics cardinality + cost ~10% perf. Only for debugging.