Skip to content
0%

How to migrate between RPC providers with zero downtime

Author: Uttam Singh

Last updated: July 14, 20266 min read
Migrate between RPC providers with zero downtime

Teams put off switching RPC providers because it feels like a rebuild. Most of the time it is a few hours of configuration. Every major provider has the same JSON-RPC standard, so the request your app sends today is the same request the new provider expects tomorrow. Migrating RPC providers is an endpoint swap, not a rewrite.

The work that remains sits around the swap rather than inside it: finding every place an endpoint URL hides, mapping the handful of provider-specific calls that won't travel, and cutting traffic over in an order your users never notice.

What does drop-in endpoint compatibility mean?

Drop-in endpoint compatibility means two RPC providers accept the same requests and return the same responses for standard JSON-RPC methods. An application switches providers by changing the endpoint URL it calls. Method names, parameters, and response shapes stay identical, so the standard surface needs no code changes at all.

The compatibility comes from the protocol, not from any agreement between providers. eth_call, eth_getLogs, eth_sendRawTransaction, and the rest of the eth_*, net_*, and web3_* families are defined by the Ethereum JSON-RPC specification, and every serious provider implements them to spec. The same holds for streaming. eth_subscribe over WebSocket carries the same newHeads, logs, and newPendingTransactions streams on our subscription endpoints as it does on any other major provider's.

Here is our endpoint shape next to the pattern most other providers use:

text
Copied
Alchemy: https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY Other providers: https://your-endpoint-name.provider.example/YOUR_AUTH_TOKEN/

Both are a URL with a secret in the path. If your endpoint lives in an environment variable, migrating your standard traffic means changing that variable's value. This is also why the standard reliability advice to keep a backup RPC endpoint configured doubles as migration insurance. The fallback machinery you would add for uptime is the same machinery you use to switch.

Standard JSON-RPC calls run on the new provider unchanged. The work hides wherever your app depends on something provider-specific, and finding those places is what the audit is for.

What should you audit before migrating?

Most surprises in a provider migration get discovered after the switch, and every one of them could have been found before it. For a typical codebase the audit takes an hour or two.

Find every endpoint reference. Endpoint URLs accumulate in more places than anyone remembers. Search environment files, Hardhat and Foundry configs, Docker images, CI pipelines, and frontend builds for the current provider's domain and for any hardcoded URLs. The reference you miss is usually in a cron job or a CI pipeline nobody has opened in months.

Map provider-prefixed methods. Most providers ship convenience methods under a vendor prefix (ours is alchemy_), and those don't travel between platforms. Token lookups map to Data API equivalents such as alchemy_getTokenBalances, and transfer history moves to alchemy_getAssetTransfers. The equivalents exist, but the response shapes differ, so treat each one as a small code change rather than a find-and-replace.

Check how you authenticate. A key in the URL path ports cleanly. If you authenticate with an x-token header or JWTs instead, those controls need recreating on the new provider. On our side, domain and IP allowlists live in the Alchemy dashboard and take a few minutes to set up.

Reprice your traffic under the new metering model. This is the audit item that touches your bill instead of your code. Many providers meter a flat requests-per-second budget. We meter compute units, where a light call like eth_blockNumber costs less than a heavy call like eth_getLogs, and throughput is a compute-unit rate over a rolling window rather than a flat request count. The effect cuts both ways. Log-heavy indexing workloads consume budget faster than their request count suggests, while light polling workloads consume less. Most teams price their busiest hour of real traffic against our pricing before switching instead of guessing from monthly totals.

Check plan gating on trace and debug methods. debug_ and trace_ methods are gated by plan on most providers. On Alchemy they are available on pay-as-you-go and enterprise plans but not the free tier, so if you run your proof of concept on a free endpoint, expect trace calls to fail there even though everything else works.

None of these items blocks a migration, but together they set its scope. For most apps the audit ends with a short list of environment variables, one or two method mappings, and a pricing estimate.

How do you cut over without downtime?

