SystemDesign Core
RoadmapDocsBlogAbout
Bắt đầu học

© 2026 System Design Core. All rights reserved.

RoadmapDocsGitHub

Phase 0 — Mental Model Shift

Từ Perfect Solution đến Trade-off Thinking - Nghệ Thuật Của Quyết Định Kiến Trúc

Học cách đưa ra quyết định kiến trúc như một Senior Architect. Hiểu rằng không có giải pháp hoàn hảo, chỉ có giải pháp phù hợp. Master nghệ thuật cân bằng trade-offs trong system design.

Bài học trong phase

  • Bài 1

    Từ Code-First đến Problem-First - Thay Đổi Tư Duy Architect

  • Bài 2

    Từ Perfect Solution đến Trade-off Thinking - Nghệ Thuật Của Quyết Định Kiến Trúc

  • Bài 3

    Components và Communication - Giải Mã Kiến Trúc Hệ Thống Phân Tán

  • Bài 4

    Thinking in Constraints - Engineering Là Quản Lý Giới Hạn

  • Bài 5

    Scale Intuition - Xây Dựng Cảm Giác Về Numbers

  • Bài 6

    System Thinking Framework - Nhìn Hệ Thống Như Một Tổng Thể

  • Bài 7

    System Question Framework - Checklist Chuẩn Khi Design Hệ Thống

  • Bài 8

    Mental Model Recap - Củng Cố Tư Duy System Design

Tổng quan phase
  1. Roadmap
  2. /
  3. Phase 0 — Mental Model Shift
  4. /
  5. Từ Perfect Solution đến Trade-off Thinking - Nghệ Thuật Của Quyết Định Kiến Trúc

Từ Perfect Solution đến Trade-off Thinking - Nghệ Thuật Của Quyết Định Kiến Trúc

Học cách đưa ra quyết định kiến trúc như một Senior Architect. Hiểu rằng không có giải pháp hoàn hảo, chỉ có giải pháp phù hợp. Master nghệ thuật cân bằng trade-offs trong system design.

Chia sẻ bài học

Từ Perfect Solution đến Trade-off Thinking

Có một câu hỏi mà mọi junior engineer đều từng hỏi tôi: "Cách tốt nhất để thiết kế hệ thống này là gì?"

Câu trả lời của tôi luôn làm họ thất vọng: "Không có 'cách tốt nhất'. Chỉ có cách phù hợp nhất với constraints của bạn."

Đó là bài học khó nhất mà mọi architect phải học: không có giải pháp hoàn hảo.

Tại Sao "Perfect Solution" Không Tồn Tại?

Khi tôi mới bắt đầu, tôi tin rằng với đủ thời gian và kiến thức, tôi có thể tìm ra "the perfect architecture" - một kiến trúc không có nhược điểm.

Sau 10 năm thiết kế hệ thống, tôi nhận ra một sự thật tàn khốc:

Mọi quyết định kiến trúc đều là một sự đánh đổi.

Không phải vì bạn không đủ giỏi. Mà vì trong thế giới thực, bạn luôn phải chọn giữa những thứ mâu thuẫn nhau:

  • Performance vs Consistency: Nhanh hoặc chính xác?
  • Scalability vs Simplicity: Dễ scale hoặc dễ maintain?
  • Flexibility vs Performance: Linh hoạt hoặc tối ưu?
  • Cost vs Reliability: Rẻ hoặc ổn định?

Bạn không thể có tất cả. Và đó không phải là vấn đề. Đó là thực tế.

The Myth of "Best Practices"

Tôi thường thấy developers nói: "Microservices là best practice" hoặc "NoSQL tốt hơn SQL".

Không. Sai hoàn toàn.

Microservices là best practice cho Netflix với 200 triệu users và 500 engineering teams. Nó là worst practice cho startup 5 người với 100 users.

NoSQL tốt cho Facebook với billions of posts không cần strict relationships. Nó là terrible choice cho banking system cần ACID transactions.

"Best practice" không tồn tại trong chân không. Context is everything.

Ví Dụ Thực Tế: Monolith vs Microservices

Hãy phân tích trade-off của hai approaches này.

Monolith:

Advantages:
- Simple deployment (1 app)
- Easy debugging (1 codebase)
- No network latency giữa components
- Transactions đơn giản (same database)
- Fast development initially

Disadvantages:
- Khó scale independently
- Deploy all-or-nothing
- Team conflicts trên same codebase
- Technology lock-in
- Restart toàn bộ app khi update

Microservices:

 Advantages:
- Scale independently
- Deploy independently
- Technology diversity
- Team autonomy
- Fault isolation

 Disadvantages:
- Network latency
- Distributed transactions nightmare
- Complex deployment
- Monitoring complexity
- Data consistency challenges

Câu hỏi không phải là "cái nào tốt hơn?". Câu hỏi là:

"Với context hiện tại của tôi, tôi cần advantages nào và có thể chấp nhận disadvantages nào?"

Framework: The Trade-off Matrix

Đây là framework tôi dùng để đánh giá mọi quyết định kiến trúc.

Step 1: Define Your Constraints

Trước khi so sánh giải pháp, hãy hiểu rõ constraints của bạn:

Technical Constraints:

  • Current scale: 1K users hay 100M users?
  • Growth rate: 2x/year hay 10x/month?
  • Team size: 2 devs hay 50 devs?
  • Latency requirement: < 100ms hay < 1s OK?

Business Constraints:

  • Budget: Unlimited hay tight?
  • Time to market: Ship trong 1 tháng hay 6 tháng?
  • Regulatory: GDPR, PCI compliance?

Team Constraints:

  • Expertise: Team biết gì?
  • Learning curve: Có thời gian học không?
  • Operational capacity: Ai maintain?

Step 2: List Trade-offs Explicitly

Với mỗi option, viết ra rõ ràng:

Option A: PostgreSQL
 Gains:
- ACID guarantees
- Rich query capabilities (JOIN, aggregations)
- Mature ecosystem
- Team đã biết

 Costs:
- Vertical scaling limits
- Schema changes expensive
- Not optimal for unstructured data

Option B: MongoDB
 Gains:
- Horizontal scaling easier
- Flexible schema
- Good for rapid iteration

 Costs:
- No JOIN support (application-level)
- Eventual consistency complexity
- Team phải học mới

Step 3: Align với Priorities

Rank priorities của project:

Priority 1: Ship fast (MVP trong 2 tháng)
Priority 2: Team productivity (ít learning curve)
Priority 3: Data integrity (financial data)

Given priorities → PostgreSQL wins
Why? Team biết, ACID critical, can scale later.

Nếu priorities thay đổi:

Priority 1: Scale to 100M users (đã có PMF)
Priority 2: Handle unstructured data (user-generated content)
Priority 3: Read performance

Given priorities → MongoDB might win
Why? Scale + flexibility outweigh JOIN limitations.

Thấy chưa? Cùng 2 options, khác priorities → khác decision.

Real-World Case Study: Cache hay Không Cache?

Hãy xem một quyết định tưởng chừng đơn giản: "Có nên dùng cache không?"

Hầu hết developers nghĩ: "Cache làm nhanh hơn → Always cache!"

Sai rồi. Hãy phân tích trade-offs.

Scenario: E-commerce Product Page

Without Cache:

User request → Query DB → Return

 Advantages:
- Always fresh data (price, stock)
- Simple logic (no invalidation)
- No infrastructure overhead

 Disadvantages:
- DB load cao
- Slow response (DB query mỗi request)
- Hard to scale reads

With Cache (Redis):

User request → Check Redis → If miss: Query DB → Return

 Advantages:
- Fast response (< 10ms)
- Reduce DB load
- Easy to scale reads

 Disadvantages:
- Stale data risk (user thấy sold-out item as available)
- Cache invalidation complexity
- Infrastructure cost (Redis server)
- Memory limits

The Trade-off Decision

Nếu bạn là Amazon:

→ Use cache vì:

  • Millions requests/second → DB không chịu nổi
  • Slight staleness acceptable (stock count có thể sai 1-2 items)
  • Budget cho infrastructure
  • Team có expertise

