Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions benchmarks/indexing-freshness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

slug: indexing-freshness
number: "070"
title: Freshest wallet data API. Zerion, Moralis, Allium, GoldRush, Mobula
title: Freshest wallet data API. Zerion, Allium, Mobula
seo_title: "Freshest wallet data API 2026"
seo_description: "How fast do wallet APIs index a new transaction? Zerion, Moralis, Allium, GoldRush, Mobula measured live on organic Base transfers, second by second."
seo_description: "How fast do wallet APIs index a new transaction? Zerion, Allium and Mobula measured live on organic Base transfers, second by second."
subtitle: Seconds between an organic transfer confirming on Base and the moment each wallet data API first returns it, measured continuously on real user transactions.
category: Aggregators
status: live
Expand All @@ -23,7 +23,7 @@ seo_intro: |
transactions API until the tx hash appears. Because the ground
truth is a random real transaction there is no benchmark wallet a
provider could special-case, and every measurement is publicly
re-verifiable from the tx hash. Cohort. Zerion, Moralis, Allium,
re-verifiable from the tx hash. Cohort. Zerion, Allium,
GoldRush (Covalent) and Mobula, all probed with the identical
schedule from the same host. The timing context matters in 2026.
Dune Sim is sunsetting and SimpleHash is gone, so teams are
Expand Down Expand Up @@ -59,7 +59,6 @@ methodology:
findings:
- "{{best_name}} currently leads at {{best_p50}} (p50 of found lags, 24h) across organic Base transfers."
- "{{name:zerion}} sits at {{p50:zerion}}. Early runs showed a bimodal pattern, some events indexed in about a second and others surfacing several seconds later, consistent with a caching layer in front of the wallet endpoint."
- "{{name:moralis}} runs at {{p50:moralis}} with a notably tight distribution across events."
- "{{name:goldrush}} trails at {{p50:goldrush}} on this probe. Its unified multi-chain schema trades freshness for breadth, a real trade-off teams should weigh explicitly."
- "Miss rates matter more than medians: an API that fails to show a deposit within two minutes breaks the user flow entirely, so read the reliability column before the latency one."

Expand Down Expand Up @@ -104,17 +103,6 @@ providers:
success: sum(increase(indexing_probe_total{provider="zerion", result="found"}[24h])) / sum(increase(indexing_probe_total{provider="zerion", result=~"found|missed"}[24h]))
sample_size: sum(increase(indexing_probe_total{provider="zerion", result=~"found|missed"}[24h]))
series: avg_over_time(indexing_freshness_seconds{provider="zerion"}[1h])
- slug: moralis
name: Moralis
tag: Web3 data API, wallet history across major EVM chains
formula: "Median (p50) over 24h of visibility lag in seconds between an organic Base transfer confirming and Moralis's wallet history endpoint first returning it, from the shared histogram estimator."
queries:
p50: histogram_quantile(0.5, sum by (le) (increase(indexing_freshness_seconds_histogram_bucket{provider="moralis"}[24h])))
p90: histogram_quantile(0.9, sum by (le) (increase(indexing_freshness_seconds_histogram_bucket{provider="moralis"}[24h])))
p99: histogram_quantile(0.99, sum by (le) (increase(indexing_freshness_seconds_histogram_bucket{provider="moralis"}[24h])))
success: sum(increase(indexing_probe_total{provider="moralis", result="found"}[24h])) / sum(increase(indexing_probe_total{provider="moralis", result=~"found|missed"}[24h]))
sample_size: sum(increase(indexing_probe_total{provider="moralis", result=~"found|missed"}[24h]))
series: avg_over_time(indexing_freshness_seconds{provider="moralis"}[1h])
- slug: goldrush
name: GoldRush
tag: Covalent's multi-chain wallet API, unified schema
Expand Down
6 changes: 0 additions & 6 deletions harnesses/indexing-freshness/cmd/script/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ type Provider struct {
var providers = []Provider{
{Slug: "mobula", EveryN: 1, Budget: 250_000},
{Slug: "zerion", EveryN: 1, Budget: 55_000},
// Moralis free tier: 40k CU/day; /wallets/{addr}/history costs 25 CU
// per call, so full participation (144 events × 16 polls = 2,304
// calls = 57.6k CU/day) blows the daily cap ~2/3 through the day
// (the API then 401s until the UTC midnight reset). EveryN 2 keeps
// it at ~28.8k CU/day. Budget = 40k/25 CU × 30 days in calls.
{Slug: "moralis", EveryN: 2, Budget: 48_000},
{Slug: "goldrush", EveryN: 1, Budget: 90_000},
// Allium free tier: 20k calls/month, aggressive per-second limits.
{Slug: "allium", EveryN: 3, Budget: 18_000},
Expand Down
6 changes: 0 additions & 6 deletions harnesses/indexing-freshness/cmd/script/pollers.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ func checkProvider(slug, wallet, txHash string) (bool, error) {
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(key+":")))
req.Header.Set("Accept", "application/json")
}
case "moralis":
u := fmt.Sprintf("https://deep-index.moralis.io/api/v2.2/wallets/%s/history?chain=%s&limit=20", wallet, chainSlug)
req, err = http.NewRequest("GET", u, nil)
if err == nil {
req.Header.Set("X-API-Key", key)
}
case "goldrush":
u := fmt.Sprintf("https://api.covalenthq.com/v1/%s-mainnet/address/%s/transactions_v3/?page-size=20", chainSlug, wallet)
req, err = http.NewRequest("GET", u, nil)
Expand Down
Loading
Loading