The zero-downtime pattern is the same one teams use for database migrations. Run old and new in parallel, move traffic in stages, and keep the old path warm until the new one has earned trust.

Client libraries make the parallel phase nearly free. viem's fallback transport takes an ordered list of endpoints and moves down the list when one fails:

typescript
Copied
import { createPublicClient, fallback, http } from "viem"; import { mainnet } from "viem/chains"; const client = createPublicClient({ chain: mainnet, transport: fallback([ http("https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY"), http("https://your-endpoint-name.provider.example/YOUR_AUTH_TOKEN/"), ]), });

With the new provider first and the old one second, every request tries the new endpoint and falls back to the one that was already working. Your worst case during the cutover is the setup you have today. ethers.js offers the same pattern in FallbackProvider, with a quorum option that queries several providers and accepts a result once they agree, which gives you cross-provider agreement checks inside the client itself.

The order you move traffic in matters more than how fast you move it, and the principle is reads first, writes last. Reads are stateless and easy to verify, so point read traffic at the new endpoint early and diff what comes back. Run your heaviest queries on both providers, eth_getLogs over your contracts' busiest block ranges and eth_call against your core contracts, and compare the responses. Transaction submission moves last, after reads have run clean, because a failed read is a retry and a failed write is a support ticket.

WebSocket subscriptions need one extra step. A subscription is bound to the connection that created it, so it doesn't fail over. It drops, and you recreate it. Plan to re-subscribe on the new endpoint and backfill the gap with an eth_getLogs query over the blocks that passed during the reconnect, so no events go missing. Our WebSocket best practices also recommend keeping subscription scope narrow, which makes both the re-subscribe and the backfill cheaper.

Two things deserve a dashboard during the parallel run. The first is block-height lag. Two healthy providers can sit at slightly different chain tips at any given moment, so alert on the new endpoint falling consistently behind the old one, not on momentary differences. The second is error shape. Rate-limit responses differ across providers. Over HTTP, ours return a 429 with a Retry-After header; over WebSocket, the same limit surfaces as a JSON-RPC 429 error with no header. Exercise your retry logic against the new endpoint, on both transports you use, before it carries production traffic.

Most teams give the parallel phase a day or two of production traffic, then make the new endpoint the default. Keep the old endpoint configured as the fallback until its billing period runs out. Rollback stays one configuration change away the whole time, and that is what zero downtime means in practice. Things can still go wrong. They just never have to reach your users.

How do you know the new provider is holding up?

The comparison you ran during the parallel phase becomes your baseline. After the switch, keep watching the numbers you diffed before it: success rate, p95 latency, and block freshness. If the migration was worth doing, at least one of them should move in your favor.

You don't have to take latency claims on faith, either. Our live RPC benchmarks compare us with other major providers across chains and regions, and the methodology behind them is public, so you can reproduce the numbers from your own region before you commit. For the deeper story on why those numbers hold under load, our edge proxy rebuild walks through the routing layer every request hits first.

And if you're still weighing providers rather than verifying one, our guide to choosing a node provider and the enterprise RPC evaluation guide cover the questions worth asking before the migration question comes up.

Keep the parallel-run checks alive after the migration wraps. The response diffs and latency dashboards that validated the cutover will flag provider regressions and stale data months later, and they're already built.

Ready to switch RPC providers?

Whichever provider you're leaving, everything above applies as written.

Create a free endpoint in the Alchemy dashboard and point your staging environment at it today. No contracts, no sales call, no minimum commitment. The free tier includes 30M compute units a month, enough to run the full parallel-phase comparison on real production traffic, and the same endpoint swap works across the 100+ chains we support.

Alchemy Newsletter

Be the first to know about releases

Sign up for our newsletter

Get the latest product updates and resources from Alchemy

A
O
D
+
Over 80,000 subscribers

By entering your email address, you agree to receive our marketing communications and product updates. You acknowledge that Alchemy processes the information we receive in accordance with our Privacy Notice. You can unsubscribe anytime.