Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Performance & Optimization11 min read

Alchemy vs QuickNode: A Reproducible RPC Evaluation Method

A measurement-first framework for comparing Alchemy and QuickNode on latency, reliability, method coverage, and cost for your own workload.

TL;DR

Alchemy and QuickNode are both managed RPC platforms with broad chain coverage, usage-based billing, and developer tooling layered on top of raw node access. The useful question is not which brand is better in general, but which one fits your method mix, regions, and reliability requirements. This article gives you a reproducible procedure: define a workload profile, run identical requests against both endpoints, record latency percentiles and error classes, and translate the results into a cost model. Vendor-published benchmarks are a starting point, but only your own measurements reflect your payloads, chains, and traffic shape.

Scope and the decision you are actually making

Choosing between Alchemy and QuickNode is a decision about operational fit, not a single score. Both providers expose JSON-RPC over HTTPS and WebSocket, both offer paid tiers with usage-based metering, and both bundle enhanced APIs such as token, NFT, and trace endpoints. The differences that matter in production are usually narrower: which chains and archive depths you need, how each provider meters expensive methods like eth_getLogs and debug_traceTransaction, how rate limits behave under burst, and how quickly support responds when a region degrades.

This article does not rank the two providers. It describes a measurement method you can run in an afternoon, then explains how to interpret the output. If you want a concrete endpoint recommendation for a specific chain rather than a methodology, the RPC Assistant answers are the right place to start; this page covers how to verify any recommendation against your own traffic.

  • Assumption: you already have trial or paid access to both providers and can issue requests from at least two regions.
  • Assumption: you know your top five RPC methods by volume and your peak requests per second.
  • Out of scope: proprietary benchmark datasets and any vendor's self-published latency claims.

Mental model: separate the transport layer from the product layer

Managed RPC providers sit between your application and a node fleet. The transport layer is the part you can measure directly: connection setup, time to first byte, full response time, HTTP status codes, and JSON-RPC error objects. The product layer is everything around it: dashboards, webhooks, enhanced endpoints, SDKs, and account abstraction tooling. Most comparison articles blend the two, which makes the result hard to act on.

Keep them separate. Benchmark the transport layer with raw JSON-RPC calls so you are comparing infrastructure, not SDK overhead. Evaluate the product layer separately by listing which enhanced endpoints your application actually calls and confirming each provider supports them on your target chains. A provider that wins on latency but lacks an archive method you depend on is not a viable option, and a provider with richer tooling but unstable p99 latency may still fail a trading workload.

Define a workload profile before touching an endpoint

A benchmark without a workload profile produces numbers that do not transfer. Write down the request mix first. For a typical DeFi dashboard, the mix might be 60% eth_call, 20% eth_getBalance, 10% eth_getLogs, 5% eth_getBlockByNumber, and 5% trace or archive reads. For an indexer, eth_getLogs and archive reads dominate. For a wallet, eth_getTransactionReceipt and eth_getTransactionCount matter more.

Record the chains, the regions your users connect from, and your peak and average requests per second. This profile becomes the input to both the benchmark script and the cost model later. Without it, you will end up comparing headline monthly quotas that have little relationship to your actual bill.

  • Top methods by call volume, with representative parameter payloads.
  • Chains and networks, including testnets if you deploy there.
  • Archive depth required, if any historical state reads are needed.
  • Geographic distribution of callers and any data-residency constraints.
  • Peak RPS, burst duration, and acceptable p95 and p99 latency.

Build a runnable latency harness with curl

This gives you a rough distribution and confirms authentication works. It is not sufficient for a real comparison because curl process startup dominates at low latencies. Move to a persistent-connection client for the actual measurement.

for i in $(seq 1 20); do
  curl -s -o /dev/null -w "%{http_code} %{time_total}\n" \
    -X POST "$RPC_URL" \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
done

Measure percentiles with a persistent-connection script

Run each payload at least a few hundred times, spread across different times of day. Record the region, timestamp, and provider alongside every result. If you need a broader picture of how endpoint selection interacts with chain choice, the guide to multi-chain RPC endpoints covers the network dimension.

import json, time, statistics, urllib.request

