Case Study: Design a Proximity Service (Nearby Businesses)

“Mỗi ngày hàng trăm triệu người mở Google Maps hỏi: ‘Quán phở nào gần đây nhất?’ — Câu hỏi tưởng đơn giản, nhưng phía sau là một bài toán geospatial indexing phức tạp, nơi toán học gặp engineering ở quy mô hành tinh.”

Tags: system-design proximity-service geospatial geohash quadtree alex-xu case-study vol2 Student: Hieu Prerequisite: Tuan-02-Back-of-the-envelope · Tuan-06-Cache-Strategy · Tuan-07-Database-Sharding-Replication Lien quan: Tuan-05-Load-Balancer · Tuan-09-Rate-Limiter · Tuan-10-Consistent-Hashing · Tuan-13-Monitoring-Observability Reference: Alex Xu, System Design Interview — An Insider’s Guide, Volume 2 — Chapter 1: Proximity Service


1. Context & Why — Tai sao Proximity Service quan trong?

1.1 Analogy — Bai toan doi thuong

Hieu, hay tuong tuong 2 tinh huong hang ngay:

Tinh huong 1 — Google Maps: Em dang o quan 1 TP.HCM, mo Google Maps va go “pho”. Trong vong 0.5 giay, ban do hien ra 20 quan pho gan nhat, sap xep theo khoang cach. Phia sau cai “0.5 giay” do la gi? Lam sao tu toa do GPS cua em (10.7769, 106.7009), he thong tim duoc 20 quan pho trong hang tram trieu dia diem tren the gioi?

Tinh huong 2 — Grab tim tai xe: Em dat Grab, app can tim tat ca tai xe trong ban kinh 3km quanh vi tri cua em. Nhung tai xe di chuyen lien tuc — vi tri cua ho thay doi moi 3-5 giay. He thong phai tra loi cau hoi “ai gan em nhat?” cho hang trieu user dong thoi.

Ca hai tinh huong nay deu la bai toan Proximity Service — cho mot toa do (latitude, longitude) va ban kinh (radius), tim tat ca cac diem (businesses, tai xe, ban be) trong vung do.

1.2 Tai sao bai toan nay kho?

Van deGiai thichQuy mo
Du lieu khong lo200 trieu businesses tren toan cau~200M records
Two-dimensional searchKhong the dung B-tree index binh thuong — latitude va longitude la 2 chieu doc lapO(N) naive search
Read-heavyHang tram trieu user search dong thoi, nhung businesses it khi thay doiRead:Write ~ 1000:1
Low latencyUser ky vong ket qua trong < 500msp99 < 200ms
Global scaleUser va businesses o khap the gioi, moi region co density khac nhauTokyo dense, Sahara sparse

1.3 Real-world Systems su dung Proximity Service

CompanyUse CaseScale
Google Maps / PlacesTim nha hang, gas station, ATM200M+ places
Uber / GrabTim tai xe gan nhatMillions of active drivers
YelpTim businesses theo category + location~200M businesses
Facebook Nearby FriendsTim ban be dang o gan2B+ users
TinderTim nguoi match trong ban kinh75M+ users
DoorDashTim nha hang co delivery390K+ merchants

Step 1 — Understand the Problem & Establish Design Scope

1.1 Clarifying Questions (Cau hoi lam ro)

Trong interview, luon hoi truoc khi thiet ke. Day la cac cau hoi quan trong:

Cau hoiTra loiGhi chu
User co the chi dinh ban kinh search?Co — 0.5km, 1km, 2km, 5km, 20kmDefault 5km
Radius toi da la bao nhieu?20kmGioi han de tranh query qua rong
Businesses co the update thong tin?Co — nhung thay doi phan anh vao ngay hom sau la chap nhan duocNear real-time khong bat buoc
User co the di chuyen va search dong thoi?Co, nhung khong can auto-refresh lien tuc — chi khi user bam search laiKhac voi Nearby Friends
Can sap xep ket qua theo gi?Khoang cach, hoac ranking/ratingDistance la primary
Business info gom nhung gi?Ten, dia chi, toa do, category, gio mo cua, rating, anhRich metadata

1.2 Functional Requirements (Yeu cau chuc nang)

  • FR1: Cho toa do (lat, lng) va ban kinh (radius), tra ve danh sach businesses trong vung do
  • FR2: Business owners co the them/sua/xoa thong tin business (CRUD)
  • FR3: Users co the xem chi tiet business (ten, dia chi, rating, gio mo cua, anh)
  • FR4: Ket qua co the loc theo category (nha hang, cafe, gas station…)

1.3 Non-functional Requirements (Yeu cau phi chuc nang)

Yeu cauMuc tieuGiai thich
Low Latencyp99 < 200ms cho searchUser ky vong ket qua nhanh
High Availability99.99% uptimeLBS la core feature cua Maps
High Scalability200M DAU, 100M businessesGlobal scale
Eventual ConsistencyBusiness updates co the delay vai phutKhong can real-time cho business info
Read-heavyRead QPS >> Write QPSSearch nhieu hon update

1.4 Capacity Estimation (Uoc luong nang luc)

Assumptions:

Thong soGia triGiai thich
DAU200MQuy mo Google Maps
Businesses100MToan cau
Searches/user/day5Trung binh
Business updates/day100KThem/sua/xoa

QPS Calculation — Search:

Nhan xet: 60K peak QPS cho read — day la read-heavy system. Write QPS chi khoang 1-2 QPS cho business updates. Ty le Read:Write ~ 60,000:1.

Write QPS — Business Updates:

Write QPS cuc thap — hoan toan co the handle boi 1 primary database server.

Storage — Business Data:

Storage — Geospatial Index:

Quan trong: 3.6 GB geospatial index vua du de load toan bo vao memory. Day la insight then chot — ta co the build in-memory index (Quadtree) tren 1 server.

Cache Sizing:

Su dung Redis cluster voi vai node la du. Tham chieu Tuan-06-Cache-Strategy.

Quadtree Memory Estimation (se deep dive o section 3):

Aha Moment: Quadtree cho 100M businesses chi chiem khoang 843 MB RAM — thoai mai fit trong 1 server co 8 GB RAM. Day la ly do nhieu he thong chon Quadtree lam in-memory geospatial index.

Tom tat Estimation

MetricValue
Search QPS (peak)~60K/s
Write QPS (peak)~5/s
Business data storage~600 GB
Geospatial index size~3.6 GB
Cache size (hot data)~120 GB
Quadtree memory~843 MB
Read:Write ratio~60,000:1

