Developers / Benchmarks

Performance benchmarks

In a synthetic loopback test on a 4-vCPU container, Riptide's serving pipeline measured p50 1.1ms and p99 80ms at 1,000 QPS with a 0.0% error rate. The highest passing 5-second ramp step reached 4,000 QPS under the 100ms p99 limit. Estimated CPU cost was $0.0028 per million requests; this excludes other infrastructure costs.

1.1ms p50 latency at 1,000 QPS
80ms p99 latency at 1,000 QPS, 0.0% errors
4,000 QPS highest passing 5-second ramp step on 4 vCPUs
$0.0028 compute per million requests at 0.51 CPU-ms/request

Report d47a4a5, generated 2026-07-24. Scenario vast_ortb_mix (50.0% VAST, the rest OpenRTB), mode self_contained, go1.25.0 on linux/amd64, 4 vCPUs. Fill rate on this mixed direct-plus-demand scenario: 55.3%.

Methodology

This test measures serving latency, throughput, and CPU use under a fixed workload.

The load driver is open-loop: it fires requests at a constant arrival rate on a fixed schedule, whether or not earlier requests have returned. Latency is measured from each request's scheduled arrival time, so queueing delay under load counts against the system. This includes delays that would be missed if the driver waited for a response before sending the next request.

Every request exercises the real serving pipeline over HTTP: placement resolve, audience gate, demand fanout to demand partners with a circuit breaker, pricing, the auction, and VAST or OpenRTB response render. The scenario mixes direct campaigns with demand-partner responses, with a measured fill rate of 55.3%.

Test conditions and limits

Read these conditions before using the results to estimate production capacity:

  • Self-contained run: the real serving pipeline (resolve, audience gate, demand fanout with circuit breaker, pricing, auction, VAST/ORTB render) driven over loopback HTTP against a synthetic plan — zero external infrastructure (services/loadtest package doc).
  • Driver and server share one OS process, so CPU-ms/request includes the load driver's own cost; the cost-per-million estimate is therefore conservative (overstates Riptide's share).
  • Latency is measured from each request's scheduled arrival time (open-loop), so queueing delay under load counts against the system — no coordinated omission.
  • Cost figures are extrapolations from measured CPU at a documented $/core-hour assumption, not an infrastructure bill (docs/spec/slo.md SLO-2).

Throughput ramp

Offered load steps up (5s per step) until the 100ms p99 limit is exceeded. The highest passing step reached 4,000 QPS, or about 1,000 QPS per core.

Offered QPS Achieved QPS p50 p99 Fill rate Error rate Drop rate Within SLO
500 500 1.2ms 80ms 55.2% 0.0% 0.0% Pass
1,000 1,000 1.0ms 80ms 54.8% 0.0% 0.0% Pass
2,000 2,000 1.1ms 80ms 56.4% 0.0% 0.0% Pass
4,000 4,000 1.2ms 80ms 54.9% 0.0% 0.0% Pass
8,000 7,999 29ms 108ms 55.6% 0.0% 0.0% Fail p99 107.8ms > 100ms

To measure auction selection separately, run make load-bench. That microbenchmark evaluates 50 competing candidates and excludes the HTTP request path.

Compute cost per million requests

Estimated serving compute cost, based on measured CPU use and the hourly rates below.

The fixed-load run measured 0.51 CPU-ms and 193 allocations per request. At the documented $0.02/core-hour assumption, that extrapolates to:

Compute profile Estimated compute cost per million requests
ARM spot $0.0024
On-demand x86 $0.0028

These estimates cover CPU only. Memory, network, storage, and spare capacity cost extra. They do not represent Riptide subscription prices or the full cost of a deployment.

Run a benchmark for your workload

Use the self-contained test to compare changes to the serving code. Use the live load generator to measure the network and deployment you expect to run. Both require access to a Riptide source checkout.

# Run the self-contained benchmark
make bench-report

# Auction selection microbenchmark (SLO-1)
make load-bench

# Stress a live deployment over the network
go run ./cmd/riptide-loadgen -base-url https://your-cell.example -mode ramp

make bench-report writes the canonical report to docs/spec/benchmarks/results/latest.json. The source checkout includes more methodology details in docs/spec/benchmarks.md.

The same load engine also drives live deployments: cmd/riptide-loadgen has also been tested against a complete local deployment. Reports in results/live-local*.json describe the hardware and test conditions for those runs.

Industry context

Published numbers from elsewhere in ad tech, cited for context rather than comparison.

The figures below are public SLAs, reference architectures, and production reports from other teams. Hardware, workloads, and network conditions differ from this test. These figures provide context and cannot establish how Riptide performs relative to another platform.

  • Kevel's public service-level agreement commits to 99.99% monthly uptime for its Decision API and to responses within 500ms for at least 95% of requests to its Management API. It publishes no decision-latency percentile.

    Source: Kevel service-level agreement, retrieved July 2026.

  • AWS's reference "Prebid Server Deployment on AWS" solution estimates a baseline cost of about $241.50 per month with no load running, and is designed for deployments handling 5,000 to 100,000 requests per second.

    Source: Prebid Server Deployment on AWS, AWS Solutions Library, retrieved July 2026.

  • FunCorp reported reaching 35,000 requests per second on its production Prebid Server deployment.

    Source: FunCorp engineering blog, retrieved July 2026.

  • The widely cited industry norm is a sub-100ms ad response window; the same source estimates roughly 1% of impressions lost for every additional 100ms of ad latency.

    Source: Osmos, on ad-tech infrastructure, retrieved July 2026.

Plan a test with your traffic

Share your request mix, expected peak load, and latency target. We can help define a test that includes your demand connections and deployment conditions.

Put this into practice

Download the examples · All feature guides