유대선
프로젝트로
·결정·4

Multi-region DB decision: US/Korea users, should we split the DB in two?

Discussing whether to split the DB in two for US/Korea users. The conclusion is 'one DB for now'. Splitting data by region is a compliance (data residency) solution, not a speed solution, and it breaks our app's cross-user contribution links. Speed is solved by function/DB colocation -> media CDN -> (later) read replicas. Splitting before measuring is self-harm. (Discussion memo — not an implementation.)

The question

"US users and Korea users are different — can we create 2 DBs to separate them? I want to think about this seriously later."

At first I vaguely wondered "if the users are different, should the DB be split too," but digging in, two different questions were mixed together.

What had to be separated first: what does "different" mean

  1. UX/language differences — English screen / Korean screen, copy branching. → This is already solved by the i18n (ko/en, lib/copy.ts) I built. No matter where the data is stored, showing each user a different language/experience is the app layer's job.
  2. Where the data is stored — latency and law (data residency). → This is the real domain of "splitting the DB."

The two are completely separate. The real reason I was trying to split was speed/latency (worried it'd be slow if a US user round-trips all the way to the Seoul DB every time). So looking only from that angle —

Core conclusion: splitting data by region is not a "speed" solution

Splitting data in two is a tool for data residency (compliance). Doing it for speed is picking the wrong tool. Reasons:

곁 has contribution links (confirmed in code: app/api/links/route.ts issues a token, and someone else comes in via app/api/c/[token]/route.ts and leaves a word in the owner's keepsake box).

If you split the DB by region:

When a link created by a Korea user is opened by a friend in the US, that token isn't in the US DB, so it won't resolve. Sharing/contribution breaks at the region boundary.

To save this, you'd have to embed a region in the link or keep a small shared mapping table → complexity spikes. On top of that, 2 DBs = management, billing, migration, and backup all doubled.

The right ladder to solve speed (cheapest and most effective first)

  1. Put the DB in the primary user region, and match the Vercel function region to it. 곁 is Korea-first → Supabase Seoul + function region icn1. US users cross the ocean once, but this app is a lightweight personal-memo type, so the perceived impact is small.
  2. Media goes on a CDN (S3 + CloudFront). What users perceive as speed is photos/voice/video, and a CDN edge already solves regional latency for that. Text query latency is small.
  3. Pooled connections (Supabase pooler) — removes serverless cold-connection latency. Essential regardless of region.
  4. Reduce the number of queries per request / caching — cutting the round-trip count is bigger than a faster DB.
  5. When US traffic actually grows → read replicas. This is the textbook solution for regional latency: US functions read from a nearby replica, and writes go to the main DB. You get all the read-speed benefits of 2 DBs while keeping the data as one → contribution links don't break.

Decision

One line

Split data by region only because of compliance. Solve speed with function–DB colocation → media CDN → (later) read replicas, and all three keep one logical dataset to keep cross-user features alive. Don't shard data for latency you haven't measured.

(This post is a discussion/decision memo. There was no code change — the app already runs on a single DATABASE_URL, and this decision keeps that design.)