Nếu bạn là startup nhỏ:

→ Skip cache vì:

  • 100 requests/second → DB handle được
  • Fresh data quan trọng hơn (ít inventory)
  • Save infrastructure cost
  • Keep it simple

Same problem, different context, different decision.

Common Trade-offs Mọi Architect Phải Biết

1. Consistency vs Availability (CAP Theorem)

Bạn không thể có cả hai trong distributed system khi có network partition.

Choose Consistency (CP):

Banking, payments, inventory management
→ Đúng quan trọng hơn fast
→ OK với downtime nếu cần ensure correctness

Choose Availability (AP):

Social media feeds, view counts, recommendations
→ Fast quan trọng hơn perfect accuracy
→ Eventual consistency acceptable

Trade-off thinking:

  • Feature này CẦN strong consistency không? (Usually NO)
  • User có bị impact nếu data sai vài giây không?
  • Cost của ensuring consistency là gì?

2. Normalization vs Denormalization

Normalized Database:

-- 3 tables, proper 3NF
users: id, name
posts: id, user_id, content
likes: id, post_id, user_id

-- Query post with like count
SELECT p.*, COUNT(l.id) as likes
FROM posts p
LEFT JOIN likes l ON p.id = l.post_id
WHERE p.id = 123
GROUP BY p.id;

Data integrity, no duplication Slow queries (JOINs expensive)

Denormalized:

-- 1 table
posts: id, user_id, content, like_count

-- Query post with like count
SELECT * FROM posts WHERE id = 123;

Fast reads (no JOIN) Risk of inconsistency, update overhead

When to denormalize?

  • Read >> Write (99% reads, 1% writes)
  • Performance critical
  • Can tolerate slight inconsistency

When to keep normalized?

  • Write heavy
  • Data integrity critical
  • Complex relationships

3. Async vs Sync Processing

Synchronous:

def upload_video(video):
    save_to_s3(video)           # 2s
    generate_thumbnail(video)   # 3s
    transcode_720p(video)       # 30s
    send_notification()         # 1s
    return "Success"            # User waits 36s

Simple, immediate feedback Poor UX, timeout risk

Asynchronous:

def upload_video(video):
    save_to_s3(video)           # 2s
    queue.add_job('process_video', video.id)
    return "Success"            # User waits 2s

# Background worker processes rest

Better UX, handles spikes Complex, eventual processing, error handling harder

Trade-off decision:

  • User cần kết quả ngay không?
  • Process có thể fail và retry được không?
  • Team có experience với async patterns không?

The Art of "Good Enough"

Một trong những skills quan trọng nhất của architect: Biết khi nào dừng optimize.

Tôi từng thấy engineers spend 2 tuần optimize một query từ 50ms xuống 20ms.

Impact? Users không thấy khác biệt (human perception threshold là ~100ms).

Cost? 2 tuần dev time = features khác bị delay.

"Perfect is the enemy of good."

The 80/20 Rule in Architecture

20% effort thường giải quyết 80% vấn đề.

Ví dụ: Optimizing API Response Time

Current: 800ms
Target: < 200ms

Option A: Add database indexes
- Effort: 2 hours
- Result: 800ms → 300ms (62% improvement)

Option B: Thêm + implement Redis caching
- Effort: 1 week
- Result: 300ms → 150ms (thêm 50% improvement)

Option C: Migrate sang Cassandra + rewrite queries
- Effort: 2 months
- Result: 150ms → 100ms (thêm 33% improvement)

Smart decision:

  • Start với Option A (high ROI)
  • Monitor
  • Option B nếu 300ms vẫn chưa đủ
  • Probably never do Option C (diminishing returns)

Bài Tập: Trade-off Analysis

Exercise 1: Design User Authentication

Requirement: User login system

Option A: JWT (Stateless)

List trade-offs:

  • Gains: ?
  • Costs: ?
  • Best for: ?

Option B: Session (Stateful)

List trade-offs:

  • Gains: ?
  • Costs: ?
  • Best for: ?

Viết ra reasoning của bạn. Không có đúng/sai, chỉ có phù hợp/không phù hợp.

Exercise 2: Real-World Scenario

Context:

  • Startup, 5 engineers
  • Current: 10K users
  • Expected: 100K users trong 6 tháng
  • Feature: Real-time chat

Options:

  1. Build custom WebSocket server
  2. Use Firebase Realtime Database
  3. Use Twilio/Stream Chat (third-party)

Your task:

  1. List trade-offs của mỗi option
  2. Rank priorities (time, cost, scalability, control)
  3. Make decision với reasoning

Không có "correct answer". Practice trade-off thinking.

Mental Models để Đưa Ra Quyết Định

Model 1: Reversibility

Câu hỏi: Quyết định này có dễ thay đổi sau không?

High reversibility (can change easily):

  • Choice of cache (Redis → Memcached)
  • ORM library
  • Frontend framework

→ Don't overthink. Chọn nhanh, iterate sau.

Low reversibility (expensive to change):

  • Database choice (SQL → NoSQL)
  • Monolith → Microservices
  • Cloud provider

→ Think carefully. Cost of wrong decision cao.

Model 2: Impact vs Effort

High Impact, Low Effort → DO NOW
High Impact, High Effort → PLAN & PRIORITIZE
Low Impact, Low Effort → DO IF TIME
Low Impact, High Effort → DON'T DO

Ví dụ:

  • Add database index: High impact, Low effort → DO NOW
  • Rewrite sang microservices: High impact, High effort → PLAN carefully
  • Refactor variable names: Low impact, Low effort → DO if time
  • Build custom authentication: Low impact, High effort → DON'T (use Auth0)

Model 3: Regret Minimization

Câu hỏi: 6 tháng sau, decision nào tôi sẽ hối hận nhất?

Scenario: Choose tech stack cho startup MVP

Decision A: Use new trendy framework (Deno, Bun...)

  • Nguy cơ: Ecosystem chưa mature, team phải học, risk fail
  • Regret potential: HIGH (nếu fail, mất thời gian quý báu)

Decision B: Use boring proven stack (Node.js + Express + PostgreSQL)

  • Nguy cơ: Không "cool", might miss new features
  • Regret potential: LOW (even if slow, it works reliably)

→ For startup MVP: Minimize regret → Choose B

Checklist: Bạn Đã Think in Trade-offs Chưa?

Trước khi finalize bất kỳ architectural decision nào:

  • Tôi đã list ít nhất 2-3 alternatives
  • Tôi đã viết ra trade-offs (gains vs costs) cho mỗi option
  • Tôi hiểu rõ context và constraints hiện tại
  • Tôi đã rank priorities rõ ràng
  • Tôi có thể explain "tại sao option này FIT" (không phải "best")
  • Tôi đã consider reversibility của decision
  • Tôi biết mình đang sacrifice cái gì để gain cái gì

Nếu check được 6/7 → Bạn đang think như một architect.

Key Takeaways

Không có perfect solution, chỉ có optimal trade-off.

Mọi architectural decision là một sự đánh đổi. Công việc của architect không phải là tìm "best practice", mà là:

  1. Hiểu rõ context: Scale, team, constraints
  2. List trade-offs explicitly: Gains vs Costs
  3. Align với priorities: Impact vs Effort
  4. Make informed decision: "Phù hợp" không phải "hoàn hảo"
  5. Accept consequences: Embrace costs của choice

Câu nói yêu thích của tôi:

"There are no solutions. There are only trade-offs." — Thomas Sowell

Một senior architect giỏi không phải là người biết mọi pattern. Mà là người biết pattern nào fit với context nào, và tại sao.

Good enough, shipped, and iterated beats perfect but never launched.

Hãy bắt đầu nghĩ theo trade-offs từ hôm nay. Mỗi khi bạn nói "solution tốt nhất", hãy dừng lại và hỏi:

"Tốt nhất cho ai? Trong context nào? Tôi đang trade-off cái gì?"

Từ Code-First đến Problem-First - Thay Đổi Tư Duy ArchitectComponents và Communication - Giải Mã Kiến Trúc Hệ Thống Phân Tán