PROVIDERS = {
    "alchemy": "ALCHEMY_RPC_URL",
    "quicknode": "QUICKNODE_RPC_URL",
}
PAYLOADS = [
    {"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]},
    {"jsonrpc":"2.0","id":2,"method":"eth_getBalance","params":["0x0000000000000000000000000000000000000000","latest"]},
]

def run(url, payload, n=200):
    samples, errors = [], 0
    for _ in range(n):
        body = json.dumps(payload).encode()
        req = urllib.request.Request(url, data=body, headers={"Content-Type":"application/json"})
        start = time.perf_counter()
        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = json.loads(resp.read())
            elapsed = (time.perf_counter() - start) * 1000
            if "error" in data:
                errors += 1
            else:
                samples.append(elapsed)
        except Exception:
            errors += 1
    samples.sort()
    def pct(p):
        return samples[min(len(samples)-1, int(len(samples)*p))] if samples else None
    return {"n": len(samples), "errors": errors, "p50": pct(0.50), "p95": pct(0.95), "p99": pct(0.99)}

for name, url in PROVIDERS.items():
    for payload in PAYLOADS:
        print(name, payload["method"], run(url, payload))

Record results in a comparison table

The expected verification result is a stable ordering across repeated runs. If p95 flips between providers on consecutive runs, your sample size is too small or your region is noisy. Increase the sample count before drawing conclusions, and keep the raw data so you can revisit it after a provider changes infrastructure.

  • | Provider | Chain | Region | Method | Samples | Errors | p50 (ms) | p95 (ms) | p99 (ms) |
  • | Alchemy | Ethereum | eu-west | eth_blockNumber | (measured) | (measured) | (measured) | (measured) | (measured) |
  • | QuickNode | Ethereum | eu-west | eth_blockNumber | (measured) | (measured) | (measured) | (measured) | (measured) |

Test rate-limit and error behavior under burst

Run this against both providers at the same concurrency and compare the distribution of status codes. A provider that returns clean 429s with retry hints is easier to operate than one that silently drops connections.

import concurrent.futures, json, urllib.request

def call(url):
    body = json.dumps({"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}).encode()
    req = urllib.request.Request(url, data=body, headers={"Content-Type":"application/json"})
    try:
        with urllib.request.urlopen(req, timeout=5) as r:
            return r.status, r.headers.get("Retry-After")
    except urllib.error.HTTPError as e:
        return e.code, e.headers.get("Retry-After")

url = "RPC_URL"
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as pool:
    results = list(pool.map(lambda _: call(url), range(500)))
from collections import Counter
print(Counter(results))

Verify method and archive coverage on your target chains

Latency is irrelevant if a method is unsupported. Build a coverage matrix from your workload profile: for each method, confirm support on each chain and each provider. Pay particular attention to archive reads, trace and debug namespaces, eth_getLogs block-range limits, and WebSocket subscription behavior. Test each one directly rather than relying on documentation alone, because support can vary by network even within the same provider.

For dedicated or single-tenant capacity, check whether the provider offers isolated nodes and in which regions; the dedicated node model changes both latency and cost. If your workload spans many chains, the networks directory helps you confirm which networks are available before you commit to a provider.

Translate measurements into a cost model

Both providers meter usage, but the units and multipliers differ. Build a cost model from your workload profile: multiply the monthly call volume for each method by that provider's weight for the method, sum the weighted units, and compare against plan quotas and overage rates. Include WebSocket message volume and any enhanced API calls separately, since these are often billed on different scales.

Do not compare headline monthly request counts across providers. A plan that includes a large number of cheap reads can still be more expensive than a smaller plan if your traffic is dominated by weighted methods. The RPC pricing page shows how OnFinality structures plans, which is useful as a third reference point when building the model.

  • Weighted units per month = sum over methods of (calls × method weight).
  • Effective cost = plan price + max(0, weighted units − included units) × overage rate.
  • Add support tier and SLA commitments as separate line items, not blended into per-request cost.

Troubleshooting common benchmark artifacts

Most misleading comparisons come from a handful of avoidable mistakes. If your results look implausible, check these first.

  • Cold connections: the first request to a new endpoint pays TLS and connection setup. Discard warm-up requests.
  • DNS and proxy effects: corporate proxies and VPNs add latency that has nothing to do with the provider. Test from a clean host.
  • Payload differences: a latest block tag hits cache more often than a specific historical block. Keep payloads identical across providers.
  • Small samples: fewer than a few hundred samples per method and region will not produce stable p99 values.
  • Clock skew: use a monotonic timer for elapsed time, not wall-clock timestamps.
  • Silent errors: a fast response containing a JSON-RPC error is not a successful sample. Classify errors separately.

Limitations and when to stop measuring

A benchmark is a snapshot. Provider infrastructure, routing, and pricing change, and a result from one week may not hold the next. Treat the harness as a recurring check rather than a one-time decision, and re-run it after any plan change or incident. Also accept that no local benchmark fully reproduces production traffic: your real application has caching, batching, and retry logic that the harness does not.

If the two providers are within noise of each other on latency and reliability, the decision should shift to product fit, support responsiveness, and contractual terms. At that point, further micro-benchmarking has diminishing returns. For teams that want a managed alternative with predictable metering, the API service overview describes how OnFinality approaches endpoint provisioning.

Next steps: operationalize the comparison

Turn the harness into a scheduled job that runs weekly from your primary regions and stores results in a time-series table. Alert when p95 or error rate crosses a threshold you set from your own baseline. Keep the workload profile current as your application evolves, and revisit the cost model whenever either provider changes its pricing page.

If you are still narrowing down a specific chain or endpoint rather than a full provider comparison, start with the RPC Assistant for a direct recommendation, then validate it with the harness above. For teams building a broader infrastructure plan, the blockchain node hosting guide covers the operational side of running and monitoring nodes.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started