DevOps

Latency optimization: where the milliseconds go and how to cut them

Latency optimization: where the milliseconds go and how to cut them

Latency optimization comes down to two numbers: how far your packets travel and how many times they have to make the trip before the user sees anything. Fix distance and round trips first. Caching, protocol choices and kernel tuning come after, and they’re worth far less than most “low latency solutions” pitches suggest.

Below I’ll go through where the milliseconds go and how to measure them, then rank the fixes by payoff.

Where latency comes from

Every request pays some mix of six costs. Only one of them requires moving the server.

Distance

Light in fiber isn’t instant. The ITU’s planning figure for optical fiber is 5 µs per kilometer, one way (ITU-T G.114, Table A.1). That works out to about 10 ms of round trip for every 1,000 km between the user and the server, before a single router touches the packet.

Here’s what that floor looks like next to real measurements from our Ashburn site (median of RIPE Atlas probes on local ISPs, September 2026, as published on the Ashburn page):

From Ashburn toStraight-line distancePhysics floor (round trip)Measured round trip
New York~350 km~3.5 msabout 7 ms
Los Angeles~3,650 km~37 msabout 62 ms
London~5,900 km~59 msabout 80 ms
Frankfurt~6,550 km~65 msabout 89 ms

The gap between the floor and the measurement is the next two items on this list. The floor itself is non-negotiable. No software makes Los Angeles closer to Virginia.

Routing and hops

Cables don’t follow great circles, and traffic doesn’t take the shortest cable. It follows business relationships between networks, so a packet between two cities can detour through a third.

Queuing and bufferbloat

When a link is busy, packets wait in buffers. Oversized buffers on home routers, cable modems and busy uplinks can add tens or hundreds of milliseconds under load, which is why a connection that pings fine at idle feels awful while someone’s uploading video. That’s bufferbloat. The usual fix is a smarter queue such as fq_codel (RFC 8290) at the bottleneck, which is often the user’s own router.

Handshakes

A fresh HTTPS request over TCP costs one round trip for the TCP handshake, then one more for TLS 1.3 or two for TLS 1.2, and only then does the actual request go out. Round trips multiply distance. This is the cost people underestimate most.

Server processing

Time the application spends building the response: framework overhead, database queries, calls to other services, lock contention. On a lot of dynamic sites this is bigger than the network time, and no CDN fixes it.

Disk

A random read from a spinning disk costs milliseconds. From an SSD it’s well under one. If your hot data doesn’t fit in RAM and lives on spinning drives, every cache miss shows up in your response times.

How to measure latency before you change anything

Don’t tune blind. Get a baseline from where your users are, change one thing, and measure again.

ping: the round trip floor

ping -c 20 example.com

Look at the min and the average. The min is close to your network floor; a big gap between min and max points to queuing somewhere. Some routers deprioritize ICMP, so treat ping as a rough guide and confirm with TCP-based tools.

mtr: where on the path it goes wrong

mtr -rwbz -c 100 example.com
mtr -rwbz -T -P 443 -c 100 example.com

-r prints a report after -c cycles, -w keeps hostnames unclipped, -b shows names and IPs, -z adds the AS number for each hop, and -T -P 443 probes with TCP SYNs to port 443 instead of ICMP (options per the mtr man page). Read it from the bottom up. Loss or high latency at one middle hop that doesn’t carry through to the final hop is usually that router rate-limiting replies to probes, not a real problem. A jump that persists all the way to the end is real, and the AS numbers tell you which network it happens in.

curl: split one request into its parts

This is the most useful one-liner in the whole guide:

curl -o /dev/null -s -w 'dns:      %{time_namelookup}\nconnect:  %{time_connect}\ntls:      %{time_appconnect}\nfirst byte: %{time_starttransfer}\ntotal:    %{time_total}\n' https://example.com/

Every value is in seconds, counted from the start of the request (see the curl man page for --write-out). So subtract neighbors to get each phase:

  • connect minus dns is roughly one network round trip (the TCP handshake).
  • tls minus connect is the TLS handshake.
  • first byte minus tls is one more round trip plus the time your server spent thinking.

If that last gap is much bigger than your ping time, stop looking at the network. Your problem is in the application or the database.

ss: what live connections are seeing

ss -ti

On the server, this shows each TCP connection’s smoothed rtt and its variance in milliseconds (ss man page). Real users beat synthetic tests.

One more thing: measure from where your users are, not from your office. Probe networks like RIPE Atlas let you ping a target from probes on ISPs in specific cities, which is how we got the Ashburn figures above.

The fixes, ranked by payoff

My order, from biggest win to smallest: location, round trips, caching, server tuning. Most teams do it backwards because tuning feels like engineering and picking a data center feels like paperwork.

1. Put the server near your users

This is the one you can’t patch later. Everything else in this list multiplies the base round trip, so a server 62 ms away pays 62 ms per round trip on every handshake, every API call and every uncached asset.

Start with where your users and your dependencies actually are. For a US audience, that usually means one of three metros. We run dedicated servers in Ashburn (East), Chicago (Central) and Los Angeles (West). Ashburn is about 7 ms from New York and about 80 ms from London, which makes it a reasonable single site for an East Coast plus Europe audience. If your workload talks to an exchange or a specific cloud region, put the server in that metro. Our posts on Chicago to CME latency and Ashburn vs Chicago latency walk through those choices with numbers.

2. Cut round trips

Once location is fixed, the cheapest way to reduce latency and improve performance is to stop paying for the same handshake twice. Here’s a worked example: a user in London hitting a server in Ashburn at 80 ms round trip, ignoring DNS and server time.

Connection typeRound trips before the response arrivesMinimum wait at 80 ms
New TCP + TLS 1.24~320 ms
New TCP + TLS 1.33~240 ms
New QUIC (HTTP/3)2~160 ms
Reused keep-alive connection1~80 ms

