Chainstack RPC Monitoring Dashboard
A serverless RPC node monitoring system that measures response times across multiple blockchains and regions. Runs on Vercel Functions and pushes metrics to Grafana Cloud.
→ Multi-Region Deployment Guide
📊 Live Dashboard | 📚 Documentation
Open Source Dashboards
The Grafana dashboards used by this project are open source and available in the dashboards/ folder. This includes all dashboard JSON definitions and a sync tool (grafana_sync.py) that lets you pull updates from Grafana Cloud and push them back — keeping the repo and your live dashboards in sync.
Table of Contents
- Overview
- Supported Blockchains
- Architecture
- Setup
- Configuration
- Development
- Multi-Region Deployment Guide
Overview
This system collects latency metrics from RPC endpoints using scheduled cron jobs. Functions run in multiple regions (Frankfurt, San Francisco, Singapore, Tokyo) to measure response times from different geographic locations.
Metric types collected:
- HTTP RPC method latency (eth_blockNumber, eth_call, eth_getLogs, etc.)
- WebSocket block notification latency (EVM only)
- Transaction landing time (Solana only)
Metrics are pushed to Grafana Cloud in Influx line protocol format for visualization and alerting.
Supported Blockchains
Ethereum, Base, Arbitrum, BNB Smart Chain, Solana, TON, Hyperliquid, Monad
Each blockchain has region-specific deployment configurations detailed in the Multi-Region Deployment Guide.
Architecture
flowchart TB
subgraph Vercel["Vercel Platform"]
subgraph Functions["Serverless Functions"]
subgraph Global["Regional Functions"]
Collectors["Metric Collectors
[3 min intervals]"]
end
subgraph Services["fra1 Only"]
STATE["State Update
[15 min intervals]"]
TX["Transaction Landing
[15 min intervals]"]
end
end
BLOB[("Blob Storage")]
end
subgraph RPC["RPC Nodes"]
API["JSON-RPC API"]
end
subgraph Grafana["Grafana Cloud"]
METRICS["Prometheus"]
end
BLOB --> Collectors
Collectors <--> API
Collectors --> METRICS
API <--> STATE
STATE --> BLOB
TX <--> API
TX --> METRICS
classDef default fill:#f9f9f9,stroke:#333,stroke-width:2px,color:#000
classDef vercel fill:#f0f0f0,stroke:#333,color:#000
classDef grafana fill:#d4eaf7,stroke:#333,color:#000
classDef rpc fill:#eafaf1,stroke:#333,color:#000
class BLOB,Collectors,STATE,TX vercel
class METRICS grafana
class API rpc
Workflow:
- State updater fetches latest block and transaction data from RPC endpoints every 15 minutes (fra1 only)
- State data is stored in Vercel Blob Storage (recent block numbers and transaction hashes)
- Metric collectors in each region fetch state data and execute RPC calls every 3 minutes
- Response times are measured and formatted as Influx metrics
- Metrics are pushed to Grafana Cloud for storage and visualization
Setup
Prerequisites
- Grafana Cloud account with Prometheus endpoint
- Vercel account (Pro plan recommended for multi-region deployment)
- RPC node endpoints to monitor
Deployment
For multi-region setup across multiple projects, see the Multi-Region Deployment Guide below.
Blob Storage Setup
Create a Vercel Blob store and configure the storage variables:
VERCEL_BLOB_TOKEN=vercel_blob_... STORE_ID=store_...
These are required for the state management system.
Configuration
Environment Variables
Required:
# Grafana Cloud credentials GRAFANA_URL=https://influx-...grafana.net/api/v1/push/influx/write GRAFANA_USER=user_id GRAFANA_API_KEY=glc_... # Authentication CRON_SECRET=random_secret_string SKIP_AUTH=FALSE # Blob Storage VERCEL_BLOB_TOKEN=vercel_blob_... STORE_ID=store_...
Optional:
# Adds 'dev_' prefix to metric names in non-production environments VERCEL_ENV=production # Required only for Solana transaction landing metrics SOLANA_PRIVATE_KEY=base58_encoded_private_key
RPC Endpoints Configuration
Configure monitored endpoints in the ENDPOINTS environment variable (JSON format):
{
"providers": [
{
"blockchain": "Ethereum",
"name": "Chainstack",
"websocket_endpoint": "wss://ethereum-mainnet.example.com",
"http_endpoint": "https://ethereum-mainnet.example.com"
},
{
"blockchain": "Solana",
"name": "Chainstack",
"http_endpoint": "https://solana-mainnet.example.com",
"tx_endpoint": "https://solana-mainnet-tx.example.com"
}
]
}Fields:
blockchain- Blockchain name (case-insensitive, must match supported list)name- Provider identifier (used in metric labels)http_endpoint- HTTP RPC endpoint URLwebsocket_endpoint- WebSocket endpoint URL (optional, use "not_supported" if unavailable)tx_endpoint- Separate transaction endpoint (Solana only, optional)
For local development, create endpoints.json in the project root. For Vercel deployment, set as environment variable.
Development
Local Setup
git clone https://github.com/chainstacklabs/chainstack-rpc-dashboard-functions.git cd chainstack-rpc-dashboard-functions python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt
Local Configuration
cp .env.local.example .env.local cp endpoints.json.example endpoints.json
Edit .env.local and endpoints.json with your credentials and endpoints.
Running Tests
# Test metric collection for a specific blockchain python tests/test_api_read.py # Test state update function python tests/test_update_state.py # Test Solana transaction landing metrics python tests/test_api_write.py
By default, test scripts import specific blockchain handlers. Modify the import statement in the test file to test different blockchains:
# In tests/test_api_read.py, change: from api.read.ethereum import handler # to: from api.read.monad import handler
Project Structure
├── api/
│ ├── read/ # Metric collection handlers (one per blockchain)
│ ├── write/ # Transaction landing metrics
│ └── support/ # State update handler
├── common/
│ ├── base_metric.py # Base metric classes
│ ├── factory.py # Metric factory
│ ├── metrics_handler.py # Request handler
│ └── state/ # Blob storage interface
├── metrics/ # Blockchain-specific metric implementations
├── config/
│ └── defaults.py # Block offset ranges, timeouts, etc.
├── tests/ # Local development servers
└── vercel.json # Function and cron configuration
Adding a New Blockchain
- Create
metrics/{blockchain}.pywith metric implementations:
from common.metric_types import HttpCallLatencyMetricBase class HTTPBlockNumberLatencyMetric(HttpCallLatencyMetricBase): @property def method(self) -> str: return "eth_blockNumber" @staticmethod def get_params_from_state(state_data: dict) -> list: return []
- Create
api/read/{blockchain}.pyhandler:
from common.metrics_handler import BaseVercelHandler, MetricsHandler from config.defaults import MetricsServiceConfig from metrics.{blockchain} import HTTPBlockNumberLatencyMetric METRIC_NAME = f"{MetricsServiceConfig.METRIC_PREFIX}response_latency_seconds" METRICS = [ (HTTPBlockNumberLatencyMetric, METRIC_NAME), ] class handler(BaseVercelHandler): metrics_handler = MetricsHandler("YourBlockchain", METRICS)
- Add to
config/defaults.py:
BLOCK_OFFSET_RANGES = { # ... "yourblockchain": (7200, 10000), # blocks back from latest }
- Add to
api/support/update_state.py:
SUPPORTED_BLOCKCHAINS = [ "ethereum", "solana", "ton", "base", "arbitrum", "bnb", "hyperliquid", "monad", "yourblockchain", # Add here ]
- Add to
common/state/blockchain_fetcher.py(EVM chains only):
if blockchain.lower() in ( "ethereum", "base", "arbitrum", "bnb", "hyperliquid", "monad", "yourblockchain", # Add here ): return await self._fetch_evm_data(blockchain)
- Update
vercel.{region}.jsonfiles to include the new blockchain's cron job in appropriate regions.
Multi-Region Deployment Guide
Problem
Vercel executes all crons defined in vercel.json across all projects/regions, even if the function filters by ALLOWED_REGIONS. This wastes cron job slots (40 total limit under the Pro plan).
Solution
Use region-specific vercel.json files that only define crons for functions that should run in each region.
Deployment Commands
Note: Due to a Vercel CLI bug, the --local-config flag doesn't always work correctly. You must copy the region-specific config to vercel.json before deploying.
Deploy each project with its region-specific configuration:
# Germany (Frankfurt - fra1) vercel link --project chainstack-rpc-dashboard-germany cp vercel.fra1.json vercel.json vercel --prod # US West (San Francisco - sfo1) vercel link --project chainstack-rpc-dashboard-us-west cp vercel.sfo1.json vercel.json vercel --prod # Singapore (sin1) vercel link --project chainstack-rpc-dashboard-singapore cp vercel.sin1.json vercel.json vercel --prod # Japan (Tokyo - hnd1) vercel link --project chainstack-rpc-dashboard-japan cp vercel.hnd1.json vercel.json vercel --prod
Important:
- Always
cpthe region-specific config tovercel.jsonbefore deploying - Ensure you're in the correct Vercel project context before deploying (use
vercel link) - After deployment, you can restore the original
vercel.jsonfrom git if needed:git checkout vercel.json
Verification
After deployment, verify cron jobs in each Vercel project:
- Navigate to each project in Vercel Dashboard
- Go to Settings → Crons
- Confirm only expected crons are listed
Updating Region Configuration
To add or remove a blockchain from a region:
- Update the corresponding
vercel.{region}.jsoncron list to add or remove the blockchain's cron entry - Redeploy that specific region with the updated config
Notes
- The original
vercel.jsonserves as a reference template - State Update and Solana Write only run in fra1 to avoid data conflicts
- Each region's config file (
vercel.fra1.json, etc.) defines only the functions needed in that region