Skip to content
Published on

영어 테크니컬 라이팅 실전 가이드: RFC, ADR, Design Doc 작성법과 템플릿

Authors
  • Name
    Twitter
Technical Writing RFC ADR Design Doc

들어가며

소프트웨어 엔지니어의 코드 작성 시간은 전체 업무 시간의 30~40%에 불과하다. 나머지는 설계, 논의, 리뷰, 문서화에 쓰인다. 특히 글로벌 팀에서 일하면 기술적 의사결정을 영어 문서로 남기는 능력이 커리어 성장의 핵심 차별점이 된다. Google, Meta, Uber, Spotify 같은 기업들은 코드를 작성하기 전에 RFC(Request for Comments), ADR(Architecture Decision Record), Design Doc을 먼저 쓰고 팀의 합의를 얻는 문화가 정착되어 있다.

한국 개발자가 이 과정에서 겪는 어려움은 두 가지다. 첫째, RFC와 ADR과 Design Doc의 차이와 용도를 정확히 구분하지 못한다. 셋 다 "기술 문서"라는 범주에 묶여서 언제 어떤 것을 써야 하는지 모호하다. 둘째, 영어로 기술적 논거를 전개하고, 대안을 비교하고, 결정을 정당화하는 문장 패턴에 익숙하지 않다.

이 글은 세 문서의 구조와 목적을 명확히 구분하고, 각각의 영문 템플릿과 실전 표현을 제공한다. 단순한 번역 팁이 아니라, 글로벌 팀에서 실제로 통하는 기술 문서를 쓰기 위한 구체적인 가이드다.


기술 문서의 종류와 목적: RFC, ADR, Design Doc

세 문서의 핵심 차이

RFC, ADR, Design Doc은 목적과 수명 주기가 다르다. 혼용하면 문서의 초점이 흐려지고, 리뷰어가 무엇에 대해 피드백을 줘야 하는지 혼란스러워진다.

항목RFCADRDesign Doc
목적제안과 합의 도출결정과 근거 기록설계와 구현 계획
작성 시점큰 변경 전결정 직후구현 착수 전
수명승인/거부 후 아카이브영구 보존구현 완료 후 참조용
분량2~10페이지1~2페이지5~20페이지
독자팀 전체 또는 조직현재 및 미래 팀원구현 관련 엔지니어
핵심 질문"이 변경을 해야 하는가?""왜 이 결정을 내렸는가?""어떻게 구현할 것인가?"
상태 관리Draft, In Review, Accepted, RejectedProposed, Accepted, Deprecated, SupersededDraft, In Review, Approved, Implemented
대안 분석필수 (3개 이상 권장)필수 (고려한 대안 목록)선택적 (주요 설계 선택에 대해)

언제 어떤 문서를 써야 하는가

다음 의사결정 트리를 참고한다.

[변경의 범위가 넓은가?]
├── Yes: 여러 팀에 영향 → RFC 작성
│         └── RFC 승인 후 → Design Doc 작성
│               └── 주요 결정마다 → ADR 작성
└── No: 단일 팀 내부
      ├── 아키텍처 결정인가?
      │     └── Yes → ADR 작성
      └── 구현 계획이 필요한가?
            └── Yes → Design Doc (경량 버전) 작성

핵심 원칙은 다음과 같다. RFC는 합의를 구하는 제안서이고, ADR은 결정의 영구 기록이며, Design Doc은 구현의 청사진이다. 하나의 프로젝트에서 세 문서가 모두 필요할 수 있고, RFC에서 시작해 승인 후 Design Doc을 작성하며, 그 과정에서 발생한 주요 결정을 ADR로 남기는 흐름이 가장 일반적이다.


RFC 작성법과 템플릿

RFC의 구조

RFC(Request for Comments)는 이름 그대로 의견을 요청하는 문서다. IETF의 인터넷 표준 RFC에서 유래했지만, 소프트웨어 엔지니어링에서는 "기술적 제안서"의 의미로 널리 쓰인다. Uber의 경우 연간 수천 건의 RFC가 작성되며, Google에서는 이를 "Design Doc"이라 부르지만 본질적으로 RFC와 동일한 프로세스를 따른다.

RFC 영문 템플릿

# RFC-0042: Migrate User Service to Event-Driven Architecture