Same server, same code, a 4x spread. The same table from New York at 7 ms tops out under 30 ms, which is why handshake work matters most for far-away users.

What to actually do:

  • Turn on TLS 1.3. It cuts the full handshake to one round trip (RFC 8446). Current nginx, Apache, Caddy and HAProxy releases support it, but check your config doesn’t still pin TLS 1.2.
  • Keep connections alive and reuse them. That goes for browsers talking to you and for your own services talking to each other. A backend that opens a new TLS connection to the database or an internal API for every request is paying handshake tax on your side of the wire.
  • Serve HTTP/2, and HTTP/3 where you can. HTTP/2 multiplexes many requests over one connection. HTTP/3 runs over QUIC, which folds the transport and TLS handshakes into one round trip (RFC 9000) and can resume with 0-RTT, at the cost of replay risk on that early data.
  • Cut third-party domains. Each new hostname on a page means DNS plus a new connection.

3. Cache, and use a CDN for what can be cached

The fastest round trip is the one that ends close to the user. A CDN puts static assets and cacheable pages near users, and it terminates TLS nearby, so the handshakes in the table above happen over a short hop. On the origin, cache rendered pages and expensive query results in memory (Redis, Memcached, or your framework’s page cache) so repeat requests skip the database.

Be honest about what a CDN can’t do. Logged-in pages, API writes, game state and trading orders still go to your origin. For those, item 1 is the whole game.

4. Tune the server, carefully

Kernel tuning comes last, not first. Measure with curl first; if “first byte minus tls” is huge, look at slow queries, missing indexes and blocking calls before you touch a sysctl. Keep hot data in RAM or on SSDs.

On the network side, the change with the best evidence behind it is BBR congestion control. It’s been in Linux since 4.9, and since 4.20 it no longer strictly needs the fq qdisc, though fq still does better on busy servers (Google’s BBR quick-start). Check what your kernel offers before you change anything:

sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

If bbr isn’t listed, try sudo modprobe tcp_bbr. If that fails, your kernel wasn’t built with it. If it works, make it stick:

echo 'tcp_bbr' | sudo tee /etc/modules-load.d/bbr.conf
echo 'net.core.default_qdisc = fq' | sudo tee /etc/sysctl.d/90-bbr.conf
echo 'net.ipv4.tcp_congestion_control = bbr' | sudo tee -a /etc/sysctl.d/90-bbr.conf
sudo sysctl --system

BBR changes how fast your server sends, not how far away the user is. It helps most on long or lossy paths and with large transfers, and it won’t move your ping by a millisecond. For services with long-lived connections that sit idle between bursts, also look at net.ipv4.tcp_slow_start_after_idle; setting it to 0 stops the kernel from shrinking the congestion window after an idle period (kernel ip-sysctl docs). Test both against your own traffic before you roll them out everywhere.

5. Use UDP or QUIC for low latency real-time traffic

For games, voice, video calls and live market data, the problem with TCP isn’t speed. It’s that one lost packet holds up everything behind it until it’s resent. UDP has no handshake and no head-of-line blocking, so a lost packet costs only that packet, and the application decides whether to resend it, skip it or interpolate around it. That’s why a lot of low latency transport and messaging middleware is built on UDP, and why QUIC exists: it gives you TLS and reliable streams over UDP without one stream’s loss stalling the others.

UDP isn’t automatically faster, though. You still pay distance, and you have to build the reliability, ordering and congestion control your app needs. If you’re writing low latency software, pick UDP when stale data is worthless (a player position from 200 ms ago) and stick with TCP or QUIC when every byte must arrive.

6. Split across regions when one site can’t cover everyone

One well-placed site plus a CDN covers most US web apps. From Ashburn, the far side of the country is about 62 ms, which is fine for a store or a dashboard. It isn’t fine for a fast shooter or a voice app, where every extra millisecond shows up as lag.

Split into regions when real-time users on both coasts, or a large European or Asian audience, sit far from a single site. The latency management strategies global multiplayer games use apply to anyone: put a server in each region, route each user to the nearest one by measured ping rather than by geography, and keep shared state in one place so you’re not fighting replication conflicts. That last part is the real cost of going multi-region. Reads are easy to spread out; writes that must agree across regions put the long round trip right back in.

Quick answers

What is latency optimization?

It’s reducing the time between a user’s action and the response they see. In practice that means shortening the network path, cutting the number of round trips per request and making the server answer faster, in roughly that order of payoff.

Does more bandwidth lower latency?

Not directly. Bandwidth is how much fits through the pipe; latency is how long the trip takes. More bandwidth helps only when a link is congested and packets are queuing, which is the bufferbloat case above.

What’s a good latency number?

There’s no single number. Work out the physics floor for your users’ distance (10 ms per 1,000 km) and compare it with what you measure. The Ashburn figures above run about 1.4 to 2 times the floor, which is normal for real routes. If you’re well past that, run mtr and find out where the path goes sideways.

Most of the fixes in this guide are software you can change next week. Distance isn’t. Choose the server’s metro first, with numbers in hand: we run dedicated servers in Ashburn, Chicago and Los Angeles, and the posts above compare round trips to the big exchanges and US metros. If you’re not sure which site fits your users, tell us where they are and ask for a quote. Dedicated servers · Chicago to CME latency · Ashburn vs Chicago latency · Ashburn dedicated servers

Not ready to order yet?

Tell us what you’re after and we’ll email you the build and the price. Need it today? Call (800) 561-2656 and we’ll check what’s in stock.

    Reply within 1 business day4.8 on Google (22 reviews)SOC 2 Type II

    By submitting this form, you agree to GigeNET's Privacy Policy. We'll only use your email to reply about this request.