ADR vs RFC vs design doc: чем отличаются и когда что писать
Каждое неочевидное архитектурное решение через год задают повторно. «А почему мы используем Postgres, а не MongoDB?». «Почему очередь на Redis, а не на Kafka?». «Почему всё в одном репозитории, а не в микросервисах?». Каждый раз это разговор на полчаса с тем, кто принимал решение пять лет назад. Если он уже не работает в компании — разговор не получится.
Решение этой проблемы — фиксировать архитектурные решения в репозитории. Под этим зонтиком живут три похожих, но разных формата: ADR, RFC и design doc. Названия путаются, команды используют их как синонимы, и в итоге на проекте есть «папка с архитектурными документами», в которой всё перемешано. Разберу, чем они отличаются, когда что использовать, и как не превратить процесс в бюрократию.
ADR — Architecture Decision Record
ADR фиксирует одно архитектурное решение в максимально лаконичной форме. Не предложение, не дискуссия, а уже принятое решение, со всем контекстом.
Стандартный шаблон Майкла Найгарда — пять секций:
# ADR-007: Use PostgreSQL for primary storage
## Status
Accepted (2026-03-15)
## Context
We need a primary data store for the user service.
Requirements:
- Strong consistency for financial data.
- ACID transactions across multiple tables.
- Team familiarity (we don't have time to learn new tech).
- Operational maturity (backups, monitoring, scaling).
## Decision
Use PostgreSQL 16 as the primary store.
## Consequences
Positive:
- Team is fluent, no learning curve.
- Mature tooling: pgbackrest, postgres_exporter, pgbouncer.
- ACID transactions out of the box.
Negative:
- Vertical scaling beyond ~100k QPS will require sharding.
- For event-heavy workloads, will need to add Kafka separately.
## Alternatives Considered
- MongoDB: rejected due to lack of multi-document transactions in our use case.
- DynamoDB: rejected, vendor lock-in to AWS.
Свойства хорошего ADR:
- Короткий. Один-две страницы. Не книга.
- Иммутабельный. Принят — не редактируется. Если решение пересматривается — новый ADR со ссылкой «Supersedes ADR-007».
- Хранится в репозитории, рядом с кодом, в папке
docs/adr/илиarchitecture/decisions/. - Нумерация сквозная и не переиспользуется.
ADR — для уже принятых решений. Если вопрос «что выбрать» ещё открыт, ADR не пишут — пишут предложение, обсуждают, и только после консенсуса оформляют ADR.
RFC — Request for Comments
RFC — это предложение, вынесенное на обсуждение. По форме похоже на ADR, но цель другая: получить feedback команды до принятия решения.
Структура RFC обычно длиннее ADR:
- Summary. О чём предложение, в трёх предложениях.
- Motivation. Зачем это нужно.
- Detailed design. Как именно предлагается сделать.
- Drawbacks. Почему может не получиться.
- Alternatives. Что ещё рассматривалось и почему отклонено в первоначальной редакции.
- Unresolved questions. На что нужен ответ команды.
RFC живёт цикл:
- Draft. Автор пишет, ходит в коридоре с ноутбуком, собирает первые мнения.
- Review. Опубликован, открыт для комментариев, обычно 1-2 недели.
- Accepted/Rejected. Команда приняла или отклонила. Если принят — превращается в ADR (или ссылается на новый ADR с принятым решением).
RFC — это процесс, ADR — артефакт. Когда RFC становится «принятым», его не выбрасывают — он остаётся как контекст, но реальный документ-источник правды на проекте — уже ADR.
На моей практике большие команды используют RFC для крупных решений (новый сервис, перевод на новую платформу), мелкие команды могут обойтись без них и сразу обсуждать в чате/PR. Бюрократия RFC оправдана, когда решение затрагивает несколько команд.
Design doc
Design doc — это технический проект, обычно для реализации фичи или сервиса. Он отвечает на вопрос «как мы это построим», а не «что мы выбираем».
Типичная структура:
- Goals и non-goals.
- Background — что уже есть, ограничения.
- Architecture overview — диаграмма, основные компоненты.
- Detailed design — структура данных, API, модули.
- Failure modes — что может пойти не так и как обрабатывается.
- Migration plan — как переходим на новое (если есть существующее).
- Testing plan — как валидируем.
- Rollout plan — как раскатываем.
- Monitoring и alerting — что мерим, на что алертим.
- Open questions — что ещё не решено.
Design doc — самый длинный из трёх. Может быть 10-20 страниц для крупного сервиса. Используется на крупных проектах в Google, Stripe, Notion. Меньше — на стартапах, где скорость важнее формальности.
Главное отличие от RFC: design doc не фокусируется на «выборе между альтернативами». Альтернативы там тоже могут быть, но основа — про то, как реализовать выбранный подход подробно.
Когда что писать
Самый частый вопрос команды, переходящей на формализацию решений.
ADR — пишем, когда:
- Принято архитектурное решение, которое влияет на много мест в коде.
- Решение неочевидное, его будут переспрашивать.
- Решение имеет долгосрочные последствия.
- Решение принято, обсуждение закрыто.
Примеры: «Используем Postgres вместо MySQL», «Применяем soft-delete для всех пользовательских данных», «Все API возвращают JSON, не XML», «Микросервисы синхронно через HTTP, события асинхронно через Kafka».
RFC — пишем, когда:
- Предлагаем большое изменение, нужен консенсус нескольких команд.
- Решение еще не принято, нужно обсуждение.
- Хотим письменно зафиксировать аргументы за и против.
Примеры: «Мигрируем на новый message broker», «Переходим на TypeScript для бэкенда», «Меняем формат API с REST на gRPC».
Design doc — пишем, когда:
- Реализуем фичу или сервис размером больше пары спринтов.
- Нужно согласовать детали реализации с командой.
- Хотим иметь документ для onboarding-а будущих разработчиков.
Примеры: «Сервис нотификаций v2», «Система прав доступа на основе RBAC», «Pipeline для обработки event log-а».
Анти-паттерн: всё подряд через RFC
Команды, которые увлекаются формальностями, начинают писать RFC на каждое решение. «Изменить таймаут с 5 до 10 секунд — заводим RFC». Через полгода у команды папка из 200 RFC, ревью занимает дни, и реальные большие изменения тонут в шуме.
Эвристика: если решение можно изменить за час, не нужен RFC. Если изменение займёт неделю — стоит подумать, нужен ли RFC. Если месяц — RFC оправдан.
Анти-паттерн: ADR-«паспорт»
На некоторых проектах ADR превращаются в формальность ради формальности. На каждый PR с архитектурным изменением — обязательный ADR из шаблона. Через полгода — папка из сотен ADR, в которых половина строк — копипаста заголовков, и никто не читает.
Эвристика: ADR пишется, когда без документа решение будет переспрашиваться. Если решение очевидное и никем не оспаривается («использовать NumPy для математики в Python-проекте»), ADR не нужен.
Хранение и навигация
Все три типа лучше хранить в репозитории, в Markdown:
docs/
├── adr/
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-postgresql.md
│ └── ...
├── rfc/
│ ├── 0001-migrate-to-typescript.md
│ └── ...
└── design/
├── notification-service.md
└── ...
В корне — индексные файлы (README.md в каждой папке), которые перечисляют документы со статусами. Можно генерировать автоматически из metadata в frontmatter каждого документа.
Альтернатива «всё в Confluence/Notion» работает хуже. Confluence-страницы устаревают быстрее, чем команда успевает обновлять. Markdown в репо ревьюится как код, версионируется, не теряется при ребрендинге wiki.
Workflow в виде PR
RFC и большие design docs обычно идут через PR-процесс.
- Автор создаёт branch
rfc/migrate-to-typescript. - Кладёт файл
rfc/2026-XX-migrate-to-typescript.mdсо статусом Draft. - Открывает PR, помечает reviewers.
- Команда комментирует прямо в PR.
- Автор обновляет документ, иногда несколько раундов.
- Достаточно approvals — PR мержится со статусом «Accepted» в документе.
- Если решение отвергнуто — PR закрывается, документ можно сохранить в
rfc/rejected/для истории.
Это работает в командах, привыкших к code review. Если культура ревью слабая, RFC будет либо аппрувится автоматически, либо висеть месяцами без feedback.
Что делать с устаревшими документами
Через несколько лет на любом проекте часть ADR устаревает. Решение пересмотрено, технология заменена, контекст изменился.
Не удаляй устаревшие. Они часть истории. Но обозначь:
# ADR-007: Use PostgreSQL for primary storage
## Status
Superseded by ADR-042 (2026-08-01)
## Context
...
В шапку ADR-042 — обратная ссылка: «Supersedes ADR-007». Так читатель видит цепочку решений и понимает, какое актуально.
Кто пишет
Не «технический писатель». ADR, RFC и design doc пишет тот, кто принял решение или предлагает его — обычно архитектор, ведущий инженер или команда сервиса. Технический писатель может помочь с формулировками, структурой, единством стиля по проекту, но не подменяет автора.
Это важно, потому что суть документа — позиция автора с аргументами. Чужими словами она не передаётся.
Чек-лист, что у вас всё по делу
- Есть папка
docs/adr/в репозитории, нумерация сквозная. - Каждый ADR — короткий, по шаблону Найгарда или похожему.
- Устаревшие ADR помечены Superseded, есть ссылки на актуальные.
- RFC используется для крупных предложений, требующих консенсуса.
- RFC проходит через PR-процесс с явным статусом.
- Design doc используется для проектирования крупных сервисов и фич.
- В индексной странице — список документов со статусами.
- Авторы — те, кто принимает решения, не отдельные писатели.
- Нет «ADR-паспортов» на каждый чих и нет 200 RFC за полгода.
ADR, RFC и design doc — три инструмента под три задачи. Если их использовать осознанно, документация архитектурных решений становится полезным артефактом. Если использовать как взаимозаменяемые или формально на каждое изменение — превращается в свалку, через которую никто не ходит.