| Field         | Value                         |
| ------------- | ----------------------------- |
| **Status**    | In Review                     |
| **Authors**   | Jane Kim (jane@example.com)   |
| **Created**   | 2026-03-01                    |
| **Updated**   | 2026-03-05                    |
| **Reviewers** | @backend-team, @platform-team |

## Summary

A one-paragraph summary of the proposal. This should be concise enough
that someone can understand the core idea in 30 seconds.

> We propose migrating the User Service from a synchronous REST-based
> architecture to an event-driven architecture using Apache Kafka.
> This change aims to reduce inter-service coupling, improve fault
> tolerance, and enable real-time data propagation to downstream
> consumers.

## Motivation

Why are we doing this? What problem does it solve? Include data
and metrics wherever possible.

- Current synchronous calls between User Service and 7 downstream
  services create cascading failures. In Q4 2025, we experienced
  12 incidents directly caused by this coupling.
- Average response time for user profile updates is 1,200ms due
  to synchronous fan-out to notification, analytics, and billing
  services.
- The current architecture cannot support the projected 10x growth
  in user events expected by Q3 2026.

## Proposed Solution

### High-Level Design

Describe the proposed solution in enough detail for reviewers to
understand the approach without reading the implementation details.

### Detailed Design

Include diagrams, API contracts, data models, and workflow
descriptions as needed.

## Alternatives Considered

### Alternative 1: Async HTTP with Retry Queue

Description of the alternative and why it was not chosen.

**Pros:**

- Minimal code changes required
- Team is already familiar with HTTP-based patterns

**Cons:**

- Does not fundamentally solve the coupling problem
- Retry storms can overwhelm downstream services

### Alternative 2: gRPC Streaming

Description and trade-off analysis.

## Migration Plan

How will we roll this out? Include phases, timelines, and rollback
procedures.

1. **Phase 1 (Week 1-2):** Set up Kafka cluster and deploy
   to staging environment.
2. **Phase 2 (Week 3-4):** Dual-write to both REST and Kafka
   for the notification service.
3. **Phase 3 (Week 5-6):** Migrate remaining consumers one
   by one with feature flags.
4. **Phase 4 (Week 7-8):** Remove synchronous endpoints after
   validation period.

### Rollback Plan

If critical issues are detected, we can revert to synchronous
calls by disabling the feature flag. Kafka messages will be
retained for 7 days, allowing replay after fix deployment.

## Risks and Mitigations

| Risk                       | Impact | Likelihood | Mitigation                                    |
| -------------------------- | ------ | ---------- | --------------------------------------------- |
| Message ordering issues    | High   | Medium     | Use partition keys based on user ID           |
| Consumer lag during peak   | Medium | High       | Auto-scaling consumer groups + alerting       |
| Data loss during migration | High   | Low        | Dual-write validation with reconciliation job |

## Open Questions

- Should we use Kafka Connect or custom consumers for the
  analytics pipeline?
- What is the acceptable message delivery latency SLA?

## References

