🏆 Staff+✍️ Khoa📅 19/04/2026☕ 9 phút đọc

Technical Strategy & Architecture Decision Making

Ở cấp độ Senior, bạn giải quyết vấn đề kỹ thuật được đặt ra. Ở cấp độ Staff+, bạn quyết định vấn đề nào đáng giải quyết, giải quyết theo hướng nào, và thuyết phục được cả tổ chức đi theo hướng đó.

Đây là skill set cực kỳ thực tế, không phải lý thuyết cao siêu — nhưng ít được dạy một cách có hệ thống.


1. Architecture Decision Records (ADR) — Tạo bộ nhớ kỹ thuật

1.1 Vấn đề ADR giải quyết

Một năm sau khi team quyết định dùng Kafka thay vì RabbitMQ, người mới join hỏi: "Tại sao team dùng Kafka?" Câu trả lời thường là: "Ờ... hồi đó anh B quyết định, mà anh B nghỉ rồi."

Đây là architectural amnesia — tổ chức quên mất context của các quyết định quan trọng. Hệ quả:

  • Quyết định bị re-litigated mỗi khi có người mới
  • Không ai biết liệu assumption cũ còn đúng hay không
  • Refactor sai vì không hiểu tại sao cái cũ được thiết kế vậy

ADR (Architecture Decision Record) là document ngắn ghi lại quyết định kiến trúc và bối cảnh dẫn đến quyết định đó.

1.2 Format ADR chuẩn

# ADR-042: Dùng PostgreSQL + pgvector thay vì Qdrant cho RAG System

**Status**: Accepted (2024-03-15)
**Deciders**: @khoa (Tech Lead), @tuan (Backend), @hoa (DevOps)

## Context
Chúng ta đang build RAG system cho chatbot hỗ trợ khách hàng.
Cần lưu trữ và tìm kiếm ~5M embeddings (1536 dims).
Team hiện tại đã quen vận hành PostgreSQL, chưa có kinh nghiệm với
distributed vector database.

## Decision
Dùng PostgreSQL với extension pgvector thay vì deploy Qdrant riêng.

## Consequences
**Positive:**
- Giảm infra complexity (không cần vận hành thêm 1 service)
- Tận dụng được row-level security của Postgres cho multi-tenancy
- Team đã quen với Postgres ops (backup, monitoring, failover)
- SQL JOIN với relational data đơn giản hơn

**Negative:**
- Throughput thấp hơn Qdrant (benchmark: ~3K vs ~100K QPS)
- Nếu scale lên >50M vectors, sẽ cần migrate sang dedicated solution
- Index build time chậm hơn với HNSW lớn

## Alternatives Considered
- **Qdrant**: Performance tốt hơn, nhưng tốn effort vận hành. Rejected vì
  team size nhỏ và current load chưa cần thiết.
- **Pinecone**: SaaS, không cần ops, nhưng vendor lock-in và data privacy concern.
  Rejected vì data sensitivity.

## Review Trigger
Revisit khi: vector count > 20M, hoặc p99 search latency > 100ms under load.

1.3 ADR trong thực tế — Không phải mọi quyết định đều cần ADR

Cần ADR:
  - Chọn technology stack mới (database, message queue, cache)
  - Thay đổi API contract (backward-incompatible)
  - Quyết định kiến trúc ảnh hưởng nhiều team
  - Bất kỳ tradeoff nào mà tương lai sẽ hỏi "tại sao lại làm vậy?"

Không cần ADR:
  - Bug fix
  - Refactoring không thay đổi behavior
  - Upgrade patch version của dependency
  - Implementation detail trong module nhỏ

Lưu ADR ở đâu? Commit vào repo (trong thư mục /docs/adr/), đánh số sequential. ADR là immutable — nếu quyết định thay đổi, viết ADR mới (supersede cái cũ) thay vì chỉnh sửa. Lịch sử là data.


2. Technical Debt — Quantify và Prioritize thay vì than thở

2.1 Tech Debt không phải là "code xấu"

Định nghĩa chính xác hơn của Ward Cunningham (người đặt ra thuật ngữ): Tech Debt là cost của việc chọn giải pháp nhanh thay vì giải pháp tốt hơn, tạo ra "interest" phải trả liên tục qua extra effort về sau.

Không phải mọi tech debt đều xấu:

