Methodology/Research methods

38 days of exchangerate.dev performance: freshness and availability

A measured performance report covering data age, observed change intervals, attempted-request availability, metadata coverage, and collector coverage.

ERexchangerate.dev research·Updated Aug 27, 2026·9 min read

From July 19 through August 26, 2026, a Jakarta-based collector scheduled EUR/USD once per minute against exchangerate.dev. Across 31,614 successful observations, median data age was 30.5 seconds, p95 data age was 57.7 seconds, attempted-request availability was 97.92%, and timestamp, source, and market-session coverage were each 100%.

Key points
The run covered 38.9 days, 55,990 scheduled observations per provider, and 32,285 actual attempts per provider.
exchangerate.dev returned a qualifying data timestamp on every success: median data age was 30.5 seconds and p95 was 57.7 seconds.
Returned values changed at a median observed interval of 61.4 seconds and p95 of 123.1 seconds.
HTTP response latency was 505 ms at the median and 2,457 ms at p95; response speed and underlying data age remain separate measurements.
Separate collector coverage from provider availability so runner downtime is not charged to an API.
Treat observed numeric changes as an observable interval, not proof of either provider’s upstream ingest schedule.

Measured exchangerate.dev performance

The collector ran from 2026-07-19T02:07Z through 2026-08-26T23:16Z from Jakarta, Indonesia. It used the public, unauthenticated EUR/USD single-pair endpoint with no optional parameters. This is a measured record for one pair, plan, region, and observation window rather than an SLA or a claim about every endpoint.

MetricMeasured resultCalculation
Scheduled / attempted55,990 / 32,285Retains every due minute and every actual request
Collector coverage57.66%Attempted requests ÷ scheduled observations
Successful responses31,614Parseable 2xx responses containing a numeric rate
Attempted-request availability97.92%Successful observations ÷ actual attempts
Response latency, p50 / p95505 ms / 2,457 msRequest start → complete response
Data age, p50 / p9530.5 s / 57.7 sResponse received − provider data timestamp
Observed change interval, p50 / p9561.4 s / 123.1 sTime between numeric changes without crossing collector downtime
Timestamp / source / session coverage100% / 100% / 100%Responses exposing each field ÷ successful responses
Closed-market labelingExplicit weekend label observedFriday 17:00 through Sunday 17:00 New York
Performance report, not an SLA
These numbers describe the measured endpoint, region, plan, pair, and dates. They do not guarantee future uptime or latency. Data age and HTTP response latency are reported separately because a fast response can still contain an older market observation.
Collector coverage was 57.66%
The operator Mac was not running for every scheduled minute. Those 23,705 missed provider-minutes remain in the audit trail, but they are charged to collector coverage rather than provider availability. Observed change intervals never bridge those scheduler gaps. Attempted requests that fail can still lengthen an observed interval, so the metric remains an observable upper bound rather than an ingest schedule.

What this benchmark measures

The benchmark separates API response speed from data freshness. Response latency is the time between starting a request and receiving the complete response. Data age is the time between receiving that response and the provider-reported timestamp for the underlying rate. A fast CDN can return an old rate quickly, so the two measurements must never be merged.

MetricCalculationWhat it does not prove
Data ageresponse received − provider data timestampThe source was executable or settlement-grade
Observed change intervaltime between returned numeric changes without crossing collector downtimeThe exact upstream ingest cadence
Provider availabilitysuccessful observations ÷ attempted requestsGlobal availability outside the measured region
Collector coverageattempted requests ÷ scheduled observationsProvider availability
Response latencyrequest start → complete responseData freshness
Metadata coverageresponses with timestamp/source labels ÷ successesThat the label itself is independently audited

The fixed protocol

  • Measure EUR/USD in one direction at the precision each provider returns; do not round before change detection.
  • Schedule one request every 60 seconds for at least seven calendar days, including five open-market days.
  • Record the provider plan, authentication state, measurement region, parser version, and exact start and end times.
  • Use a UTC clock and disclose whether its error was independently calibrated. For this version 1.1 run, it was not; data age uses the recorded response receive time without a measured clock-offset bound.
  • Retain every scheduled observation, including HTTP errors, parse errors, missing timestamps, and timeouts.
  • Do not publish a provider result until it contains at least 500 successful observations.
  • Stay within each provider’s documented rate limits and terms; a provider is not eligible when measurement is not permitted.
Why seven days?
A seven-day window covers a complete trading week and the weekend boundary. Five open-market days prevents a run dominated by carried weekend values, while the weekend observations test whether the API labels a closed market honestly.

The observation record

Store the raw rate and provider timestamp before computing summaries. The normalized record below is sufficient to reproduce each metric while preserving errors instead of silently dropping them.

json · one normalized observationcopy
{
  "provider": "example",
  "plan": "free",
  "pair": "EUR/USD",
  "request_started_at": "2026-07-16T09:00:00.000Z",
  "response_received_at": "2026-07-16T09:00:00.184Z",
  "http_status": 200,
  "rate": "1.16427",
  "provider_data_updated_at": "2026-07-16T08:59:31Z",
  "provider_source_label": "live",
  "provider_market_session_label": "open",
  "response_latency_ms": 184,
  "error_class": null
}

The timestamp rule

A provider is scorable for data age only when it exposes a parseable timestamp that describes the underlying rate. An HTTP Date header or the collector’s receive time does not qualify. If timestamp semantics are ambiguous, report timestamp coverage and mark data age unscored rather than inventing precision.

Version 1.1 calculates data age by directly subtracting every successful, parseable provider timestamp from the response receive time. The collector did not record provider timestamp precision, apply a future-timestamp tolerance, or separately count future timestamps, so those safeguards cannot be claimed for this result. Its clock-calibration limitation is disclosed in the machine-readable report; a future run requiring those controls needs a new collector version.

The weekend rule

Interbank FX closes from Friday 17:00 New York through Sunday 17:00 New York. A provider may legitimately carry its final trading-week value, but the benchmark records whether it labels that condition. The New York boundary is converted for daylight saving time so Sunday reopening is not misclassified as weekend trading. A changing crypto-derived proxy, a carried FX observation, and a daily reference fix are different products; the report must preserve the provider’s source and market-state metadata instead of calling all three “live.”

The publication gate

Every published result must include the scheduled sample count, attempted count, success count, collector coverage, provider availability, p50 and p95 data age, p50 and p95 observed change interval, timestamp coverage, source-label coverage, observation window, measurement region, plan, parser version, and exclusions. Raw normalized observations should accompany the summary wherever provider terms allow redistribution.

Evidence gate passed
Version 1.1 passed the minimum evidence gate with 38.9 elapsed days, 34 open-market dates, and 31,614 successful observations. Passing the gate establishes enough evidence to report this measured window; it does not turn one pair, region, plan, or endpoint into an SLA.

Machine-readable protocol

Download the versioned benchmark protocol. It defines eligibility, recorded fields, formulas, required disclosures, prohibited claims, and the current result status. The broader FX data methodology defines exchangerate.dev’s own source and timestamp semantics.

ER
exchangerate.dev research
Reproducible methods for evaluating indicative FX data APIs.

Keep reading

MethodologyHow exchangerate.dev builds and labels FX ratesRead ReferenceReading source and market_sessionRead GuideWhy exchange rates differ across providersRead
More ComparisonsFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.devCurrencylayer vs ExchangeRate-API
LearnReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Live RatesEUR/USDGBP/USDUSD/JPY