- [Event-Driven Architecture at Uber](https://example.com)
- [Kafka Best Practices](https://example.com)

RFC 작성 핵심 원칙

1. Summary는 30초 안에 읽을 수 있어야 한다. 경영진이든 다른 팀 엔지니어든, Summary만 읽고 이 RFC가 자기에게 관련이 있는지 판단할 수 있어야 한다.

2. Motivation에는 반드시 데이터를 포함한다. "현재 아키텍처가 복잡하다"는 의견이지 근거가 아니다. "Q4 2025에 12건의 장애가 발생했고, 평균 복구 시간은 47분이었다"가 근거다.

3. Alternatives는 최소 2개 이상 제시한다. 대안 없이 하나의 방안만 제시하면 "왜 다른 방법은 안 되는가?"라는 질문에 대응할 수 없다. 각 대안의 Pros/Cons를 명시하고, 제안 방안이 우수한 이유를 논리적으로 설명한다.

4. Open Questions를 두려워하지 않는다. 모든 답을 갖고 있을 필요는 없다. 해결되지 않은 질문을 명시적으로 남기면 리뷰어가 거기에 집중해서 건설적인 피드백을 준다.


ADR 작성법과 템플릿

ADR이란

ADR(Architecture Decision Record)은 아키텍처 결정의 맥락, 이유, 결과를 기록하는 짧은 문서다. Michael Nygard가 2011년에 제안한 이후, Spotify, GitHub, GOV.UK 등 많은 조직에서 표준 프랙티스로 채택되었다. RFC가 "제안"에 초점을 맞춘다면, ADR은 "결정 그 자체"에 초점을 맞춘다.

ADR의 핵심 가치는 미래의 팀원이 과거 결정의 맥락을 이해할 수 있게 하는 것이다. 6개월 후에 합류한 새 팀원이 "왜 MongoDB 대신 PostgreSQL을 선택했지?"라고 물었을 때, ADR이 있으면 그 당시의 제약 조건과 논의 과정을 정확히 전달할 수 있다.

ADR 영문 템플릿

# ADR-0015: Use PostgreSQL as the Primary Database

| Field         | Value                          |
| ------------- | ------------------------------ |
| **Status**    | Accepted                       |
| **Date**      | 2026-03-04                     |
| **Deciders**  | Jane Kim, Alex Park, Sarah Lee |
| **Consulted** | Database Team, Security Team   |

## Context

We need to select a primary database for the new Order Management
Service. The service will handle approximately 50,000 orders per
day initially, with projected growth to 500,000 orders per day
within 18 months.

Key requirements:

- ACID transactions for order state management
- Complex queries for reporting and analytics
- JSON support for flexible product metadata
- Strong ecosystem for monitoring and tooling

The team has production experience with both PostgreSQL and MongoDB.
Our existing infrastructure runs PostgreSQL 15 for three other
services.

## Decision

We will use **PostgreSQL 17** as the primary database for the
Order Management Service.

## Rationale

1. **ACID compliance**: Order processing requires strict
   transactional guarantees. PostgreSQL's MVCC provides
   this without application-level workarounds.
2. **Operational familiarity**: The team already operates
   three PostgreSQL instances. Adding MongoDB would
   increase operational overhead and require new runbooks.
3. **JSON support**: PostgreSQL's JSONB type with GIN
   indexing satisfies the flexible metadata requirement
   without sacrificing query performance.
4. **Cost**: Our existing database infrastructure and
   tooling (pgBouncer, pg_stat_statements, Patroni)
   can be reused.

## Alternatives Considered

### MongoDB

- **Pros:** Native JSON document model, flexible schema,
  horizontal scaling with sharding
- **Cons:** Eventual consistency by default requires careful
  configuration for order processing, additional operational
  overhead, separate monitoring stack needed
- **Rejected because:** The operational cost of maintaining
  two database ecosystems outweighs the benefits of native
  document storage.

### Amazon DynamoDB

- **Pros:** Fully managed, auto-scaling, single-digit
  millisecond latency
- **Cons:** Limited query flexibility, complex data modeling
  for relational data, vendor lock-in
- **Rejected because:** The reporting requirements demand
  complex JOINs and aggregations that DynamoDB does not
  natively support.

## Consequences

### Positive

- Consistent operational practices across all services
- Reduced time-to-production due to existing expertise
- Full SQL support for future analytics requirements

### Negative

- Vertical scaling limits may require sharding strategy
  if growth exceeds projections
- JSONB queries are less intuitive than MongoDB's query
  language for deeply nested documents

### Risks

- If order volume exceeds 500K/day significantly ahead
  of schedule, we may need to implement read replicas
  or table partitioning earlier than planned.

## Related Decisions

- ADR-0012: Event sourcing for order state transitions
- ADR-0014: Use Patroni for PostgreSQL HA

ADR 작성 핵심 원칙

1. 하나의 ADR에는 하나의 결정만 담는다. "데이터베이스 선택과 캐싱 전략"을 하나의 ADR에 넣으면 나중에 검색과 참조가 어렵다. 결정 단위로 분리한다.

2. Context는 결정 당시의 제약 조건을 충실히 기록한다. 시간이 지나면 당시의 팀 규모, 기술 스택, 일정 압박 같은 맥락이 사라진다. "왜 최적의 방안이 아닌 이걸 선택했지?"라는 미래의 질문에 답할 수 있어야 한다.

3. Consequences에 부정적 결과도 솔직하게 기록한다. 모든 결정에는 트레이드오프가 있다. 부정적 결과를 숨기면 문서의 신뢰성이 떨어지고, 추후 같은 문제가 발생했을 때 대비할 수 없다.

4. 상태 관리를 엄격히 한다. ADR의 상태는 Proposed, Accepted, Deprecated, Superseded 중 하나다. 새로운 결정이 이전 결정을 대체할 때는 기존 ADR 상태를 "Superseded by ADR-XXXX"로 변경하고 새 ADR에서 이전 ADR을 참조한다.


Design Doc 구조와 예시

Design Doc의 역할

Design Doc은 RFC보다 구체적이고, ADR보다 포괄적인 문서다. 어떻게 구현할 것인가에 대한 상세한 청사진을 담으며, 코드 리뷰 전에 설계 리뷰를 받기 위한 도구다. Google에서는 모든 중요한 프로젝트가 Design Doc으로 시작하며, 이 문화가 "코드 작성 전에 먼저 생각하게 만드는" 핵심 메커니즘이라고 알려져 있다.

Design Doc 영문 템플릿 (핵심 구조)

# Design Doc: Real-Time Notification Pipeline

| Field            | Value                                          |
| ---------------- | ---------------------------------------------- |
| **Authors**      | Jane Kim, Alex Park                            |
| **Status**       | Approved                                       |
| **Last Updated** | 2026-03-05                                     |
| **Approvers**    | Sarah Lee (Tech Lead), Mike Chen (Staff Eng.)  |
| **Related RFCs** | RFC-0042 (Event-Driven Architecture Migration) |

## 1. Overview

### 1.1 Objective

Build a real-time notification pipeline that delivers push
notifications, emails, and in-app messages within 5 seconds
of trigger events, supporting 100K notifications per minute
at peak load.

### 1.2 Background

Following the approval of RFC-0042, we are migrating from
synchronous notification delivery to an event-driven model.
Currently, notifications are sent synchronously during API
request processing, adding 200-800ms to response times and
creating tight coupling between the User Service and the
Notification Service.

### 1.3 Goals and Non-Goals

**Goals:**

- Deliver notifications within 5 seconds of trigger events
- Support push, email, and in-app notification channels
- Handle 100K notifications/min at peak without degradation
- Provide per-user notification preferences and opt-out

**Non-Goals:**

- SMS delivery (planned for Phase 2)
- Marketing campaign notifications (separate system)
- Real-time chat functionality

## 2. High-Level Design

[Architecture diagram description]

The pipeline consists of four main components:

1. **Event Ingestion Layer**: Consumes events from Kafka
   topics published by upstream services.
2. **Routing Engine**: Determines which channels to use
   based on event type and user preferences.
3. **Channel Adapters**: Deliver notifications via push
   (FCM/APNs), email (SES), and in-app (WebSocket).
4. **Feedback Loop**: Tracks delivery status and handles
   retries for failed deliveries.

## 3. Detailed Design

### 3.1 Data Model

[Detailed schema definitions, API contracts, and
sequence diagrams go here]

### 3.2 API Contracts

[Endpoint specifications with request/response examples]

### 3.3 Error Handling and Retry Strategy

- Transient failures: Exponential backoff with jitter,
  max 3 retries
- Permanent failures: Dead letter queue with alerting
- Channel-specific: FCM token refresh on
  InvalidRegistration errors

## 4. Scalability and Performance

### 4.1 Load Estimates

| Metric                   | Current | Target (6 months) |
| ------------------------ | ------- | ----------------- |
| Notifications/min (avg)  | 10K     | 50K               |
| Notifications/min (peak) | 30K     | 100K              |
| End-to-end latency (p99) | 3s      | 5s                |

### 4.2 Scaling Strategy

- Kafka consumer groups with auto-scaling based on
  consumer lag metric
- Horizontal pod autoscaler targeting 70% CPU utilization
- Email sending rate limiter to stay within SES quotas

## 5. Security and Privacy

- All notification content encrypted at rest (AES-256)
- PII fields (email, device tokens) stored in separate
  encrypted columns
- GDPR compliance: user data deletion propagated within
  72 hours

## 6. Testing Strategy

- Unit tests for routing logic (target: 90% coverage)
- Integration tests with embedded Kafka
- Load test simulating 150K notifications/min
- Chaos testing: Kafka broker failure, SES outage

## 7. Rollout Plan

| Phase | Timeline | Scope                | Rollback Trigger  |
| ----- | -------- | -------------------- | ----------------- |
| 1     | Week 1-2 | Internal dogfooding  | Any P0 bug        |
| 2     | Week 3   | 5% of users (canary) | Error rate > 0.5% |
| 3     | Week 4   | 50% of users         | Error rate > 0.1% |
| 4     | Week 5   | 100% of users        | Error rate > 0.1% |

## 8. Open Questions and Risks

- How should we handle notification deduplication across
  channels?
- What is the retention policy for notification history?

## 9. Appendix

- Link to prototype: [URL]
- Performance benchmark results: [URL]
- Related ADRs: ADR-0015, ADR-0017

Design Doc 작성 핵심 원칙

1. Non-Goals를 명시한다. "무엇을 하지 않을 것인가"를 분명히 하면 범위 확장(scope creep)을 방지하고, 리뷰어가 관련 없는 기능에 대해 질문하는 것을 줄일 수 있다.

2. 숫자를 구체적으로 제시한다. "대량의 트래픽을 처리한다"가 아니라 "분당 100K 알림을 5초 이내에 전달한다"처럼 측정 가능한 목표를 제시한다. 이것이 설계 결정의 기준이 되고, 나중에 성공 여부를 판단하는 척도가 된다.

3. Rollout Plan에 롤백 트리거를 포함한다. 단계별 배포 계획만으로는 불충분하다. 각 단계에서 "무엇이 잘못되면 롤백하는가"의 기준을 수치로 명시한다.


효과적인 영문 표현과 패턴

기술 문서에서 자주 쓰이는 영어 표현

기술 문서는 문학이 아니다. 명확하고 직접적인 표현이 최선이다. 다음은 상황별로 바로 쓸 수 있는 표현 패턴이다.

상황추천 표현피해야 할 표현
제안할 때"We propose..." / "This RFC proposes...""I think maybe we should..."
근거를 제시할 때"Based on our analysis of..." / "Data from Q4 shows...""I feel like..." / "In my opinion..."
대안을 설명할 때"We considered X but rejected it because...""X is bad because..."
트레이드오프 설명"The trade-off is..." / "This approach sacrifices X for Y.""The downside is kind of..."
결정을 기록할 때"We decided to use X." / "The team agreed on X.""X was chosen." (by whom?)
미해결 사항"This remains an open question." / "We need further investigation on...""I don't know about this part."
범위 한정"This is out of scope for this document.""We won't bother with..."
제약 조건"Given the constraint that..." / "Due to the requirement for...""Because of stuff..."

Formal vs Informal 톤 비교

기술 문서에서는 Formal에 가까운 톤을 유지하되, 지나치게 학술적이지 않은 "Professional" 톤이 적합하다.

Informal (피하기)Professional (권장)Too Formal (불필요)
"This is gonna fix the bug.""This change resolves the race condition.""Herein we present a remediation for the aforementioned defect."
"We can just throw in a cache.""We propose adding a caching layer to reduce latency.""It is hereby proposed that a caching mechanism be introduced."
"The old system is pretty slow.""The current system shows p99 latency of 2.3 seconds.""The extant system exhibits suboptimal temporal performance characteristics."
"Let's use Kafka or whatever.""We recommend Kafka for its proven reliability at our scale.""After exhaustive deliberation, the committee recommends the adoption of Kafka."

유용한 문장 패턴

제안의 배경을 설명할 때:

"As our user base has grown from 1M to 10M monthly active users,
the current architecture has shown signs of strain, particularly
in [specific area]."

"Over the past quarter, we observed [metric] degradation,
which correlates with [root cause]."

설계 결정을 정당화할 때:

"We chose X over Y primarily because [reason 1]. Additionally,
[reason 2] and [reason 3] supported this decision."

"While Y offers [advantage], the operational complexity
it introduces outweighs the benefits for our current scale."

리스크를 명시할 때:

"The primary risk of this approach is [risk]. We plan to
mitigate this by [mitigation strategy]."

"If [condition] occurs, we will [fallback plan]."

리뷰 프로세스 설계

리뷰 워크플로우

기술 문서의 리뷰 프로세스가 체계적이지 않으면 문서 품질이 들쭉날쭉해지고, 리뷰가 무한히 길어지거나 형식적으로 끝난다. 다음은 권장하는 리뷰 워크플로우다.

[1단계: Self-Review]
   작성자가 체크리스트로 자가 점검 (1일)
       |
[2단계: Peer Review]
   같은 팀 동료 1~2명이 리뷰 (2~3일)
       |
[3단계: Stakeholder Review]
   영향받는 팀의 Tech Lead가 리뷰 (3~5일)
       |
[4단계: Final Approval]
   승인권자(Staff/Principal Engineer)가 최종 판단 (1~2일)
       |
[5단계: Archive]
   최종 상태 업데이트 후 저장소에 보관

PR Description 템플릿

기술 문서를 Git 저장소에서 관리할 때, PR 자체도 하나의 커뮤니케이션 문서다. 다음은 RFC/ADR 관련 PR을 올릴 때 사용하는 템플릿이다.

## Summary

This PR introduces RFC-0042 proposing the migration of User
Service to an event-driven architecture.

## Type of Document

- [x] RFC (Request for Comments)
- [ ] ADR (Architecture Decision Record)
- [ ] Design Doc

## Key Decisions Requested

1. Should we use Kafka or Pulsar for the event bus?
2. Is the proposed 8-week migration timeline realistic?
3. Are there additional risks we have not considered?

## Reviewers

- @backend-team: Technical feasibility
- @platform-team: Infrastructure implications
- @security-team: Security review of event payload design

## Review Deadline

Please provide feedback by **2026-03-10**. If no objections are
raised by the deadline, this RFC will be considered accepted.

## How to Review

- Focus on the **Alternatives Considered** section first.
- Check if the **Risks and Mitigations** are comprehensive.
- Comment inline on specific sections if possible.

리뷰 코멘트 작성법

리뷰어로서 영어 코멘트를 달 때 유용한 패턴이다.

[질문할 때]
"Have we considered the impact on [X]?"
"What happens if [edge case]?"
"Could you clarify the rationale for choosing X over Y?"

[개선 제안할 때]
"Consider adding a section on [topic] to address [concern]."
"It might be worth including metrics from [source] to
 strengthen the motivation."
"Suggestion (non-blocking): Mentioning the rollback SLA
 would help on-call engineers."

[동의를 표현할 때]
"LGTM - the trade-off analysis is thorough."
"+1 on the proposed approach. The phased rollout plan
 is well-structured."

[우려를 표현할 때]
"I have concerns about [specific aspect]. Specifically, [detail]."
"Blocking: The security implications of [X] need to be
 addressed before we proceed."

글로벌 팀 커뮤니케이션 전략

비동기 우선 원칙

글로벌 팀은 시간대가 다르므로 비동기 커뮤니케이션이 기본이다. 기술 문서는 비동기 커뮤니케이션의 핵심 도구이며, 잘 작성된 문서 하나가 여러 차례의 미팅을 대체한다.

비동기 문서의 원칙:

  • Self-contained: 문서만 읽고도 맥락을 완전히 이해할 수 있어야 한다. "지난 미팅에서 논의한 대로"는 문서에 쓰면 안 된다.
  • Explicit timeline: 리뷰 마감일을 명시한다. "As soon as possible"이 아니라 "Please review by March 10, 2026"으로 쓴다.
  • Decision log: 비동기로 논의가 진행되면 결론이 흩어지기 쉽다. 문서 상단에 결정 사항을 요약하고, 논의 이력을 하단에 타임라인으로 기록한다.

문화적 차이를 고려한 표현

글로벌 팀에서는 직접적인 표현과 간접적인 표현 사이의 균형이 중요하다.

[반대 의견을 낼 때 - 한국어 직역은 피하기]

피하기: "I disagree."
       (너무 직접적이어서 갈등으로 읽힐 수 있음)

피하기: "That might not be the best approach, maybe..."
       (너무 간접적이어서 의견이 무시될 수 있음)

권장: "I see the merit of this approach. However, I have
      a concern about [specific issue]. Have we considered
      [alternative]?"

[동의하면서 보충할 때]
권장: "Building on Alex's point, I think we should also
      consider [additional factor]."

[확신이 없을 때]
권장: "I'm not fully sure about this, but my initial
      read is that [opinion]. I'd appreciate others'
      input on this."

의사결정 매트릭스

여러 대안을 비교할 때 의사결정 매트릭스를 활용하면 논의가 구조적으로 진행된다.

## Decision Matrix: Message Queue Selection

Scoring: 1 (Poor) to 5 (Excellent)
Weight: Importance multiplier

| Criteria               | Weight | Kafka  | RabbitMQ | Amazon SQS |
| ---------------------- | ------ | ------ | -------- | ---------- |
| Throughput             | 5      | 5 (25) | 3 (15)   | 4 (20)     |
| Operational complexity | 4      | 2 (8)  | 3 (12)   | 5 (20)     |
| Team familiarity       | 3      | 4 (12) | 2 (6)    | 3 (9)      |
| Cost at scale          | 3      | 4 (12) | 4 (12)   | 2 (6)      |
| Ecosystem/tooling      | 2      | 5 (10) | 3 (6)    | 4 (8)      |
| **Total**              |        | **67** | **51**   | **63**     |

**Recommendation:** Kafka scores highest due to superior
throughput and strong ecosystem support, despite higher
operational complexity. The team's existing Kafka experience
(score: 4) mitigates the operational overhead.

흔한 실수와 교정

한국 개발자가 자주 하는 영작 실수

1. 주어 생략

한국어는 주어를 자주 생략하지만, 영어 기술 문서에서는 주어를 명확히 해야 한다.

Wrong: "Need to migrate the database before deployment."
Right: "The team needs to migrate the database before deployment."
Right: "We need to migrate the database before deployment."

2. 관사(a/the) 누락

기술 문서에서 관사 누락은 가독성을 크게 떨어뜨린다.

Wrong: "System sends notification to user."
Right: "The system sends a notification to the user."

Wrong: "We propose using cache to reduce latency."
Right: "We propose using a cache to reduce latency."

3. 수동태 남용

수동태가 자연스러운 경우도 있지만, 기본은 능동태다.

Passive: "The configuration is loaded by the service at startup."
Active:  "The service loads the configuration at startup."

Passive: "It was decided that Kafka would be used."
Active:  "The team decided to use Kafka."

4. 불명확한 대명사

Vague:  "When the service calls the API, it returns an error."
        (it이 service인지 API인지 불명확)
Clear:  "When the service calls the API, the API returns an error."

5. "etc." 남용

Vague:  "The system handles errors, retries, etc."
Clear:  "The system handles errors, retries, and circuit breaking."

"etc."는 구체적인 항목을 나열하기 귀찮을 때 쓰는 표현이다. 기술 문서에서는 모든 항목을 명시하거나, "such as"로 예시임을 밝힌다.


운영 체크리스트

RFC 작성 체크리스트

[ ] Summary가 3문장 이내인가
[ ] Motivation에 정량적 데이터가 포함되어 있는가
[ ] 최소 2개 이상의 대안이 분석되어 있는가
[ ] 각 대안에 Pros/Cons가 명시되어 있는가
[ ] Migration/Rollout plan이 단계별로 작성되어 있는가
[ ] Rollback plan이 포함되어 있는가
[ ] Risks and Mitigations 섹션이 있는가
[ ] Open Questions가 정리되어 있는가
[ ] 리뷰어가 명시되어 있고 리뷰 마감일이 설정되어 있는가
[ ] 문법과 스펠링 체크를 완료했는가 (Grammarly 등 활용)

ADR 작성 체크리스트

[ ] 하나의 ADR에 하나의 결정만 담았는가
[ ] Context가 결정 당시의 제약 조건을 충분히 설명하는가
[ ] Decision이 한 문장으로 명확하게 서술되어 있는가
[ ] 고려한 대안과 각각의 기각 사유가 기록되어 있는가
[ ] Consequences에 긍정적/부정적 결과가 모두 포함되어 있는가
[ ] 상태(Proposed/Accepted/Deprecated/Superseded)가 정확한가
[ ] 관련된 다른 ADR이 참조되어 있는가
[ ] 번호 체계가 기존 ADR과 일관되는가

Design Doc 작성 체크리스트

[ ] Goals와 Non-Goals가 명확히 구분되어 있는가
[ ] 성능 목표가 구체적 수치로 제시되어 있는가
[ ] High-Level Design에 아키텍처 다이어그램이 포함되어 있는가
[ ] API 계약(Contract)이 정의되어 있는가
[ ] Error handling 전략이 기술되어 있는가
[ ] Security/Privacy 고려사항이 포함되어 있는가
[ ] Testing 전략이 구체적인가
[ ] Rollout plan에 단계별 롤백 트리거가 명시되어 있는가
[ ] 관련 RFC와 ADR이 참조되어 있는가
[ ] 승인자가 명시되어 있는가

문서 관리 체크리스트

[ ] 문서가 Git 저장소에 버전 관리되고 있는가
[ ] 파일 네이밍 규칙이 일관되는가 (예: RFC-NNNN, ADR-NNNN)
[ ] 문서 색인(index) 또는 카탈로그가 유지되고 있는가
[ ] 더 이상 유효하지 않은 문서에 Deprecated 표시가 되어 있는가
[ ] 정기적인 문서 리뷰 일정이 잡혀 있는가 (분기별 권장)

실패 사례와 개선

사례 1: RFC 없이 시작한 대규모 마이그레이션

상황: 팀이 모놀리스에서 마이크로서비스로 전환하면서 RFC를 작성하지 않고 바로 코딩에 들어갔다. 3개월 후 서비스 분리 기준에 대한 팀원 간 이견이 표면화되었고, 이미 작성된 코드의 30%를 재작성해야 했다.

근본 원인: 서비스 경계(service boundary)에 대한 합의 없이 각자의 해석으로 구현을 진행했다. RFC가 있었다면 구현 전에 서비스 분리 기준과 통신 패턴에 대한 명시적 합의를 도출할 수 있었다.

개선 방안:

  • 2개 이상의 서비스에 영향을 미치는 변경은 반드시 RFC를 작성한다
  • RFC에 명확한 서비스 경계 다이어그램과 API 계약을 포함한다
  • RFC 승인 없이 구현을 시작하지 않는 정책을 수립한다

사례 2: ADR 없이 반복되는 "왜 이렇게 했지?" 논쟁

상황: 2년 전에 선택한 메시지 큐(RabbitMQ)에 대해 새로 합류한 시니어 엔지니어가 "왜 Kafka를 쓰지 않았는가?"라고 질문했다. 당시 결정에 참여한 사람이 모두 퇴사한 상태여서 아무도 정확한 이유를 설명하지 못했다. 결국 1개월간 Kafka vs RabbitMQ 재평가를 진행했고, 분석 결과 당시 선택이 올바른 결정이었음을 확인했다. 하지만 그 1개월은 완전히 낭비된 시간이었다.

근본 원인: 아키텍처 결정의 맥락과 근거를 기록하지 않았다. Slack 대화와 회의록에 단편적으로 남아 있었지만, 체계적으로 정리된 문서가 없었다.

개선 방안:

  • 모든 아키텍처 결정에 ADR을 작성하는 문화를 수립한다
  • ADR을 코드 저장소의 /docs/adr/ 디렉토리에 함께 보관한다
  • 온보딩 문서에 "주요 ADR 목록"을 포함한다

사례 3: Design Doc이 코드와 괴리된 경우

상황: 6개월 전에 승인된 Design Doc대로 구현을 시작했지만, 구현 과정에서 설계가 여러 차례 변경되었다. 그러나 Design Doc은 한 번도 업데이트되지 않았다. 신규 팀원이 Design Doc을 읽고 코드를 이해하려 했지만, 실제 구현과 문서가 완전히 달라서 오히려 혼란만 가중되었다.

근본 원인: Design Doc을 "한 번 쓰고 끝내는 문서"로 취급했다. 구현 중 설계 변경이 발생했을 때 문서를 업데이트하는 프로세스가 없었다.

개선 방안:

  • Design Doc에 "Last Updated" 필드를 포함하고, 주요 변경 시 반드시 업데이트한다
  • 코드 리뷰 시 "Design Doc과의 정합성"을 체크 항목에 포함한다
  • 구현 완료 후 Design Doc에 "Implementation Notes" 섹션을 추가하여 설계 변경 사항을 기록한다
  • 더 이상 유효하지 않은 Design Doc에는 상단에 경고 배너를 추가한다
> WARNING: This design doc was written in March 2026 and has
> not been updated since. The actual implementation may differ
> significantly. Refer to the codebase and ADR-0023 for the
> current architecture.

사례 4: 영어 문서 품질이 낮아 리뷰가 지연된 경우

상황: 한국 엔지니어가 작성한 RFC가 문법 오류와 불명확한 표현으로 인해 리뷰어들이 내용 파악에 시간을 과도하게 소비했다. "What does this sentence mean?"이라는 코멘트가 10개 이상 달렸고, 실질적인 기술 리뷰가 2주 이상 지연되었다.

근본 원인: 영어 작문 품질에 대한 자가 점검 없이 문서를 제출했다. 기술적 내용은 훌륭했지만 전달력이 부족했다.

개선 방안:

  • Grammarly, LanguageTool 등 영문 교정 도구를 필수로 사용한다
  • 문서 제출 전에 영어에 능숙한 동료에게 15분 사전 리뷰를 요청한다
  • 팀 차원에서 "Writing Buddy" 제도를 도입하여 비영어권 엔지니어를 지원한다
  • 자주 쓰는 표현을 팀 내부 용어집(glossary)으로 정리한다

참고자료