Infrastructure

Measuring Latency in the Browser: A Meta Demo

The RTT badge on this site measures real latency. Here's how, using the Performance API, Vercel edge, and the same principles that apply to trading.

5 min
#latency #monitoring #performance #vercel #infrastructure #observability

The floating badge in the corner shows your actual round-trip time to my server.

RTT 24ms · σ ±3 (iad1)

That’s not decoration. It’s a demonstration of the same latency awareness I apply to trading systems.

What the Badge Shows {#what-it-shows}

MetricMeaning
RTTRound-trip time in milliseconds
σStandard deviation (jitter) of last 10 samples
EdgeVercel edge region serving you

Why These Metrics?

RTT: The total time for a request to travel from browser → server → browser. Includes:

  • DNS resolution (cached after first)
  • TCP handshake (kept alive)
  • TLS negotiation (session resumed)
  • HTTP request/response
  • Edge compute time (<1ms)

Standard Deviation (σ): More important than raw RTT. Low jitter means consistent performance. High jitter means unpredictable spikes, the enemy of trading systems.

Edge Region: Which datacenter served you. iad1 = Virginia, sfo1 = San Francisco, sin1 = Singapore. Vercel routes to the nearest edge.

The Ping Endpoint {#ping-endpoint}

// /api/ping.ts
export const config = {
  runtime: 'edge',  // Run on edge, not origin
};

export async function GET({ request }) {
  // Extract edge region from Vercel headers
  const vercelId = request.headers.get('x-vercel-id') || '';
  const edge = vercelId.split('::')[0] || 'local';
  
  return new Response(JSON.stringify({
    edge,
    ts: Date.now()
  }), {
    status: 200,
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-store, no-cache, must-revalidate',
      'X-Edge-Location': edge
    }
  });
}

Key design decisions:

DecisionWhy
Edge runtimeMinimal latency, no cold starts
no-storeEvery request hits server, no CDN cache
Minimal payloadOnly edge + timestamp
JSON responseEasy parsing

Client-Side Measurement {#client-side}

const samples = [];
const MAX_SAMPLES = 10;

async function measureLatency() {
  // Cache-busting query parameter
  const url = `/api/ping?t=${Date.now()}`;
  
  const t0 = performance.now();
  
  const response = await fetch(url, {
    method: 'GET',
    cache: 'no-store',
    mode: 'cors'
  });
  
  const t1 = performance.now();
  const rtt = t1 - t0;
  
  const data = await response.json();
  
  // Rolling buffer
  samples.push(rtt);
  if (samples.length > MAX_SAMPLES) {
    samples.shift();
  }
  
  // Calculate statistics
  const avg = samples.reduce((a, b) => a + b, 0) / samples.length;
  const sigma = calculateStdDev(samples);
  
  updateDisplay(Math.round(avg), Math.round(sigma), data.edge);
}

function calculateStdDev(arr) {
  const n = arr.length;
  if (n < 2) return 0;
  
  const mean = arr.reduce((a, b) => a + b, 0) / n;
  const variance = arr.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / n;
  return Math.sqrt(variance);
}

// Measure every 10 seconds
setInterval(measureLatency, 10000);
measureLatency();  // Initial measurement

Why performance.now()?

APIResolutionUse Case
Date.now()1msGeneral timing
performance.now()Sub-millisecondHigh precision
performance.timeOriginAbsolute timeCross-origin correlation

performance.now() provides sub-millisecond resolution and is monotonic (won’t go backwards). Citation: Performance API spec.

Statistics: Why Standard Deviation Matters {#statistics}

Average Latency is Vanity

Consider two networks:

  • Network A: 50ms, 50ms, 50ms, 50ms, 50ms → Avg: 50ms, σ: 0ms
  • Network B: 10ms, 10ms, 10ms, 10ms, 170ms → Avg: 42ms, σ: 64ms

Network B has lower average but one horrible request. For trading:

  • Network A: Predictable, can size positions accordingly
  • Network B: One spike causes slippage

Jitter (σ) is the reliability metric.

Interpretation

σQualityImplication
<5msExcellentVery consistent
5-20msGoodNormal variance
20-50msDegradedNetwork congestion
>50msBadInvestigate

Design Philosophy {#design-philosophy}

Measure What You Care About

Traditional metrics for websites:

  • Page load time
  • Time to first byte
  • Largest contentful paint

These aggregates hide latency distribution. A site can have great average load time but terrible P99.

The Trading Parallel

Web MetricTrading Metric
RTTFill latency
Jitter (σ)P99 variance
Edge regionExchange connectivity
Cache missOrder rejection

The same principle applies: measure continuously, track percentiles, minimize variance.

Show, Don’t Tell

Anyone can claim to care about performance. The badge proves it:

  • Real measurement, not synthetic
  • Updated every 10 seconds
  • Visible on every page

Build Your Own {#build-your-own}

Minimal Implementation

<!DOCTYPE html>
<html>
<head>
  <style>
    #rtt-badge {
      position: fixed;
      bottom: 20px;
      right: 20px;
      background: #1a1a1a;
      color: #00ff88;
      font-family: monospace;
      font-size: 12px;
      padding: 8px 12px;
      border-radius: 4px;
      z-index: 1000;
    }
  </style>
</head>
<body>
  <div id="rtt-badge">RTT: --ms</div>
  
  <script>
    const samples = [];
    
    async function measure() {
      const t0 = performance.now();
      await fetch('/api/ping?t=' + Date.now(), { cache: 'no-store' });
      const rtt = Math.round(performance.now() - t0);
      
      samples.push(rtt);
      if (samples.length > 10) samples.shift();
      
      const avg = Math.round(samples.reduce((a, b) => a + b) / samples.length);
      const sigma = Math.round(Math.sqrt(
        samples.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / samples.length
      ));
      
      document.getElementById('rtt-badge').textContent = 
        `RTT: ${avg}ms · σ ±${sigma}`;
    }
    
    setInterval(measure, 10000);
    measure();
  </script>
</body>
</html>

AWS Alternative

If you’re on AWS instead of Vercel:

# CloudWatch Synthetics canary
resource "aws_synthetics_canary" "latency" {
  name                 = "latency-monitor"
  artifact_s3_location = "s3://${aws_s3_bucket.canary.bucket}/canary/"
  execution_role_arn   = aws_iam_role.canary.arn
  handler              = "latency.handler"
  runtime_version      = "syn-python-selenium-1.0"
  
  schedule {
    expression = "rate(1 minute)"
  }
}

Audit Your Infrastructure

Want to check if your servers are configured for low latency? Run latency-audit - it validates kernel settings, CPU governors, and network configurations in seconds.

pip install latency-audit && latency-audit

Reading Path

Continue exploring with these related deep dives:

TopicNext Post
The 5 kernel settings that cost you latencyThe $2M Millisecond: Linux Defaults That Cost You Money
Measuring without overhead using eBPFeBPF Profiling: Nanoseconds Without Adding Any
Design philosophy & architecture decisionsTrading Infrastructure: First Principles That Scale
SLOs, metrics that matter, alertingTrading Metrics: What SRE Dashboards Miss
Share: LinkedIn X