Step 2 — High-Level Design

2.1 Kien truc tong quan — 2 Service chinh

Proximity Service bao gom 2 loai service co dac tinh hoan toan khac nhau:

ServiceChuc nangDac tinhScale strategy
LBS (Location-Based Service)Nhan toa do + radius, tra ve businesses gan nhatRead-heavy, stateless, no writeHorizontal scaling, read replicas
Business ServiceCRUD operations cho businessesWrite operations, low QPSSingle primary + replicas

Tai sao tach 2 service? Vi read va write co pattern hoan toan khac nhau:

  • LBS: 60K QPS, stateless, can low latency → scale horizontally, dat sau Load Balancer
  • Business Service: 5 QPS, stateful, can consistency → single primary database

Principle: Tach read path va write path khi chung co scale requirements khac nhau. Day la CQRS (Command Query Responsibility Segregation) pattern — mot dang cua Tuan-11-Microservices-Pattern.

2.2 High-Level Architecture Diagram

flowchart TB
    subgraph Clients
        Mobile["Mobile App"]
        Web["Web App"]
    end

    LB["Load Balancer<br/>→ [[Tuan-05-Load-Balancer]]"]

    subgraph "Read Path (LBS)"
        LBS1["LBS Instance 1"]
        LBS2["LBS Instance 2"]
        LBSN["LBS Instance N"]
    end

    subgraph "Write Path"
        BS["Business Service"]
    end

    subgraph "Data Layer"
        Primary["Primary DB<br/>PostgreSQL"]
        R1["Read Replica 1"]
        R2["Read Replica 2"]
        RN["Read Replica N"]
    end

    subgraph "Geospatial Index"
        GI["Geohash Index<br/>(in DB read replicas)"]
        QT["Quadtree<br/>(in-memory, per LBS instance)"]
    end

    subgraph "Cache Layer"
        RC["Redis Cluster<br/>Business data cache<br/>Geohash → business_ids cache"]
    end

    Mobile --> LB
    Web --> LB
    LB -->|"GET /nearby"| LBS1 & LBS2 & LBSN
    LB -->|"POST/PUT/DELETE /businesses"| BS

    LBS1 & LBS2 & LBSN --> RC
    LBS1 & LBS2 & LBSN --> R1 & R2 & RN
    LBS1 & LBS2 & LBSN -.-> QT

    BS --> Primary
    Primary -->|"Replication"| R1 & R2 & RN

    R1 & R2 & RN --> GI

    style LB fill:#42a5f5,color:#fff
    style RC fill:#ef5350,color:#fff
    style Primary fill:#66bb6a,color:#fff
    style QT fill:#ffa726,color:#000

2.3 API Design

Search Nearby Businesses:

FieldTypeDescription
GET /v1/search/nearby
latitudedoubleVi do cua user (-90 den 90)
longitudedoubleKinh do cua user (-180 den 180)
radiusintBan kinh search (meters). Default: 5000. Max: 20000
categorystring(Optional) Filter theo loai business
page_tokenstring(Optional) Pagination token

Response:

FieldTypeDescription
businessesarrayDanh sach businesses
businesses[].idstringBusiness ID
businesses[].namestringTen business
businesses[].latdoubleVi do
businesses[].lngdoubleKinh do
businesses[].distanceintKhoang cach (meters)
businesses[].ratingfloatRating trung binh
next_page_tokenstringToken cho trang tiep theo

Business CRUD:

EndpointMethodDescription
/v1/businessesPOSTTao business moi
/v1/businesses/:idGETXem chi tiet business
/v1/businesses/:idPUTCap nhat business
/v1/businesses/:idDELETEXoa business

2.4 Data Flow — Read vs Write

Read Flow (Search):

1. User gui request GET /v1/search/nearby?lat=10.77&lng=106.70&radius=5000
2. Load Balancer route den 1 trong N LBS instances
3. LBS tinh geohash tu (lat, lng) va radius → xac dinh cac geohash cells can query
4. LBS check Redis cache: geohash_cells → list of business_ids
5. Neu cache hit → lay business details tu Business Data Cache
6. Neu cache miss → query Read Replica (geospatial index table)
7. Tinh khoang cach chinh xac, loc businesses ngoai radius
8. Sap xep theo distance, tra ve ket qua

Write Flow (Update Business):

1. Business owner gui PUT /v1/businesses/123
2. Load Balancer route den Business Service
3. Business Service update Primary DB
4. Primary DB replicate sang Read Replicas (async)
5. Cache invalidation: xoa cache entries lien quan
6. Neu dung Quadtree: rebuild scheduled (overnight hoac moi vai gio)

Trade-off: Business updates khong phan anh ngay lap tuc trong search results. Delay co the la vai phut (replication lag) den vai gio (quadtree rebuild). Day la chap nhan duoc vi businesses hiem khi thay doi vi tri.


Step 3 — Design Deep Dive

3.1 Bai toan cot loi: Geospatial Indexing

Hieu, day la phan kho nhat va quan trong nhat cua bai nay. Bai toan co ban la:

Cho diem P(lat, lng) va ban kinh r, tim tat ca businesses B sao cho distance(P, B) r.

Cach naive — Two-dimensional search:

Cach don gian nhat: query truc tiep trong database.

SELECT * FROM businesses
WHERE latitude BETWEEN 10.77 - delta AND 10.77 + delta
  AND longitude BETWEEN 106.70 - delta AND 106.70 + delta

Van de: Ngay ca khi co index tren latitude VA index tren longitude, database phai:

  1. Query index tren latitude → tap A (co the hang trieu records)
  2. Query index tren longitude → tap B (co the hang trieu records)
  3. Lay giao (intersection) A ∩ B → rat cham!

Ly do: B-tree index chi hieu qua cho 1 chieu. Khi co 2 chieu doc lap (lat, lng), khong co B-tree nao co the index ca 2 dong thoi mot cach hieu qua.

Day la ly do ta can geospatial indexing — cac ky thuat chuyen biet de bien bai toan 2 chieu thanh bai toan 1 chieu hoac chia khong gian thanh cac o (cells) de thu hep pham vi search.

3.2 Approach 1 — Evenly Divided Grid

Y tuong: Chia toan bo ban do thanh cac o (cells) co kich thuoc bang nhau. Moi business thuoc ve dung 1 cell. Khi search, chi can tim cac businesses trong cell hien tai va cac cells lan can.