Tech Debt tốt (Deliberate):
  → Biết mình đang "vay", có kế hoạch trả
  → "Ship MVP với in-memory storage, sẽ migrate sang Redis sau khi validate"
  → Trade-off có ý thức với business benefit rõ ràng

Tech Debt xấu (Accidental):
  → Không biết mình đang tạo ra debt
  → "Mọi người cứ copy-paste cái function này, tốt nhất không nên đụng vào"
  → Debt ẩn, không ai muốn nhận ownership

2.2 Debt Taxonomy — Phân loại trước khi đề xuất xử lý

Technical Debt Map:
  ┌──────────────────────────────────────────────────────┐
  │                                                        │
  │   Architecture Debt:  Kiến trúc sai từ căn bản        │
  │   Ví dụ: Monolith không thể scale theo request pattern │
  │   Cost: Thường cần nhiều tháng, multiple team          │
  │                                                        │
  │   Code Debt:  Code khó hiểu, không test được          │
  │   Ví dụ: 2000-line functions, spaghetti dependencies   │
  │   Cost: Days to weeks per area                         │
  │                                                        │
  │   Infrastructure Debt: Infra outdated, không secure    │
  │   Ví dụ: Still on Ubuntu 18.04, HTTP không HTTPS       │
  │   Cost: Days to weeks, risk-driven                     │
  │                                                        │
  │   Dependency Debt: Dependencies outdated               │
  │   Ví dụ: 3 major versions behind, security CVEs        │
  │   Cost: Hours to days per dependency                   │
  └──────────────────────────────────────────────────────┘

2.3 Cách pitch Tech Debt cho Product/Business

Sai lầm phổ biến nhất: đến gặp sếp và nói "Code mình tệ lắm, cần refactor." Response: "Okay, khi nào rảnh thì làm."

Điều Product/Business quan tâm không phải code quality — mà là risk, velocity, và cost. Frame theo ngôn ngữ của họ:

❌ Nói với Product:
"Hệ thống authentication của mình có tech debt nặng,
middleware viết từ 2019, khó maintain lắm."

✅ Nói với Product:
"Hiện tại mỗi khi add feature mới vào flow authentication,
team mất trung bình 2 tuần thay vì 3 ngày vì codebase phức tạp.
Nếu đầu tư 3 sprint để refactor, velocity của team sẽ tăng ~40%
cho tất cả auth-related work trong 6 tháng tới.
Ngoài ra, đợt security audit tháng trước flag 2 potential vulnerabilities
trong code cũ này — risk cần address trước Q2."

Tech Debt Scorecard — Công cụ để prioritize:

Debt Item Business Impact Probability of Issue Fix Cost Priority Score
Auth refactor High (security, velocity) Medium 3 sprints P0
Remove dead code Low Low 2 days P3
Upgrade Node 14→20 Medium (EOL security) High 1 week P1

Priority Score = (Business Impact × Probability) / Fix Cost


3. Build vs Buy vs Open Source — Framework quyết định

Đây là một trong những quyết định quan trọng nhất mà Staff Engineer phải đưa ra. Không có câu trả lời đúng mọi lúc — chỉ có framework phân tích đúng.

3.1 Khi nào Build?

Build khi:
  ✅ Đây là core competency / competitive advantage của sản phẩm
     Ví dụ: Netflix build recommendation engine vì đó là giá trị cốt lõi
  
  ✅ Requirements cực kỳ specific, không solution nào fit
     Ví dụ: Trading algorithm với latency microseconds
  
  ✅ Existing solutions đều quá nặng hoặc bring unwanted complexity
     Ví dụ: Build in-house config management thay vì deploy full Consul
     cho 5-service startup

Đừng Build khi:
  ❌ Đây là commodity problem (auth, logging, monitoring)
  ❌ Team không có domain expertise để maintain long-term
  ❌ Timeline quả ngắn để build đúng cách

3.2 Khi nào Buy (SaaS)?

Buy khi:
  ✅ Problem là non-differentiating (không phải lợi thế cạnh tranh)
     Ví dụ: Email sending, Payment processing, Analytics
  
  ✅ Vendor cung cấp expertise mà team không có
     Ví dụ: Security compliance (SOC2), ML model serving
  
  ✅ TCO của self-host cao hơn SaaS fee
     (TCO = licensing + eng time + ops time + incident cost)

