Guided journey

Serve Users in Asia Without the Round Trip

An intermediate journey: pick an APAC region, put a Hong Kong edge in front, cut the bytes, cache correctly, and measure p95 from real cities.

You walk away with

An app that answers Hong Kong and Singapore users from a nearby edge with a measured p95, not an assumption — and no mainland filing required.

Assume you have

A deployed app and a domain you control. You should be able to change DNS and redeploy.

Stack used

Any host plus a CDN with a Hong Kong point of presence. The steps are provider-neutral on purpose.

The project

Take an app that feels slow for users in Hong Kong, Singapore, and Southeast Asia, and fix the actual cause — usually distance and bytes, not code. You will pick a region, put an edge in front of it, cut the payload, cache deliberately, and prove the improvement from real cities.

By the end you will have: a region choice you can justify, a CDN edge in front of the origin, a cache hit ratio you know, and a before-and-after p95 measured from at least three APAC locations.

Before you start

  • The app deployed and reachable from a public URL, with DNS you can change.
  • A way to measure requests from somewhere other than your laptop: a measurement service with APAC agents, or users who will run a command for you.
  • Which APAC Cloud Region Should You Deploy To? as the map for the region decision. This journey is the order to walk it in.

Milestone — Measure before you move anything

Build: a baseline of time to first byte, measured from your real user cities.

You cannot fix a latency problem you have not measured, and a local test tells you almost nothing. Get numbers from Hong Kong, Singapore, and one more city you actually care about, before changing a single setting.

Do it

  1. Measure the current site from each location, splitting DNS, connect, TLS, and time to first byte.
  2. Record the numbers in a table with the date, because you will compare against them.
  3. Note which city is worst and whether the difference looks like distance or like bytes.

Done when you have a baseline table with at least three rows and you know which row is the problem. Latency Numbers Every Developer Should Know tells you which bands are normal.

# Run from a box or service in each city. The phase breakdown is the point.
curl -o /dev/null -s -w \
  'dns %{time_namelookup}s  connect %{time_connect}s  tls %{time_appconnect}s  ttfb %{time_starttransfer}s  total %{time_total}s\n' \
  https://example.com/

Milestone — Decide the region, and write down why

Build: a written region choice with the compliance question answered first.

Region choice looks like a latency question and is actually a compliance question first. If you are considering a mainland region, stop and check eligibility before comparing milliseconds.

Do it

  1. Answer whether a mainland entity exists that could hold a filing — Does a Foreign Company Need a Chinese Entity for an ICP Filing?.
  2. If not, choose between Hong Kong, Singapore, and nearby options — Hosting in Hong Kong vs Mainland China: What Actually Changes.
  3. Write the choice and the trade-off into NOTES.md, including which city you are optimising for and which you are accepting as second-best.

Done when the region is chosen for a stated reason and you can name the city you are deliberately not serving as well.

Milestone — Move the origin closer

Build: the application running in the chosen region, serving the same domain.

This is a migration, not a rewrite: same app, same database, different location. The failure to avoid is moving the origin while also changing TLS termination or DNS in the same window, which makes the measurement meaningless.

Do it

  1. Provision the app in the new region and verify a health check passes there.
  2. Move the database if it is co-located, or confirm the distance to it is acceptable — a Hong Kong app with a database in Virginia has not solved anything.
  3. Cut DNS over with a low time-to-live so a rollback is quick.

Done when the app serves from the new region and a direct request to the origin is fast from nearby. How to Point a Domain at Your Server is the DNS step.

Milestone — Put a Hong Kong edge in front

Build: a CDN in front of the origin, with the nearest edge answering for APAC users.

The edge does two jobs at once: it terminates users closer to home, and it absorbs repeat requests so the origin is asked far less often. Both reduce the time a user waits.

Do it

  1. Add the domain to a CDN that has a Hong Kong point of presence.
  2. Confirm static assets are served from the edge and that the origin is no longer answering them.
  3. Leaving mainland acceleration off is correct here — enabling it requires a filing, and you do not have one.

Done when a request from Hong Kong is answered by the edge, and the origin’s request count has dropped. What Is a CDN and Do You Need One? covers what the edge is doing; Does Hosting Behind a CDN in China Require an ICP Filing? explains why the mainland nodes stay off.

Milestone — Cut the bytes before tuning anything else

Build: a smaller payload, measured in kilobytes.

Every kilobyte is latency for someone on the far side of an ocean from your origin. Reducing bytes is usually a bigger win than any server-side optimisation, and it is the change with the least risk.

Do it

  1. Enable compression for text responses and confirm the content is actually compressed.
  2. Serve images at the size they are displayed, in a modern format.
  3. Check the page weight in the browser’s network panel, on a throttled connection, and record it next to the baseline.