Van de nghiem trong:

Van deGiai thich
Distribution khong deuTokyo co the co 100,000 businesses trong 1 cell, nhung Sahara co 0
Fixed granularityKhong the adaptive — vung dong duc can grid nho hon, vung thua can grid lon hon
Qua nhieu empty cells70% Trai Dat la nuoc → 70% cells rong
Edge casesBusiness o sat ranh gioi cell → search can check nhieu cells

Ket luan: Evenly divided grid khong phu hop cho du lieu phan bo khong deu. Ta can cach tiep can thong minh hon.

3.3 Approach 2 — Geohash (Core Approach)

3.3.1 Geohash la gi?

Geohash la ky thuat bien toa do 2 chieu (lat, lng) thanh 1 chuoi string duy nhat bang cach chia doi xen ke (interleaving) latitude va longitude.

Quy trinh encoding (simplified):

Buoc 1 — Encode Longitude:

  • Bat dau voi khoang [-180, 180]
  • Chia doi: neu lng nam ben trai ([-180, 0]) → bit 0, ben phai ([0, 180]) → bit 1
  • Lap lai, chia doi tiep khoang duoc chon
  • Vi du: lng = 106.70 → [0, 180] → 1, [90, 180] → 1, [90, 135] → 1, [101.25, 112.5] → 1, …

Buoc 2 — Encode Latitude:

  • Tuong tu, bat dau voi [-90, 90]
  • Vi du: lat = 10.77 → [0, 90] → 1, [0, 45] → 0, [0, 22.5] → 0, …

Buoc 3 — Interleave Bits:

  • Xen ke: bit lon[0], bit lat[0], bit lon[1], bit lat[1], …
  • Ket qua la 1 chuoi bits

Buoc 4 — Encode thanh Base32:

  • Nhom 5 bits → 1 ky tu Base32 (0-9, b-z loai tru a, i, l, o)
  • Vi du: toa do TP.HCM (10.7769, 106.7009) → geohash: w3gvk1

3.3.2 Precision Levels — Do chinh xac

Geohash LengthCell WidthCell HeightSu dung
15,009 km4,992 kmToan bo luc dia
21,252 km624 kmQuoc gia nho
3156 km156 kmTinh / state
439.1 km19.5 kmThanh pho lon
54.89 km4.89 kmQuan / district
61.22 km0.61 kmKhu vuc nho — phu hop cho proximity search
7153 m153 mDuong pho
838.2 m19.1 mToa nha
94.77 m4.77 mPhong trong toa nha
123.7 cm1.8 cmDo chinh xac GPS max

Rule of thumb cho proximity search: Radius 5km → dung geohash length 5 (cell ~4.89 km). Radius 1km → dung geohash length 6 (cell ~1.22 km).

3.3.3 Mapping Radius to Geohash Precision

RadiusGeohash PrecisionGiai thich
0.5 km6Cell 1.22km, can check cell hien tai + 8 neighbors
1 km5Cell 4.89km du cover
2 km5Cell 4.89km du cover
5 km4Cell 39.1km — du rong, co the tra ve qua nhieu ket qua
20 km4Cell 39.1km cover duoc

Chien luoc thuc te: Chon precision level sao cho cell size >= radius va query cell hien tai + 8 cells lan can (tong cong 9 cells). Dieu nay dam bao cover toan bo vung tron search.

3.3.4 Tinh chat quan trong cua Geohash

Tinh chat 1 — Shared prefix = Nearby (thuong la dung):

Hai diem co geohash chia se prefix cang dai → cang gan nhau.

Diem ADiem BShared prefixKhoang cach xap xi
w3gvk1w3gvk9w3gvk (5 chars)< 5 km
w3gvk1w3gvm2w3gv (4 chars)< 40 km
w3gvk1w3h001w3 (2 chars)< 1,252 km

Tinh chat 2 — Neighbor lookup:

Moi geohash cell co chinh xac 8 neighbors (tren, duoi, trai, phai, 4 goc). Co the tinh neighbors bang algorithm hieu qua trong O(1).

3.3.5 Edge Cases — Nhung truong hop dac biet

Edge Case 1 — Khac prefix nhung rat gan (Boundary Problem):

┌──────────┬──────────┐
│          │          │
│  w3gvk   │  w3gvm   │
│          │          │
│        A ● ● B     │
│          │          │
└──────────┴──────────┘

Diem A (w3gvk...) va B (w3gvm...) o 2 cells khac nhau — prefix khac hoan toan tu ky tu thu 5. Nhung thuc te chung chi cach nhau 50 met!

Giai phap: Luon query cell hien tai + 8 cells lan can. Dieu nay dam bao khong bo sot cac businesses o ranh gioi cell.

Edge Case 2 — Cung prefix nhung xa (Rare case):

Do cach Hilbert/Z-curve map 2D → 1D, co nhung truong hop 2 cells co cung prefix nhung khong thuc su lan can ve mat dia ly. Vi du: 2 cells o 2 ben cua duong ranh gioi encoding.

Giai phap: Sau khi lay danh sach businesses tu geohash cells, luon tinh khoang cach thuc te (Haversine formula) va loc bo nhung businesses ngoai radius.

Trong do = ban kinh Trai Dat (6,371 km), = latitude (radians), = longitude (radians).

Edge Case 3 — Khong du businesses trong radius:

Khi search radius = 1km nhung chi co 2 businesses, user co the muon xem them. Chien luoc mo rong radius:

1. Search voi geohash precision tuong ung radius ban dau
2. Neu ket qua < min_results (vi du: 10)
3. Giam geohash precision 1 bac (mo rong vung search ~4x)
4. Search lai
5. Lap lai cho den khi du ket qua hoac dat max_radius

3.4 Approach 3 — Quadtree (Adaptive Grid)

3.4.1 Quadtree la gi?

Quadtree la cau truc du lieu hinh cay, trong do moi node co the co 0 hoac 4 children. No tu dong chia nho vung co nhieu businesses va giu nguyen vung it businesses.

Nguyen tac: Chia khong gian 2D thanh 4 phan. Neu 1 phan co nhieu hon K businesses (threshold, vi du K=100), tiep tuc chia phan do thanh 4. Lap lai cho den khi moi o co K businesses.

3.4.2 Quy trinh Build Quadtree

Bat dau: Toan bo ban do la 1 node
  - Node chua 5,000,000 businesses (> threshold 100) → SPLIT

Node chia thanh 4 children:
  NW (Northwest): 1,200,000 businesses → SPLIT
  NE (Northeast): 2,500,000 businesses → SPLIT
  SW (Southwest): 800,000 businesses → SPLIT
  SE (Southeast): 500,000 businesses → SPLIT

Tiep tuc chia cho den khi moi leaf node co <= 100 businesses

Dac diem quan trong:

Dac diemGiai thich
AdaptiveVung Tokyo (dong duc) co cell nho ~100m. Vung Sahara co cell lon ~1000km
In-memoryToan bo tree nam trong RAM — query cuc nhanh
Build timeBuild 1 lan khi server khoi dong, hoac rebuild dinh ky
Not easily shareableMoi server giu 1 ban copy cua tree — khong chia se qua network

3.4.3 Quadtree Structure — Chi tiet Node

Internal Node (node co children):

FieldSizeGiai thich
Top-left coordinates16 bytes(lat, lng) goc tren trai
Bottom-right coordinates16 bytes(lat, lng) goc duoi phai
Pointer to NW child8 bytes
Pointer to NE child8 bytes
Pointer to SW child8 bytes
Pointer to SE child8 bytes
Total64 bytes

Leaf Node (node chua businesses):

FieldSizeGiai thich
Top-left coordinates16 bytesRanh gioi vung
Bottom-right coordinates16 bytesRanh gioi vung
List of business_ids8 bytes x NN threshold (100)
Total32 + 8N bytesVoi N=100: ~832 bytes

3.4.4 Memory Estimation (Chi tiet)

Quadtree la full 4-ary tree. Tong so internal nodes:

Key insight: 853 MB — mot server voi 8 GB RAM co the chua thoai mai. Khong can distributed index! Day la dieu nhieu ung vien interview khong nhan ra.

3.4.5 Build Time Estimation

Voi may tinh hien dai xu ly ~1 billion operations/second, build time khoang vai phut. Co the chap nhan cho startup time.

3.4.6 Quadtree Search Algorithm

Tim businesses trong radius R tu diem P(lat, lng):

1. Bat dau tu root node
2. Tim leaf node chua diem P (traverse tree theo toa do)
3. Tinh khoang cach tu P den moi business trong leaf node do
4. Neu vong tron (P, R) overlap voi cac neighboring cells:
   - Traverse len parent, check cac sibling nodes
   - Lap lai cho den khi vong tron duoc cover hoan toan
5. Loc businesses co distance > R
6. Sap xep theo distance, tra ve top N

Trong do = so businesses trong vung search. Voi :

3.4.7 Update Strategy cho Quadtree

Van de: Businesses thay doi (them moi, dong cua, doi dia chi) — lam sao update Quadtree?

Option 1 — Rebuild dinh ky (Recommended):

AspectDetail
FrequencyMoi vai gio hoac overnight
ProcessBuild quadtree moi tu database, swap voi tree cu (atomic swap)
DowntimeZero — tree cu van serve requests trong khi tree moi dang build
Phù hop khiBusiness data thay doi cham (hang ngay), khong can real-time

Option 2 — Incremental update:

AspectDetail
ProcessThem/xoa business truc tiep trong tree
ComplexityCao — can handle split/merge khi node vuot threshold
Phù hop khiData thay doi thuong xuyen (vi du: driver locations trong Uber)

Cho bai toan Proximity Service (businesses), Option 1 la du vi businesses hiem khi thay doi vi tri.

3.5 Approach 4 — Google S2 Geometry Library

3.5.1 S2 la gi?

Google S2 la thu vien chuyen dung do Google phat trien, su dung Hilbert curve de map be mat hinh cau (Trai Dat) thanh cac S2 cells.

Diem khac biet voi Geohash:

FeatureGeohashS2
Hinh dang cellHinh chu nhat tren ban doHinh thoi (rhombus) tren hinh cau
Mo hinh Trai DatPhang (flat projection)Hinh cau (sphere)
Curve typeZ-order curveHilbert curve
Cell levels1-12 (base32 chars)0-30 (64-bit integer)
Do chinh xacTot, co boundary issuesTot hon — Hilbert curve bao toan locality tot hon
Region coveringManual (9 cells)Tu dong — S2RegionCoverer tim toi uu cells

3.5.2 Hilbert Curve — Tai sao tot hon Z-curve?

Z-curve (Geohash) co van de “jumps” — doi khi 2 cells ke nhau tren ban do lai xa nhau tren Z-curve. Dieu nay gay ra cac boundary issues.

Hilbert curve dam bao: 2 diem gan nhau tren curve hau nhu luon gan nhau trong khong gian 2D. Tinh chat nay goi la locality-preserving — tot hon Z-curve dang ke.

3.5.3 S2 trong thuc te

CompanySu dung S2 cho
Google MapsCore geospatial indexing
Uber H3Inspired by S2, dung hexagonal cells
FoursquarePlace detection
MongoDB2dsphere index su dung S2 internally

3.6 So sanh Geohash vs Quadtree vs S2

Tieu chiGeohashQuadtreeS2
Do phuc tap implementThap — chi la string operationTrung binh — can build treeCao — can S2 library
StorageTrong database (column)In-memory tren moi serverTrong database (column)
UpdateUpdate database recordRebuild treeUpdate database record
Adaptive densityKhong — fixed grid sizeCo — tu dong chia nho vung dong ducCo — S2RegionCoverer
Precision control12 levels (base32)Vo han (chia cho den khi du)31 levels (0-30)
Boundary issuesCo — can query 8 neighborsIt — tree structure handle tu nhienIt nhat — Hilbert curve
DistributedDe — geohash la string, index binh thuongKho — tree phai o 1 serverDe — S2 cell ID la integer
Database supportRedis, PostgreSQL, MySQL, DynamoDBPhai tu implementMongoDB (native), PostgreSQL (extension)
Phu hop choHau het use cases, don gianDataset lon, can adaptive, in-memory okGoogle-scale, hinh cau chinh xac

Recommendation cho interview: Chon Geohash lam primary approach (de giai thich, database support tot). Nhac den Quadtree nhu alternative khi interviewer hoi ve adaptive density. Nhac den S2 de show depth of knowledge.

3.7 Database Schema Design

3.7.1 Business Table

ColumnTypeDescriptionIndex
business_idUUID (PK)ID duy nhatPrimary Key
nameVARCHAR(255)Ten businessFull-text index
addressTEXTDia chi
cityVARCHAR(100)Thanh pho
countryVARCHAR(2)Ma quoc gia (ISO 3166)
latitudeDOUBLEVi do
longitudeDOUBLEKinh do
categoryVARCHAR(50)Loai businessIndex
ratingDECIMAL(2,1)Rating trung binh
phoneVARCHAR(20)So dien thoai
hoursJSONBGio mo cua
photosJSONBURLs anh
created_atTIMESTAMP
updated_atTIMESTAMPIndex

3.7.2 Geospatial Index Table (Geohash approach)

ColumnTypeDescriptionIndex
geohashVARCHAR(12)Geohash cua businessPrimary prefix index
business_idUUIDFK to business table
latitudeDOUBLEDe tinh khoang cach chinh xac
longitudeDOUBLEDe tinh khoang cach chinh xac

Index Strategy: Tao compound index tren (geohash, business_id). Khi query, dung prefix search:

-- Tim businesses trong geohash cell "w3gvk" va cac neighbors
WHERE geohash LIKE 'w3gvk%'
   OR geohash LIKE 'w3gvm%'
   OR geohash LIKE 'w3gvj%'
   ... (tong 9 cells)

Optimization: Thay vi 9 queries rieng biet, dung IN clause hoac UNION ALL de batch thanh 1 query.

3.7.3 Database Architecture — Read Replicas

flowchart LR
    subgraph "Write Path"
        BS["Business Service"]
        Primary["Primary DB<br/>PostgreSQL"]
    end

    subgraph "Read Path"
        LBS["LBS Instances"]
        R1["Read Replica 1<br/>US-West"]
        R2["Read Replica 2<br/>US-East"]
        R3["Read Replica 3<br/>EU-West"]
        R4["Read Replica 4<br/>AP-Southeast"]
    end

    BS --> Primary
    Primary -->|"Async Replication"| R1 & R2 & R3 & R4
    LBS --> R1 & R2 & R3 & R4

    style Primary fill:#66bb6a,color:#fff
    style R1 fill:#42a5f5,color:#fff
    style R2 fill:#42a5f5,color:#fff
    style R3 fill:#42a5f5,color:#fff
    style R4 fill:#42a5f5,color:#fff

Tai sao Read Replicas theo region? Vi LBS la read-heavy (60K QPS peak). Moi region co read replicas rieng → giam latency (user o Singapore query replica o Singapore, khong phai di qua US). Tham chieu Tuan-07-Database-Sharding-Replication.

3.8 Caching Strategy

3.8.1 Cache Architecture

Su dung 2 lop cache:

Cache Layer 1 — Geohash to Business IDs:

KeyValueTTLGiai thich
geo:w3gvk:restaurant[id1, id2, id3, ...]1 hourDanh sach business IDs trong geohash cell + category
geo:w3gvk:*[id1, id2, ...]1 hourTat ca businesses trong cell (khong filter category)

Cache Layer 2 — Business Details:

KeyValueTTLGiai thich
biz:uuid-123{name, lat, lng, rating, ...}24 hoursChi tiet business

3.8.2 Cache Flow

Search request: lat=10.77, lng=106.70, radius=5000, category=restaurant

1. Tinh geohash: w3gvk (precision 5)
2. Tinh 8 neighbors: w3gvm, w3gvj, w3gvh, w3gvs, w3gvt, w3gve, w3gv7, w3gv6
3. Voi moi geohash cell:
   a. Check Redis: GET geo:w3gvk:restaurant
   b. Cache HIT → nhan list business_ids
   c. Cache MISS → query Read Replica → set cache
4. Merge tat ca business_ids tu 9 cells
5. Voi moi business_id:
   a. Check Redis: GET biz:uuid-123
   b. Cache HIT → nhan business details
   c. Cache MISS → query Read Replica → set cache
6. Tinh distance, filter, sort, return

3.8.3 Cache Invalidation

EventActionLy do
Business update (name, hours, rating)Invalidate biz:{id}Chi tiet thay doi
Business move (lat/lng thay doi)Invalidate biz:{id} + geo:{old_hash}:* + geo:{new_hash}:*Vi tri thay doi → geohash cell thay doi
Business deletedInvalidate biz:{id} + geo:{hash}:*Xoa khoi tat ca cache
TTL expiryTu dongSafety net

Tham chieu Tuan-06-Cache-Strategy cho cac pattern cache invalidation chi tiet.

3.9 Scaling Strategy

3.9.1 LBS — Stateless Horizontal Scaling

LBS instances la stateless (khong giu state nao). Moi request co the duoc xu ly boi bat ky instance nao.

Dat sau Load Balancer (Tuan-05-Load-Balancer), su dung round-robin hoac least-connections.

Neu dung Quadtree: Moi LBS instance giu 1 ban copy cua Quadtree trong memory. Khi scale them instance → instance moi build Quadtree tu database khi khoi dong (vai phut). Sau do serve requests binh thuong.

3.9.2 Database — Read Replicas per Region

RegionRead ReplicasLy do
US-West3California, tech hub
US-East3New York, Washington DC
EU-West2London, Paris
AP-Southeast3Singapore, TP.HCM, Jakarta — high density
AP-Northeast2Tokyo, Seoul

PostgreSQL co the handle 10K+ simple reads/s → 4.6K QPS per replica la thoai mai.

3.9.3 Cache — Redis Cluster

Su dung Redis Cluster voi sharding theo geohash prefix. Tat ca keys voi geohash bat dau “w3” (Vietnam) se o cung shard → locality tot cho cache.


Query Flow — End to End

sequenceDiagram
    participant U as User (Mobile)
    participant LB as Load Balancer
    participant LBS as LBS Instance
    participant Cache as Redis Cache
    participant DB as Read Replica

    U->>LB: GET /v1/search/nearby<br/>lat=10.77, lng=106.70, radius=5000

    LB->>LBS: Route to LBS Instance

    Note over LBS: 1. Tinh geohash: w3gvk (precision 5)
    Note over LBS: 2. Tinh 8 neighbors

    loop Cho moi 9 geohash cells
        LBS->>Cache: GET geo:w3gvk:*
        alt Cache HIT
            Cache-->>LBS: [business_id_1, business_id_2, ...]
        else Cache MISS
            LBS->>DB: SELECT business_id FROM geo_index<br/>WHERE geohash LIKE 'w3gvk%'
            DB-->>LBS: [business_id_1, business_id_2, ...]
            LBS->>Cache: SET geo:w3gvk:* (TTL 1h)
        end
    end

    Note over LBS: 3. Merge business_ids tu 9 cells

    loop Cho moi business_id
        LBS->>Cache: GET biz:{id}
        alt Cache HIT
            Cache-->>LBS: {name, lat, lng, rating, ...}
        else Cache MISS
            LBS->>DB: SELECT * FROM businesses<br/>WHERE id = ?
            DB-->>LBS: {name, lat, lng, rating, ...}
            LBS->>Cache: SET biz:{id} (TTL 24h)
        end
    end

    Note over LBS: 4. Tinh Haversine distance
    Note over LBS: 5. Filter distance > radius
    Note over LBS: 6. Sort by distance

    LBS-->>LB: {businesses: [...], next_page_token: ...}
    LB-->>U: 200 OK

Geohash Grid Visualization

graph TB
    subgraph "Geohash Grid — TP.HCM Area (Precision 5)"
        subgraph row1[""]
            C1["w3gv6<br/>0 biz"]
            C2["w3gv7<br/>12 biz"]
            C3["w3gve<br/>5 biz"]
        end
        subgraph row2[""]
            C4["w3gvj<br/>45 biz"]
            C5["w3gvk<br/>●USER<br/>78 biz"]
            C6["w3gvm<br/>23 biz"]
        end
        subgraph row3[""]
            C7["w3gvh<br/>8 biz"]
            C8["w3gvs<br/>156 biz"]
            C9["w3gvt<br/>34 biz"]
        end
    end

    style C5 fill:#ff9800,color:#000,stroke:#e65100,stroke-width:3px
    style C4 fill:#c8e6c9
    style C6 fill:#c8e6c9
    style C8 fill:#c8e6c9
    style C2 fill:#c8e6c9
    style C1 fill:#e8eaf6
    style C3 fill:#e8eaf6
    style C7 fill:#e8eaf6
    style C9 fill:#e8eaf6

User o cell w3gvk. He thong query cell nay + 8 neighbors (tong 9 cells, 361 businesses). Sau do tinh khoang cach thuc va loc.


Quadtree Structure Visualization

graph TD
    Root["ROOT<br/>Toan bo ban do<br/>100M businesses"]

    Root --> NW["NW<br/>North America<br/>25M biz"]
    Root --> NE["NE<br/>Europe + Africa<br/>20M biz"]
    Root --> SW["SW<br/>South America<br/>5M biz"]
    Root --> SE["SE<br/>Asia + Oceania<br/>50M biz"]

    SE --> SE_NW["SE-NW<br/>East Asia<br/>20M biz"]
    SE --> SE_NE["SE-NE<br/>Pacific<br/>2M biz"]
    SE --> SE_SW["SE-SW<br/>Southeast Asia<br/>18M biz"]
    SE --> SE_SE["SE-SE<br/>Oceania<br/>10M biz"]

    SE_SW --> VN1["VN-North<br/>Ha Noi area<br/>500K biz"]
    SE_SW --> VN2["VN-South<br/>TP.HCM area<br/>800K biz"]
    SE_SW --> TH["Thailand<br/>1.2M biz"]
    SE_SW --> ID["Indonesia<br/>2M biz"]

    VN2 --> D1["Quan 1<br/>5K biz"]
    VN2 --> D2["Quan 7<br/>3K biz"]
    VN2 --> D3["Thu Duc<br/>2K biz"]
    VN2 --> D4["Binh Thanh<br/>4K biz"]

    D1 --> L1["Block A<br/>95 biz ✓"]
    D1 --> L2["Block B<br/>78 biz ✓"]
    D1 --> L3["Block C<br/>88 biz ✓"]
    D1 --> L4["Block D<br/>62 biz ✓"]

    style Root fill:#e53935,color:#fff
    style SE fill:#ff9800,color:#000
    style SE_SW fill:#ffc107,color:#000
    style VN2 fill:#66bb6a,color:#fff
    style D1 fill:#42a5f5,color:#fff
    style L1 fill:#a5d6a7,stroke:#388e3c
    style L2 fill:#a5d6a7,stroke:#388e3c
    style L3 fill:#a5d6a7,stroke:#388e3c
    style L4 fill:#a5d6a7,stroke:#388e3c

Leaf nodes (mau xanh la) chua 100 businesses. Vung dong duc (Quan 1 TP.HCM) co cells nho. Vung thua (Pacific Ocean) co cells lon. Day la suc manh cua adaptive grid.


4. Security

4.1 Location Privacy — Bao ve vi tri nguoi dung

Moi deGiai phapChi tiet
Location fuzzingLam mo toa do GPS truoc khi logThem noise ±100-500m vao toa do truoc khi luu vao analytics/logs. User thuc nhan ket qua chinh xac, nhung server logs chi luu vi tri xap xi
AggregationChi luu aggregated dataThay vi log “User A o toa do X luc 14:00”, log “50 users search khu vuc geohash w3gvk luc 14:00-15:00”
Retention policyXoa location data sau thoi gian nhat dinhRaw GPS coordinates xoa sau 30 ngay. Chi giu aggregated stats
User consentHoi quyen truoc khi truy cap GPSMobile OS (iOS/Android) bat buoc hoi permission. Backend phai ton trong “While Using” vs “Always”
Encryption in transitTLS 1.3 cho moi requestToa do truyen qua HTTPS, khong bao gio HTTP

4.2 Rate Limiting on Location Queries

TierLimitLy do
Per user30 requests/minuteNguoi binh thuong search ~5 lan/phut max
Per IP100 requests/minuteCho shared networks (co-working spaces)
Per API key (business)1,000 requests/minuteCho third-party integrations
Burst allowance2x limit trong 10 giayCho phep burst ngan khi user scroll ban do nhanh

Su dung Token Bucket algorithm. Tham chieu Tuan-09-Rate-Limiter.

4.3 Chong Data Scraping tu Doi thu

Moi de: Doi thu co the viet bot de scrape toan bo danh sach businesses va toa do tu API.

Bien phapChi tiet
API key requiredMoi client can API key. Revoke key neu phat hien scraping pattern
Pagination limitToi da 20 results per page, toi da 100 pages per session
Honeypot businessesChen fake businesses (chi visible qua API, khong hien tren UI). Neu doi thu hien thi honeypot → co bang chung scraping
Request pattern analysisPhat hien: systematic grid scanning (search moi 1km tren toan thanh pho), unusual QPS, sequential page requests
CAPTCHATrigger CAPTCHA sau 50 searches lien tiep khong co user interaction
Response watermarkingChen metadata an vao response (user ID, timestamp) de trace nguon leak

4.4 GDPR Compliance cho Location Data

Yeu cau GDPRImplementation
Right to be forgottenUser yeu cau xoa → xoa tat ca location history, search history, cached data
Data portabilityExport location history dang JSON/CSV khi user yeu cau
Purpose limitationLocation data chi dung cho search nearby — khong ban cho third-party advertising
Data minimizationChi luu toa do khi can thiet. Khong luu location history cho tinh nang search (chi can real-time)
ConsentExplicit opt-in cho location tracking. Granular permissions: “Chi khi dang dung app”
Data Processing AgreementVoi cloud provider (AWS/GCP) — dam bao data o region phu hop (EU data o EU region)

5. DevOps & Monitoring

5.1 Key Metrics to Monitor

5.1.1 Search Latency by Region

MetricAlert ThresholdDashboard
search_latency_p50 by region> 50msTime series, group by region
search_latency_p99 by region> 200msTime series, group by region
search_latency_p99 global> 500msSingle number, red/green
search_error_rate> 0.1%Percentage gauge

Tai sao by region? Vi latency phu thuoc vao: khoang cach den read replica, business density (vung dong duc tra ve nhieu ket qua hon → cham hon), va cache hit ratio.

5.1.2 Cache Performance

MetricAlert ThresholdY nghia
cache_hit_ratio_geo (geohash → business_ids)< 90%Cache khong hieu qua → check TTL, check neu co geohash precision thay doi
cache_hit_ratio_biz (business details)< 95%Business data it thay doi, cache hit phai cao
cache_eviction_rate> 1000/sRedis het memory → can them node
cache_latency_p99> 5msRedis cham → check network, check memory fragmentation

Cache Hit Ratio by Geohash Precision:

PrecisionExpected Hit RatioGiai thich
4 (39km cells)98%+Cell lon → nhieu user search cung cell → cache warm
5 (4.9km cells)95%+Pho bien nhat — balance giua granularity va cache efficiency
6 (1.2km cells)85-90%Cell nho → nhieu cells → cache cold cho cells it search
7 (153m cells)70-80%Qua granular cho proximity search → khong khuyen nghi

5.1.3 Database Replication Lag

MetricAlert ThresholdImpact
replication_lag_seconds per replica> 30sBusiness updates cham hien thi
replication_lag_seconds max> 300s (5 min)Can investigate — replica co the bi stuck
replica_connections< expectedReplica bi disconnect → data stale

Tham chieu Tuan-07-Database-Sharding-Replication cho chi tiet ve replication monitoring.

5.1.4 Quadtree Health (neu su dung)

MetricAlert ThresholdY nghia
quadtree_build_time_seconds> 600 (10 min)Build cham → data tang hoac server cham
quadtree_memory_bytes> 2 GBTree lon bat thuong → check data quality
quadtree_last_build_timestamp> 6 hours agoQuadtree outdated → trigger rebuild
quadtree_max_depth> 20Co the co du lieu bat thuong (nhieu businesses cung toa do)

5.2 Deployment Strategy

AspectStrategyLy do
LBS instancesRolling updateStateless → co the update tung instance
Quadtree rebuildBlue-greenBuild tree moi, swap khi xong. Zero downtime
Database schema migrationOnline DDL (pt-online-schema-change)Khong lock table
Cache warmingPre-warm after deployScript query top geohash cells de warm cache
Canary deployment5% traffic truocPhat hien van de som truoc khi rollout 100%

5.3 Alerting Rules

AlertConditionSeverityAction
High search latencyp99 > 500ms for 5 minP1On-call investigate, check DB/cache
Cache cluster down> 1 node unreachable for 2 minP1Auto-failover, page on-call
Replication lag high> 5 min for any replicaP2Check replica health, network
Quadtree build failedBuild process crashedP2Serve voi tree cu, investigate
Error rate spike> 1% for 3 minP1Check recent deploy, rollback if needed
Scraping detected> 500 sequential searches from 1 IPP3Auto rate limit, review

Tham chieu Tuan-13-Monitoring-Observability cho alerting best practices.


6. Aha Moments & Pitfalls

6.1 Aha Moments — Nhung dieu bat ngo

Aha 1: Geohash Boundary Problem

Van de: Hai quan pho cach nhau 50m nhung o 2 geohash cells khac nhau. Neu chi query 1 cell → bo sot ket qua.

Giai phap: Luon query 9 cells (cell hien tai + 8 neighbors). Chi phi: 9x queries thay vi 1x. Nhung voi cache, chi phi nay giam dang ke.

Tui interview: Neu interviewer hoi “geohash co van de gi?”, PHAI nhac den boundary problem va giai phap 9-cell query. Day la diem phan biet ung vien trung binh va ung vien tot.

Aha 2: Quadtree fit trong 1 server

100 trieu businesses, quadtree chi chiem ~853 MB RAM. Mot server co 16 GB RAM du suc giu ca tree. Khong can distributed index.

Y nghia: Khi interviewer goi y “lam sao distribute quadtree across servers?”, cau tra loi dung la: khong can distribute. Moi LBS server giu 1 ban copy. Scale bang cach them server (moi server co full copy).

So sanh voi B-tree: Neu dung B-tree trong database, index cho 100M records co the chiem 10-20 GB (vi B-tree co overhead lon hon). Quadtree tiet kiem memory hon dang ke cho geospatial data.

Aha 3: Radius khong map 1-1 voi Geohash Precision

Khong co cong thuc chinh xac: radius = X → geohash precision = Y. Phai chon precision sao cho cell size >= radius, roi query 9 cells.

Vi du: Radius 2km. Cell precision 6 = 1.22km (nho hon radius) → khong du. Cell precision 5 = 4.89km (lon hon radius) → OK, nhung tra ve nhieu ket qua thua. Giai phap: dung precision 5, query 9 cells, roi filter bang Haversine distance.

Aha 4: Write path va Read path hoan toan tach biet

Proximity Service la mot trong nhung case study ro rang nhat cua CQRS pattern. Write QPS = 1-5, Read QPS = 60,000. Scale chung se lang phi tai nguyen.

Aha 5: Geohash la string → dung duoc voi moi database

Geohash chi la 1 chuoi string (vi du: “w3gvk1”). Co the luu trong bat ky database nao co string index: PostgreSQL, MySQL, DynamoDB, Redis, Cassandra. Khong can database dac biet.

6.2 Pitfalls — Nhung sai lam pho bien

Pitfall 1: Dung two-dimensional search truc tiep

“SELECT WHERE lat BETWEEN … AND lng BETWEEN …” — cham O(N) vi database khong the dung ca 2 index cung luc hieu qua.

Fix: Dung geospatial index (geohash, quadtree, hoac PostGIS).

Pitfall 2: Chi query 1 geohash cell

Bo qua boundary problem → mat ket qua o ranh gioi cell. Day la loi nghiem trong nhat khi implement geohash search.

Fix: Luon query cell hien tai + 8 neighbors.

Pitfall 3: Khong tinh Haversine distance sau khi query

Geohash query tra ve hinh vuong (hoac hinh chu nhat). Nhung user search theo vong tron (radius). Cac businesses o goc cua hinh vuong co the nam ngoai vong tron nhung van duoc tra ve.

Fix: Sau khi lay ket qua tu geohash cells, PHAI tinh Haversine distance va loc bo businesses ngoai radius.

Pitfall 4: Overcomplicate distributed Quadtree

Nhieu ung vien co gang distribute quadtree across servers. Khong can thiet — 853 MB fit trong 1 server. Complexity cua distributed tree khong dang.

Fix: Moi server giu full copy. Scale bang cach them servers.

Pitfall 5: Quen cache invalidation khi business di chuyen

Khi business thay doi toa do (vi du: food truck), geohash thay doi. Neu khong invalidate cache cu → user o vi tri cu van thay business do, user o vi tri moi khong thay.

Fix: Invalidate cache o CA HAI geohash cu va moi khi business update toa do.

Pitfall 6: Dung geohash precision qua cao

Precision 7 (153m cells) nghe co ve “chinh xac hon”. Nhung cell nho → can query nhieu cells hon de cover radius → nhieu queries hon → cham hon. Va cache hit ratio giam vi qua nhieu distinct cells.

Fix: Chon precision phu hop voi radius. Thuong la precision 4-6 cho hau het use cases.


7. Summary — Tom tat Decision Framework

7.1 Khi nao dung Geohash?

Tinh huongRecommendation
Database co san (PostgreSQL, MySQL)Geohash — chi can them 1 column
Can distributed indexGeohash — string column, dung duoc voi sharding
Team nho, can ship nhanhGeohash — don gian nhat
Data thay doi thuong xuyenGeohash — update record la xong

7.2 Khi nao dung Quadtree?

Tinh huongRecommendation
Can adaptive densityQuadtree — tu dong chia nho vung dong duc
Query in-memory la chap nhanQuadtree — cuc nhanh, O(log N)
Data it thay doi (businesses)Quadtree — rebuild dinh ky la du
Single region deploymentQuadtree — khong can distribute

7.3 Khi nao dung S2?

Tinh huongRecommendation
Can do chinh xac hinh cauS2 — tot nhat cho bai toan toan cau
Google-scaleS2 — proven at Google
MongoDB ecosystemS2 — native support (2dsphere)
Complex region queriesS2 — S2RegionCoverer toi uu

Kien thuc nen tang lien quan

TopicLinkAp dung trong Proximity Service
Cache StrategyTuan-06-Cache-StrategyGeohash cache, business data cache, invalidation patterns
Database Sharding & ReplicationTuan-07-Database-Sharding-ReplicationRead replicas per region, replication lag monitoring
Load BalancerTuan-05-Load-BalancerDistribute traffic across stateless LBS instances
Rate LimiterTuan-09-Rate-LimiterChong scraping, protect LBS tu traffic spikes
MonitoringTuan-13-Monitoring-ObservabilitySearch latency, cache hit ratio, replication lag alerts
Back-of-envelopeTuan-02-Back-of-the-envelopeQPS, storage, memory estimation
Microservices PatternTuan-11-Microservices-PatternCQRS — tach Read (LBS) va Write (Business Service)

So sanh voi cac Case Study khac

Case StudyDiem tuong dongDiem khac biet
Tuan-16-Design-URL-ShortenerRead-heavy, caching quan trongURL shortener khong co geospatial component
Tuan-18-Design-News-FeedFan-out pattern, cachingNews Feed la social graph, khong phai location
Tuan-20-Design-Key-Value-StoreIn-memory data structures, partitioningKV Store la general purpose, Proximity la domain-specific

9. Interview Cheat Sheet

Buoc 1 — Hoi Clarifying Questions (2-3 phut)

  • Scale: bao nhieu businesses? bao nhieu DAU?
  • Radius: user co chon radius khong? Max radius?
  • Real-time: business updates can hien thi ngay khong?
  • Features: search only? hay ca CRUD businesses?

Buoc 2 — High-level Design (5-7 phut)

  • Ve 2 services: LBS (read) + Business Service (write)
  • Ve database: Primary + Read Replicas
  • Nhac CQRS pattern
  • Ve cache layer (Redis)

Buoc 3 — Deep Dive (15-20 phut)

  • Giai thich geohash: encoding, precision levels, 9-cell query
  • Nhac boundary problem va giai phap
  • Quadtree nhu alternative: adaptive, in-memory, 853 MB
  • Database schema: business table + geospatial index table
  • Caching: 2-layer (geohash → IDs, ID → details)

Buoc 4 — Wrap Up (3-5 phut)

  • Scaling: LBS stateless → horizontal, DB read replicas per region
  • Monitoring: search latency, cache hit ratio, replication lag
  • Security: location privacy, rate limiting, anti-scraping

Cau hoi interviewer thuong hoi

Cau hoiCach tra loi
”Geohash vs Quadtree?”Geohash: distributed, database-friendly. Quadtree: adaptive, in-memory, faster query. Chon theo use case
”Geohash co van de gi?”Boundary problem — 2 diem gan nhau nhung khac cell. Fix: query 9 cells
”Quadtree co scale khong?“100M businesses chi 853 MB — moi server giu full copy. Scale horizontal
”Lam sao handle business updates?”CQRS: write vao Primary, async replicate. Quadtree rebuild dinh ky. Cache invalidation
”Lam sao giam latency?”Cache (2-layer), read replicas per region, geohash precision tuning

“Proximity Service la bai toan tuyet voi de hieu geospatial indexing — nen tang cua moi ung dung location-based. Khi em hieu cach bien bai toan 2 chieu thanh 1 chieu (geohash) hoac chia khong gian thong minh (quadtree), em co the ap dung cho bat ky bai toan location nao: tim tai xe, tim ban be, tim nha hang, hay tim bat ky thu gi tren ban do.”