Tại sao cần Surge Pricing?
Đêm Giao thừa, trời mưa lớn, tan ca giờ cao điểm — nhu cầu gọi xe tăng vọt nhưng số tài xế không đổi. Nếu giữ giá cố định:
- Khách đặt xe không được vì hết tài xế.
- Tài xế ở khu vực khác không có động lực di chuyển đến khu vực nóng.
- Hệ thống quá tải, khách chờ rất lâu.
Surge Pricing (hay Dynamic Pricing) không chỉ là công cụ tăng doanh thu — nó là cơ chế cân bằng thị trường (marketplace equilibrium mechanism):
Giá tăng → Hai tác động đồng thời:
1. CUNG TĂNG: Tài xế thấy khu vực đỏ (giá cao) trên heatmap
→ Di chuyển về khu vực đó để kiếm thêm tiền
→ Số tài xế tại khu vực tăng
2. CẦU GIẢM: Khách thấy giá cao → Một số chọn chờ, đi xe buýt,
hoặc đi bộ → Số request giảm bớt
→ Cung và cầu dần về trạng thái CÂN BẰNG
→ Thời gian chờ giảm cho những khách thực sự cần xe
Kiến trúc Surge Pricing Engine
┌────────────────────────────────────────────────────────────────┐
│ DATA PIPELINE │
│ │
│ Kafka Topic Flink Stream Processing │
│ "driver.location" ───► ┌────────────────────┐ │
│ "ride.requests" ───► │ Supply-Demand │ │
│ │ Aggregator │ │
│ │ (per H3 cell, │ │
│ │ 5-min window) │ │
│ └─────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ Pricing Engine │ │
│ │ (Surge Calculator) │ │
│ └─────────┬──────────┘ │
│ │ │
│ ┌─────────▼──────────┐ │
│ │ Redis Cache │ │
│ │ (Surge Multipliers) │ │
│ └─────────┬──────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ Rider App Driver App Matching Engine │
│ (Hiện giá) (Heatmap) (Weigh cost) │
└────────────────────────────────────────────────────────────────┘
Bước 1: Chia vùng bằng H3 (Geofencing)
Surge pricing không tính cho cả thành phố — nó tính cho từng ô lục giác H3 riêng biệt. Uber dùng Resolution 7 (mỗi ô ~5 km²), đủ lớn để có ý nghĩa thống kê nhưng đủ nhỏ để phản ánh tình hình cục bộ.
Thành phố Hồ Chí Minh chia thành ~200 ô H3 (Resolution 7)
Ô A (Quận 1 - Trung tâm): Supply=5, Demand=30 → Surge 3.2x
Ô B (Quận 7 - Phú Mỹ Hưng): Supply=20, Demand=15 → Surge 1.0x (bình thường)
Ô C (Sân bay Tân Sơn Nhất): Supply=8, Demand=40 → Surge 4.0x
Ô D (Quận 9 - Ngoại ô): Supply=12, Demand=3 → Surge 1.0x
Bước 2: Tính Surge Multiplier
Mô hình cơ bản: Supply-Demand Ratio
surge_multiplier = f(demand / supply)
Với:
supply = Số tài xế AVAILABLE trong H3 cell (5 phút gần nhất)
demand = Số ride requests trong H3 cell (5 phút gần nhất)
Ví dụ công thức đơn giản (minh họa):
ratio = demand / supply
if ratio <= 1.0: surge = 1.0 (giá bình thường)
if ratio == 2.0: surge = 1.5
if ratio == 3.0: surge = 2.0
if ratio >= 5.0: surge = 3.5 (cap tối đa)
Mô hình nâng cao: Machine Learning
Thực tế, Uber không dùng công thức tuyến tính đơn giản. Họ dùng ML models tính toán giá tối ưu dựa trên nhiều yếu tố:
| Input Feature | Ý nghĩa |
|---|---|
| Supply count | Số tài xế rảnh trong cell |
| Demand count | Số request trong sliding window |
| Historical patterns | Mẫu cung-cầu theo giờ/ngày trong tuần |
| Weather data | Trời mưa → demand tăng, supply giảm |
| Events | Có sự kiện lớn (concert, bóng đá)? |
| Conversion rate | Bao nhiêu % khách vẫn đặt ở mức giá surge hiện tại? |
| Neighboring cells | Surge ở các ô lân cận (hiệu ứng tràn) |
Feedback Loop — Ngăn Over-Pricing
Vòng phản hồi liên tục:
1. Surge = 3.0x → Nhiều khách huỷ (conversion rate giảm từ 70% → 30%)
2. Engine nhận ra: giá quá cao, khách bỏ đi
3. Giảm surge xuống 2.0x → Conversion rate phục hồi 60%
4. Đồng thời, tài xế đổ về (supply tăng) → ratio giảm
5. Surge tiếp tục giảm về 1.5x → 1.0x
Toàn bộ quá trình này diễn ra tự động trong vài phút
Bước 3: Heatmap cho tài xế
Surge pricing không chỉ ảnh hưởng giá cho khách — nó tạo ra Heatmap (bản đồ nhiệt) hiển thị trên app tài xế, hướng dẫn họ di chuyển đến khu vực có nhu cầu cao.
Heatmap Visualization:
┌────────────────────────────────────┐
│ │
│ 🟢 🟡 │
│ 🟢 🟡 │
│ 🟢 Quận 7 🔴 │
│ 🟢 🟡 🔴 Quận 1 │
│ 🟢 🟡 🔴 🔴 │
│ 🔴 │
│ 🟡 │
│ │
└────────────────────────────────────┘
🟢 = 1.0x (bình thường, dư tài xế)
🟡 = 1.5-2.0x (nhu cầu cao vừa)
🔴 = 2.5x+ (nhu cầu rất cao, kiếm tiền tốt)
Cập nhật Heatmap Real-time
Heatmap được đẩy xuống app tài xế qua WebSocket (hoặc gRPC stream):
Server → WebSocket Push → Driver App
Payload mỗi 30 giây:
{
"heatmap": [
{"h3": "872a100d6ffffff", "surge": 3.2, "color": "#FF0000"},
{"h3": "872a100d7ffffff", "surge": 1.0, "color": "#00FF00"},
{"h3": "872a100d8ffffff", "surge": 1.8, "color": "#FFAA00"}
],
"updated_at": "2026-05-06T20:30:00Z"
}
Predictive Surge — Dự đoán trước khi xảy ra
Uber và Grab không chỉ phản ứng với surge hiện tại — họ dự đoán surge trước khi nó xảy ra:
Predictive Model:
Inputs:
- Giờ hiện tại: 17:00 (giờ tan ca)
- Ngày: Thứ 6 (cuối tuần → demand tăng)
- Thời tiết: Dự báo mưa lúc 17:30
- Sự kiện: Concert tại SVĐ Mỹ Đình lúc 20:00
- Lịch sử: 4 thứ 6 trước cũng surge 2.5x lúc 17:30
Output:
- Dự đoán: Surge sẽ đạt 2.8x tại khu vực Cầu Giấy lúc 17:30
- Hành động: Gửi thông báo cho tài xế gần đó TRƯỚC 15 phút
"Khu vực Cầu Giấy sắp có nhu cầu cao, di chuyển đến để kiếm thêm thu nhập!"
Upfront Pricing vs Surge Multiplier
Mô hình cũ: Surge Multiplier (Uber trước 2017)
Giá hiển thị cho khách: "Surge 2.5x"
Giá cuối = Giá cơ bản × 2.5
Vấn đề: Khách không biết tổng tiền trước khi lên xe → Bất ngờ, khiếu nại
Mô hình mới: Upfront Pricing (Uber hiện tại, Grab)
Hiển thị cho khách: "Giá: 125.000 VNĐ" (cố định trước khi đặt)
Giá được tính từ:
base_fare + (distance × per_km_rate) + (time × per_min_rate)
+ surge_premium
+ route_specific_adjustments (kẹt xe dự đoán)
Khách biết chính xác giá trước khi đặt → Minh bạch hơn
Lưu trữ Surge State
-- Redis: Lưu surge multiplier cho mỗi H3 cell
-- Key pattern: surge:{resolution}:{h3_cell_id}
-- TTL: 60 giây (tự hết hạn nếu không cập nhật → fallback 1.0x)
SET surge:7:872a100d6ffffff "3.2" EX 60
SET surge:7:872a100d7ffffff "1.0" EX 60
SET surge:7:872a100d8ffffff "1.8" EX 60
-- Khi Rider App yêu cầu giá:
GET surge:7:872a100d6ffffff → "3.2"
-- API Gateway dùng giá trị này để tính Upfront Price
Cơ chế chống lạm dụng
| Rủi ro | Giải pháp |
|---|---|
| Tài xế cố tình tắt app để tạo khan hiếm giả | Phát hiện pattern: nhiều tài xế tắt đồng thời → flag |
| Tài xế chỉ nhận cuốc surge cao, từ chối cuốc thường | Acceptance rate thấp → giảm priority trong matching |
| Surge quá cao gây phản ứng dữ dội | Cap tối đa (ví dụ: 5.0x), soft cap dựa trên conversion rate |
| Surge “nhấp nháy” (tăng giảm liên tục) | Smoothing: surge chỉ tăng/giảm tối đa 0.5x mỗi 30 giây |
Phần cuối cùng, chúng ta sẽ tìm hiểu RAMEN — hạ tầng giao tiếp real-time của Uber, giải quyết bài toán đẩy thông báo tức thì tới hàng triệu thiết bị đồng thời. Đọc tiếp Phần 6 — RAMEN & Giao tiếp Real-time.