Done when the initial payload is substantially smaller and you can state the before-and-after figure. How to Add Redis Caching to an App is the related work once you start caching responses rather than files.

Milestone — Cache deliberately, and know your hit ratio

Build: correct cache headers and a hit ratio you can quote.

Caching is where the biggest wins and the strangest bugs live. Getting the headers wrong serves stale data to everyone; getting them right means most requests never reach your origin at all.

Do it

  1. Set immutable, long-lived caching for fingerprint-named assets.
  2. Set short caching or revalidation for HTML and API responses, and make sure personalised responses are marked private.
  3. Read the CDN’s cache statistics after a day and write the hit ratio down.

Done when static assets hit the cache almost always and your origin’s CPU is measurably lower. What Is Caching? and What Is Cache Poisoning? cover the correctness side.

Milestone — Remove the cross-border killers

Build: fewer round trips per request, and no long-lived connections being torn down cheaply.

Cross-border connections are more sensitive to handshake cost than domestic ones. Three settings account for a surprising share of the remaining delay.

Do it

  1. Enable HTTP/2 or HTTP/3 so multiple resources share one connection.
  2. Keep TLS modern and check the certificate chain is complete — an incomplete chain can add a round trip.
  3. Look for redirect chains, which each add a round trip before the useful response; flatten them.
  4. If anything on the request path is serverless, check for cold starts on the first request from a new region — What Are Serverless Cold Starts (and Do They Matter for You)?.

Done when a repeat visit makes fewer round trips than the baseline and the redirect chain is gone. Cloudflare 525 and 526: How to Fix an SSL Handshake Failure is the reference when TLS is what breaks rather than what is slow.

Milestone — Re-measure from three cities, and set a p95 target

Build: a before-and-after table with p95 from at least three APAC locations.

The only honest proof is the same measurement you took at the start, run the same way. Compare p95, not just the median, and keep the numbers in the repository so the next change has a baseline.

Do it

  1. Repeat the phase-split measurement from each city, several times over a day.
  2. Put the before and after in the same table, with p50 and p95.
  3. State a budget you will defend — for example, a p95 time to first byte for Hong Kong and Singapore users — so regressions are visible.

Done when the table shows an improvement for every measured city and the budget is written down.

Milestone — Keep watching it

Build: a monitor that tests from more than one region, and an alert that names the region.

Latency is a slow-moving regression: a new dependency, a larger image, or a database that moved will undo this work quietly. Monitoring from one location cannot see it.

Do it

  1. Point an uptime check at the app from at least two APAC locations.
  2. Track response time as a metric, not only availability.
  3. Alert on a sustained increase rather than a single slow sample.

Done when you would receive an alert if Asia got slower next month. What Is Uptime Monitoring? and How to Get Alerted When Your Site Goes Down cover the setup.

Ship checklist

  • Baseline measured from real cities before any change.
  • Region chosen, with the compliance question answered first.
  • Origin and database are in the same region, or the distance is justified.
  • A CDN edge in Hong Kong answers APAC users.
  • Mainland acceleration is deliberately off, or a filing exists.
  • Payload size reduced and recorded.
  • Cache headers correct; hit ratio known.
  • Redirect chains removed; HTTP/2 or HTTP/3 enabled.
  • p95 re-measured from at least three cities and a budget written down.
  • Multi-region uptime and latency monitoring in place.

Where this journey goes wrong

  • Optimising code before measuring. The delay is almost always distance or bytes.
  • Moving the origin and the CDN in the same window. You cannot tell which change helped.
  • Judging by the median. p95 is where cross-border users live.
  • Enabling China acceleration by reflex and hitting a filing requirement at configuration time.
  • Caching personalised responses publicly. A correctness bug that looks like a speed feature.
  • Leaving the database behind. A fast edge in front of a distant database is still slow.
  • Watching from one location. The city that breaks is usually not the one you test from.

FAQ

Do I need an ICP filing to serve Hong Kong and Singapore users?

No. The filing attaches to hosting inside mainland China. A Hong Kong or Singapore region with a Hong Kong CDN edge serves those users without any registration. The filing only enters the picture if you host inside the mainland or enable mainland acceleration, both of which are separate decisions.

Is the average response time a fair measure?

No. Cross-border routing has a long tail, so the average can hide the users who are actually suffering. Measure p95 as well as the median, from several cities, and set your target on p95. A healthy median with a bad tail usually means one carrier or one path is congested.

Should I keep my database in the same region as the app?

Yes, unless the latency cost is justified. An edge and an app in Hong Kong with a database across an ocean still pay a round trip per query, and an app making many queries pays it many times. Training the database to be far away undoes the benefit of moving everything else closer.

Share: