Tài liệu Trung bình 6 phút đọc

Decision log và ADR: ký ức của dự án

Cách viết Architecture Decision Record (ADR) và decision log nhẹ hơn để thành viên tương lai - và cả tương lai bạn - thật sự thấy hữu dụng.

Mục lục
  1. Khi nào tài liệu hoá quyết định bắt đầu trả lại giá trị?
  2. Cái giá khi bỏ tài liệu hoá quyết định là gì?
  3. Template ADR tối thiểu là gì?
  4. Một decision log nhẹ hơn trông thế nào?
  5. Tài liệu hoá quyết định scale lên đa team như thế nào?
  6. Tài liệu hoá quyết định có thể tự tạo ra những lỗi nào?
  7. Khi nào ADR đầy đủ là quá liều?
  8. Đi tiếp từ đây như thế nào?

Một quyết định mà dự án đưa ra hôm nay sẽ bị chính người ra quyết định quên đi trong vòng 6 tháng. Team tham gia một năm sau sẽ không biết vì sao thiết kế lại trông như vậy. ADR và decision log là những artifact giúp chặn đứng việc mất ký ức này. Chương này giới thiệu template cho cả hai và kỷ luật cần để giữ chúng hữu dụng.

Khi nào tài liệu hoá quyết định bắt đầu trả lại giá trị?

Có ba tín hiệu chính.

Dự án dài hơn 6 tháng. Dưới mức đó, trí nhớ vẫn giữ được ngữ cảnh. Trên mức đó, team đã xoay vòng, sponsor đã đổi, và câu "vì sao chúng ta làm cái này" đã mất nguồn gốc.

Lựa chọn kiến trúc đảo-ngược-được-nhưng-tốn. Database, kiểu API, cách auth - đúng loại lựa chọn mà series System Design phủ. Mỗi cái đáng một ADR.

Nhiều team sẽ kế thừa hệ. Việc onboard một team mới sẽ nhanh hơn rất nhiều với một folder ADR, so với câu "hỏi Bob, anh ấy đã ở đó".

Nếu dự án nhỏ, ngắn, và bạn sẽ sở hữu nó mãi mãi, tài liệu hoá là gánh nặng. Nhưng phần lớn dự án production không như vậy.

Cái giá khi bỏ tài liệu hoá quyết định là gì?

Có ba kiểu lỗi thường gặp.

Tái xét kéo dài. Mọi engineer mới đều đặt lại các câu hỏi về kiến trúc. Team tốn nhiều giờ để giải thích lại; vài lựa chọn còn bị đảo qua đảo lại.

Engineering kiểu cargo-cult. Việc mới copy pattern cũ mà không hiểu lý do. Lựa chọn gốc được đưa ra cho lý do X; bản copy lại áp ở chỗ mà lý do X không còn giữ.

Mất ngữ cảnh ở handover. Team A xây hệ; Team B kế thừa; các quyết định từng có lý do giờ trông tuỳ tiện. Team B viết lại tất cả vì không phân biệt được cái cố ý với cái ngẫu nhiên.

Template ADR tối thiểu là gì?

# ADR-001: Dùng Postgres làm data store chính

Date: 2026-06-19
Status: Accepted
Deciders: Tech Lead, EM, Sponsor

## Context

Cần một data store chính cho service billing mới. Service ghi
100-500 transaction/giây và đọc gấp 5-10 lần. Data có quan hệ
(đơn, line item, thanh toán). Team đã quen Postgres; các phương
án xem xét gồm MongoDB, DynamoDB.

## Decision

Sẽ dùng PostgreSQL 16 host trên Azure Database for PostgreSQL
Flexible Server, kèm một read replica.

## Consequences

### Tích cực
- Sự quen thuộc của team giảm thời gian onboard
- Strong consistency mặc định; transaction đơn giản
- Hỗ trợ EF Core đã trưởng thành
- Read replica gánh các query dashboard

### Tiêu cực
- Mặc định single-region; multi-region cần làm sau
- Trần scale dọc khoảng 5K write/giây; sẽ cần partition nếu
  volume tăng 10 lần

## Phương án đã xem xét

- **DynamoDB**: từ chối - team không quen, eventual consistency
  làm phức tạp logic billing
- **MongoDB**: từ chối - schema linh hoạt không cần thiết; mô
  hình quan hệ hợp với domain hơn

## Điều kiện xem lại

Nếu write QPS tiệm cận 3K/giây, đánh giá lại sharding qua Citus
hoặc chuyển sang store khác. Theo dõi qua [metric
observability](/system-design/observability-otel-dotnet).

Có ba chi tiết quan trọng. Một, trường Status (Accepted, Superseded, Deprecated) cho thấy quyết định có còn giữ không. Hai, "Điều kiện xem lại" là một trigger sẵn để mở lại; không có nó, ADR cũ sẽ chìm trong im lặng. Ba, đánh số tuần tự trong folder docs/adr/.

Một decision log nhẹ hơn trông thế nào?

Với các quyết định không thuộc kiến trúc, dùng một file markdown duy nhất cho mỗi dự án:

# Decision Log — {{ Tên dự án }}

## 2026-06-19: Dùng Mailgun cho email giao dịch
Quyết bởi: PM + TL. Ngữ cảnh: cần giao email tin cậy cho thông
báo refund. Đã xem xét SendGrid, Postmark. Chọn Mailgun vì có
tài khoản sẵn và tier volume thấp hơn. Lý do: rẻ hơn ở volume
hiện tại; team đã có quyền truy cập dashboard.

## 2026-06-15: Hoãn subscription billing sang Q4
Quyết bởi: Sponsor. Ngữ cảnh: scope creep ở release đầu. Áp
khung scope-tradeoff; subscription chuyển từ Must sang Won't
trong quý này.

## 2026-06-10: Outsource runbook customer support cho vendor
Quyết bởi: PM. Ngữ cảnh: writer in-house đã ở capacity. Chọn
vendor: AcmeWriting dựa trên dự án trước. Chi phí: $5K. Owner:
PM ký final.

Format nhẹ này bắt được các quyết định về quy trình và mua sắm mà ADR không phủ. Cả hai format có thể đồng tồn tại - ADR nằm trong repo cho engineer, decision log nằm ở wiki dự án cho mọi người.

Tài liệu hoá quyết định scale lên đa team như thế nào?

flowchart TB
    OrgADRs[ADR cấp tổ chức<br/>chuẩn xuyên team] --> TeamADRs[ADR cấp team<br/>lựa chọn local]
    TeamADRs --> Project[Decision log dự án<br/>lựa chọn vận hành]
    OrgADRs -.tham chiếu bởi.-> Project
    Project --> Onboarding[Nhân viên mới đọc ngày 2]

ADR cấp tổ chức phủ các lựa chọn mà mọi người theo ('chúng ta dùng PostgreSQL làm mặc định'); ADR cấp team phủ những lựa chọn mà team đưa ra bên trong default đó; còn decision log dự án phủ các call vận hành. Engineer mới đọc cả ba lớp ở plan onboard chương 16 ngay ngày 2. Chương scopechương stakeholder là nguồn đẩy nội dung vào cả hai format.

Tài liệu hoá quyết định có thể tự tạo ra những lỗi nào?

Khi nào ADR đầy đủ là quá liều?

Có hai trường hợp.

Engineer solo, scope nhỏ. Bạn là người duy nhất sẽ đọc. Một file README ngắn giải thích "tôi chọn X vì Y" là đủ.

Thí nghiệm nhanh hoặc spike. Code sẽ vứt sau hai tuần không cần ADR. Hãy tài liệu hoá kết quả của spike; phần scaffold sẽ biến mất.

Kỷ luật đầy đủ chỉ đáng overhead ở quy mô team 3+ người và thời lượng dự án 3+ tháng.

Đi tiếp từ đây như thế nào?

Bạn đã hoàn tất nhóm artifact. Bốn chương tiếp theo là case study đưa mọi artifact bạn đã học vào hành động trên các hình dạng dự án thật. Bắt đầu với cứu dự án sắp đổ - playbook cho tình huống khó nhất mà một tech lead có thể kế thừa.

Câu hỏi thường gặp

ADR và decision log khác gì nhau?
ADR (Architecture Decision Record, được Michael Nygard phổ biến hoá) là một file markdown chính thức trong repo, mỗi quyết định một file, tập trung vào kiến trúc. Còn decision log là một danh sách chạy theo dự án, mỗi quyết định một entry, gồm cả các lựa chọn không phải kiến trúc (quy trình, vendor, scope). Hãy dùng ADR cho 10-15 quyết định kiến trúc định hình cả hệ; dùng decision log cho 50+ call nhỏ hơn mà dự án đưa ra.
Khác comment trong code ra sao?
Comment trả lời câu 'cái này làm gì'; còn ADR trả lời câu 'vì sao chọn cái này thay vì phương án khác'. Comment sống cùng code; ADR sống ở folder riêng nên ai đọc lịch sử dự án đều khám phá ra được. Cả hai đều có giá trị; ADR bắt được những quyết định không có một chỗ trong code rõ ràng để gắn vào.
Khi nào nên viết ADR thay vì chỉ ra quyết định?
Hãy viết ADR khi quyết định không hiển nhiên, gây tranh cãi, hoặc đắt khi đảo ngược. 'Chúng ta dùng Postgres' cho một app CRUD đơn giản không cần ADR. Còn 'Chúng ta dùng Cassandra vì scale dự kiến' thì cần, vì engineer kế tiếp sẽ tự hỏi vì sao và có thể muốn xem lại. Cây quyết định trong Design Patterns when-to-use-which thể hiện cùng kỷ luật ở mức code.
Ai sẽ đọc ADR?
Là các thành viên tương lai của team, bao gồm cả tương lai của chính bạn một năm sau. Đối tượng không phải là team đang ra quyết định (họ vẫn nhớ). Đối tượng là engineer tham gia 12 tháng sau và đặt câu hỏi 'sao cái này lại lạ thế' - ADR chính là câu trả lời du hành thời gian của bạn. Không có ADR, mọi lựa chọn kiến trúc sẽ bị tái xét bởi mọi nhân viên mới.