# Edge server in Tokyo: a reverse proxy in front of your origin

URL: https://cloudj.net/blog/tokyo-edge-reverse-proxy
Published: 2026-11-11 · Updated: 2026-11-11

> Put an edge server in Tokyo in front of a distant origin: when it helps, an Nginx reverse proxy and cache config, a Caddy option, and how to check cache hits.

An edge server in Tokyo is a small VPS that sits between your users in East Asia and an origin server somewhere else, often in Europe or the United States. It terminates TLS close to the user, keeps a reused connection open to the origin, and serves cacheable responses straight from Tokyo. You get part of what a CDN does, with full control over the rules, on a server you can SSH into. This guide covers when the pattern is worth it, a working Nginx configuration with caching, a simpler Caddy variant, and how to check that it does what you think.

## How an edge node in front of an origin works

Without an edge, a visitor in Tokyo or Seoul opens a TCP connection and negotiates TLS with an origin on another continent. Each of those handshakes is a round trip over the long path before the first byte of the page arrives.

With an edge in Tokyo:

1. The visitor connects to the Tokyo VPS, and the TCP and TLS handshakes happen over a short regional path.
2. If the response is in the edge cache, Tokyo answers immediately and the origin is never asked.
3. If not, the edge forwards the request over a connection to the origin it has already opened and kept alive, so the long path is crossed once per request instead of several times.

The origin keeps running your application and database as before. The edge is stateless apart from its cache, which makes it easy to rebuild.

## When an edge server in Tokyo is worth it

The pattern helps when:

- A meaningful share of your users are in Japan, Korea, Taiwan or nearby, and your origin is far away.
- Many responses are cacheable: product pages, docs, images, API responses that are the same for everyone.
- You want control a CDN plan does not give you, such as custom cache keys, a fixed egress IP for allowlists, or logs on your own disk.

It helps less, or not at all, when:

- Almost every request is personalised and uncacheable. You still save handshake time, but every request crosses the long path.
- Your users are spread worldwide. One edge in Tokyo makes visitors in Europe take a detour through Japan. You would need GeoDNS to send only East Asian visitors to Tokyo, or a full CDN.
- The real fix is moving the origin. If most of your users are in East Asia, running the application itself in Tokyo is simpler; [best VPS in Japan](https://cloudj.net/blog/best-vps-japan) covers that choice.

If you are deciding between Asian cities for the edge, [Singapore vs Hong Kong vs Tokyo VPS](https://cloudj.net/blog/singapore-vs-hong-kong-vs-tokyo-vps) compares them, and the [Asia VPS guide](https://cloudj.net/blog/asia-vps-guide) explains the wider region. For Southeast Asian users a second edge in Singapore can sit alongside Tokyo, much as a [crypto trading bot in Singapore](https://cloudj.net/blog/crypto-trading-bot-vps-singapore) is placed close to the systems it talks to.

## Sizing the Tokyo VPS

An edge proxy is light on CPU and needs RAM mainly for the cache index and the operating system page cache. A small general purpose plan is a sensible start; Cloudj's Tokyo location offers 30 ready-made plans from 1 vCPU with 1 GB RAM and 20 GB disk, or your own mix of vCPU, RAM and disk. Give the disk room for the cache.

Watch traffic carefully. Every byte the edge serves to visitors leaves from Tokyo, and cache misses also pull data from the origin. Monthly plans in Tokyo include 1 TB of traffic; on hourly billing traffic is charged per GB. See the [Japan VPS page](https://cloudj.net/cloud-servers/japan) and live prices on the [pricing page](https://cloudj.net/pricing).

## Nginx reverse proxy and cache configuration

This assumes Ubuntu or Debian with Nginx installed, DNS for `www.example.com` pointing to the Tokyo VPS, and an origin reachable at `origin.example.com` that also serves `www.example.com` with a valid certificate. Get the edge certificate first with Certbot (`sudo certbot certonly --nginx -d www.example.com`), as described in the [Nginx reverse proxy with SSL guide](https://cloudj.net/blog/nginx-reverse-proxy-ssl-vps).

Create `/etc/nginx/conf.d/edge.conf`:

```nginx
proxy_cache_path /var/cache/nginx/edge levels=1:2 keys_zone=edge:50m
                 max_size=10g inactive=7d use_temp_path=off;

upstream origin {
    server origin.example.com:443;
    keepalive 16;
}

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    location / {
        proxy_pass https://origin;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;

        proxy_ssl_server_name on;
        proxy_ssl_name $host;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;

        proxy_cache edge;
        proxy_cache_valid 200 301 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;
        proxy_cache_bypass $cookie_session;
        proxy_no_cache $cookie_session;
        add_header X-Cache-Status $upstream_cache_status always;
    }
}
```

What the important lines do:

- `keepalive 16` with `proxy_http_version 1.1` and an empty `Connection` header keeps connections to the origin open, which is where most of the gain on uncached requests comes from.
- `proxy_ssl_server_name` and `proxy_ssl_name $host` send the right SNI so the origin presents the right certificate, and `proxy_ssl_verify` checks it.
- `proxy_cache_use_stale` keeps serving cached pages if the origin is briefly unreachable.
- The `$cookie_session` lines skip the cache for logged-in users; replace `session` with your application's session cookie name.

Nginx also respects the origin's `Cache-Control` headers and does not cache responses that set cookies, so the origin stays in charge of what is cacheable. Note that Nginx resolves `origin.example.com` when it starts; reload Nginx if the origin's IP changes. Run `sudo nginx -t && sudo systemctl reload nginx` to apply. Directive details are in the [Nginx proxy module documentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html).

On the origin, allow web traffic only from the edge's IP (and any other edges), so nobody bypasses the cache, and log `X-Forwarded-For` to keep real visitor IPs.

## A simpler option: Caddy

If you want automatic HTTPS with almost no configuration and do not need caching, Caddy is a good fit. A minimal `Caddyfile` for an origin that expects its own hostname:

```text
www.example.com {
    reverse_proxy https://origin.example.com {
        header_up Host {upstream_hostport}
    }
}
```

Caddy obtains and renews the certificate itself. The standard Caddy build does not include an HTTP cache, so this variant saves handshake time but does not serve pages from Tokyo. Choose Nginx when caching matters.

## Verifying and troubleshooting

Request the same URL twice and read the cache header:

```bash
curl -sI https://www.example.com/ | grep -i x-cache-status
```

The first response should say `MISS` and the second `HIT`. To compare timings, run `curl -o /dev/null -s -w "%{time_starttransfer}\n" https://www.example.com/` from a machine in the region, against both the edge and the origin. For network-level checks, [test VPS latency with ping and mtr](https://cloudj.net/blog/test-vps-latency-ping-mtr) shows how to read the path.

| Symptom | Likely cause | Fix |
|---|---|---|
| Always `MISS` | Origin sends `Cache-Control: private` or `no-store`, or sets a cookie | Adjust origin headers for public pages |
| `BYPASS` for everyone | The bypass cookie is set on all visitors | Bypass on the login cookie only |
| 502 errors | SNI or certificate mismatch to origin | Check `proxy_ssl_name` and the origin certificate |
| Logged-in pages shown to others | Personal pages cached | Add `proxy_no_cache` rules for those paths |

## FAQ

### Is this a replacement for a CDN?

Not fully. It gives you one well-placed cache under your control. A CDN gives many locations at once. Many teams use both.

### Can I add more edges later?

Yes. Save the configured Tokyo server as a custom image and deploy it in another location, then route visitors with GeoDNS.

### Does the edge need much CPU?

Usually not. TLS and proxying are light; disk and traffic tend to matter more. Watch the console metrics after launch.

## Build your Tokyo edge

Deploy a small Tokyo server in the [Cloudj console](https://app.cloudj.net), apply the Nginx configuration above, and point a test hostname at it before switching production DNS. Check the cache headers and the traffic graph for a week, then decide whether to keep it, resize it, or add a second edge.