Risks của Buy:
  ❌ Vendor lock-in: Khó migrate sau nếu cần
  ❌ Data privacy: Data đi ra third party
  ❌ Cost có thể tăng đột ngột (pricing change)
  ❌ SLA của vendor ảnh hưởng đến SLA của bạn

3.3 Khi nào dùng Open Source?

Open Source khi:
  ✅ Community active, project mature (không abandoned)
  ✅ License phù hợp với business model của bạn
     (MIT/Apache 2.0: OK; GPL: cẩn thận với commercial; AGPL: risky)
  ✅ Team có capacity để maintain fork nếu cần
  ✅ Không cần commercial support

Risks:
  ❌ Maintainer burnout → project abandoned
  ❌ Security vulnerability không được patch kịp
  ❌ License change (HashiCorp → BSL, Redis → SSPLv1)
  ❌ "Not invented here" trap: tự build khi OSS đã đủ tốt

Decision matrix thực tế:

Scenario: Cần message queue cho event-driven system

Build: ❌ (commodity, đã có solutions mature)

Buy (AWS SQS/SNS): 
  + Managed, scale tự động
  + Không ops burden
  - Vendor lock-in
  - Latency cao hơn self-host
  → Chọn nếu: team nhỏ, startup giai đoạn early

OSS (Kafka self-host):
  + Full control, performance cao
  + Không vendor lock-in
  - Ops burden nặng (Kafka là infra phức tạp)
  - Cần specialist knowledge
  → Chọn nếu: scale lớn, team có Kafka expertise, latency critical

OSS (Managed Confluent/MSK):
  + Best of both: OSS Kafka + managed ops
  - Đắt hơn raw SQS
  → Chọn nếu: cần Kafka feature nhưng không muốn tự ops

4. Technical Roadmapping — Lên kế hoạch kỹ thuật 6-12 tháng

4.1 Technical Roadmap là gì và tại sao cần?

Product có Product Roadmap. Engineering cần Technical Roadmap — kế hoạch kỹ thuật song song, định hướng investment vào platform, infrastructure, và enablers để support product roadmap.

Product Roadmap (Q1-Q4 2025):
  Q1: Launch mobile app
  Q2: International expansion (EU)
  Q3: Enterprise tier
  Q4: ML-powered recommendations

Tương ứng, Technical Roadmap:
  Q4 2024 (prerequisites):
    - Set up CDN cho performance mobile
    - Data residency compliance (GDPR) cho EU
  Q1:
    - API versioning để support mobile client
    - Mobile auth (push notifications, biometric)
  Q2:
    - Multi-region deployment (EU datacenter)
    - i18n framework
  Q3:
    - SSO/SAML cho Enterprise
    - Advanced audit logging
  Q4:
    - ML infrastructure (feature store, model serving)
    - A/B testing platform

4.2 Cách xây dựng Technical Roadmap

Step 1: Understand Product Strategy (6-12 months)
  → Meeting với Product/Business để hiểu direction
  → Identify technical implications của mỗi product goal

Step 2: Audit Technical Health hiện tại
  → Đánh giá tech debt, scalability bottlenecks, security gaps
  → Identify: "Cái gì sẽ fall apart nếu load tăng 10x?"

Step 3: Identify Technical Enablers
  → Những gì team cần xây để unlock product features nhanh hơn?
  → Platform investments: observability, CI/CD, developer experience

Step 4: Prioritize và Sequence
  → Dependencies giữa các items
  → Risk-adjusted priority: urgent (security) > important (scale) > nice-to-have
  → Realistic capacity planning (thường team overestimate 30-40%)

Step 5: Communicate và Iterate
  → Present cho Product/Leadership với tradeoffs rõ ràng
  → Review quarterly, update assumptions
  → "Roadmap là living document, không phải commitment"

4.3 Pitfall hay gặp

Pitfall 1: Over-engineering future
  "Chúng ta sẽ cần sharding khi có 1 tỷ users"
  → Bạn có 10K users hiện tại. Focus on what's needed next 6 months.
  
Pitfall 2: Tech Roadmap không sync với Product Roadmap
  → Technical work cần deliver value cho product goals, không phải 
  chỉ là "tech for tech's sake"
  
Pitfall 3: Quên Buffer time
  → Incidents, on-call, recruiting, onboarding ăn 30-40% capacity
  → Kế hoạch phải tính đến điều này