← BlogInfrastructure

Dictation went from 1 second to 26. The cause was a network route.

In July 2026, a GHZ Voice dictation took between 0.4 and 2 seconds to come back as text. In August it took 12 to 26 seconds. Nothing in the app had changed, the transcription provider was as fast as ever, and the server was idle.

Where the time went

A dictation is a short WAV file. A 30-second recording weighs about 1 MB. The app uploads it to our API, the API sends it to the speech model and returns the text. We timed each leg separately, from the same Mac:

4.2 MB/s
Mac → Cloudflare
40 MB/s
Cloudflare → our server
1.8 MB/s
our server → Mac
28 KB/s
Mac → our server, direct

Downloads were fine. Uploads straight to the server crawled at 28 KB per second, so a 1 MB recording spent about 30 seconds in transit. We reproduced it with curl and an authenticated request: 27 to 32 seconds, every time.

The cause was a route, not a server

The hosting provider had changed our server’s IP range a few weeks earlier. After that, traffic from our internet provider to the new address took a different path than the traffic coming back. A traceroute showed the upload path going through China Mobile International, with 175 ms of latency and around 7% packet loss.

TCP does not survive that kind of loss on a long path. The connection keeps backing off and the throughput collapses. The return path went elsewhere, which is why downloads looked healthy and the problem hid for weeks.

What to run when only one direction is slow
# time an upload of a known size
curl -o /dev/null -w "%{speed_upload} B/s\n" \
  --data-binary @1mb.bin https://api.example.com/endpoint

# compare the path in each direction
mtr -rwzc 100 api.example.com      # from your machine
mtr -rwzc 100 <your public IP>     # from the server

The fix: stop depending on that path

We could not change how other networks route traffic. We could change where our traffic enters. We moved the API behind Cloudflare: the Mac uploads to the nearest Cloudflare location, which was already fast, and Cloudflare carries the request to the server over its own network.

The server now has no public web port at all. A Cloudflare Tunnel opens an outbound connection from the server, and every request comes in through it. More on that setup in one server for every backend.

Today, from the same Mac, a 1 MB upload to the API takes 1.4 to 2.3 seconds, measured on 2 November 2026.

Keep reading

More build logs.

All posts →
  1. Engineering2 November 2026Shipping updates to a Mac app without the App Store5 min
  2. Engineering2 November 2026Why “Update Codex” failed inside GHZ Code and worked in the Terminal4 min
  3. Story2 November 2026FundingView: 11 days, Claude in a browser tab, and a CSV on GitHub4 min