Article - 깊게 탐구하기/개발 꿀팁

백엔드 개발자의 의사결정 티어: 어디에 고민을 쏟을 것인가

조금씩 차근차근 2026. 4. 4. 22:00

개발은 코딩이 아니라 의사결정의 연속이다.
 
변수명을 뭘로 할지, DB를 뭘 쓸지, API를 어떻게 설계할지.
하루에도 수십 번의 선택이 쌓여서 하나의 시스템이 된다.
그런데 이 선택들이 전부 같은 무게를 가지는 건 아니다.
어떤 결정은 한번 내리면 2년 동안 팀 전체를 옥죄고, 어떤 결정은 내일 당장 뒤집어도 아무도 모른다.
 
문제는 많은 개발자들이 이 무게를 구분하지 못한다는 것이다.
가벼운 결정에 이틀을 쓰고, 무거운 결정을 점심시간에 "일단 이거로 가죠" 하고 넘긴다.
이 감각의 부재가 기술 부채의 진짜 원인이다.
 
백엔드 의사결정을 네 단계로 나누고, 각각에 얼마만큼의 에너지를 쓰는 것이 적정한지 이야기해보려 한다.


Tier 1. 되돌릴 수 없는 결정

어떤 결정들인가

시스템의 뼈대에 해당하는 결정들이다. 잘못 세우면 살을 아무리 예쁘게 붙여도 소용없다.

  • 데이터 모델 / 스키마 설계 — 테이블 간 관계, 정규화 수준, ID 전략(UUID vs auto-increment), 멀티테넌시 구조
  • 인증/인가 아키텍처 — 세션 vs 토큰, OAuth 플로우, RBAC vs ABAC, 멀티 디바이스 정책
  • 핵심 기술 스택 — 언어, 프레임워크, 데이터베이스 엔진(RDB vs NoSQL vs NewSQL)
  • 도메인 경계 / 서비스 분리 기준 — 모놀리스 vs 마이크로서비스, 바운디드 컨텍스트 경계

공통점은 한번 정하고 데이터가 쌓이거나 외부 의존이 생기면, 변경 비용이 기하급수적으로 올라간다는 것이다.
사용자 테이블 하나의 구조를 바꾸려면 연관된 수십 개의 쿼리, 수백 개의 API, 이미 쌓인 수백만 건의 데이터를 전부 마이그레이션해야 한다.
인증 구조를 세션에서 토큰으로 바꾸겠다는 건 모든 API의 미들웨어를 다시 쓰겠다는 뜻이다.

어떻게 결정하는가

  • 소요 시간: 3일 ~ 2주
  • 참여 범위: 시니어 개발자, 아키텍트, 경우에 따라 CTO나 PO까지
  • 프로세스: 후보안 2~3개 도출 → 각각 간단한 PoC 작성 → 트레이드오프 비교 문서 작성 → ADR(Architecture Decision Record)로 결정 이유 기록

중요한 건 시간보다 관련자의 합의다. 혼자 결정하면 거의 반드시 후회한다.

현실적인 함정

"일단 빨리 만들자"는 압박은 이해하지만, 이때 대충 정한 DB 스키마가 2~3년 뒤에 가장 큰 기술 부채로 돌아온다.
빠르게 가려다 결국 가장 느려지는 아이러니다.


Tier 2. 어렵지만 부분적으로 되돌릴 수 있는 결정

어떤 결정들인가

영향 범위가 넓지만, 추상화 레이어나 어댑터 패턴을 잘 두면 점진적 교체가 가능한 영역이다.

  • API 설계 규칙 — REST vs GraphQL vs gRPC, URL 네이밍, 버저닝 전략(URI vs Header), 페이지네이션 방식
  • 비동기 처리 전략 — 메시지 큐 선택(Kafka vs RabbitMQ vs SQS), 이벤트 드리븐 범위, CQRS 도입 여부
  • 캐싱 전략 — 캐시 위치(로컬 vs Redis vs CDN), 대상(쿼리 결과 vs 연산 결과), TTL과 무효화 정책
  • 트랜잭션 / 일관성 모델 — 강한 일관성 vs 최종 일관성, 분산 트랜잭션(Saga vs 2PC), 보상 트랜잭션

REST로 시작했다가 일부를 gRPC로 바꾸는 건 가능하다.
하지만 버저닝 전략 없이 외부 클라이언트가 붙기 시작하면 이야기가 달라진다.
v1과 v2가 공존하는 지옥이 펼쳐지고, "하위 호환성"이라는 족쇄가 팀을 옥죈다.

어떻게 결정하는가

  • 소요 시간: 1~3일 (의견 충돌 시 최대 1주)
  • 참여 범위: 해당 도메인 담당 개발자 2~4명
  • 프로세스: 슬랙 스레드에 제안 → 댓글로 의견 교환 → 반대 의견이 강하면 30분~1시간 미팅 → 합의 후 간단히 기록

현실적인 함정

"일단 해보고 바꾸자"라는 말의 유효 기간을 조심해야 한다.
내부에서만 쓰는 동안에는 맞는 말이지만, 외부에 노출되는 순간 그 결정은 Tier 1에 준하는 무게를 갖게 된다.
결정의 티어는 고정된 것이 아니라, 의존하는 쪽이 늘어날수록 올라간다.


Tier 3. 비용은 있지만 변경 가능한 결정

어떤 결정들인가

코드베이스 내부에서 리팩토링으로 해결할 수 있는 수준이다.

  • 에러 처리 / 응답 포맷 표준 — 에러 코드 체계, 공통 응답 envelope, HTTP 상태코드 매핑
  • 로깅 / 모니터링 설계 — 로그 레벨 기준, 구조화 로깅 포맷, 트레이싱 전략(OpenTelemetry 등)
  • 테스트 전략 — 단위/통합/E2E 비율, 픽스처 관리, 테스트 DB 전략
  • 디렉토리 구조 / 레이어 분리 — 헥사고날, 클린 아키텍처, 레이어드 등

어떻게 결정하는가

  • 소요 시간: 30분 ~ 반나절
  • 참여 범위: 담당자 1명 + 리뷰어 1~2명
  • 프로세스: 구현하면서 자연스럽게 선택 → PR에 선택 이유 한두 줄 기재 → 리뷰 코멘트에서 한두 번 왕복으로 마무리

별도 미팅을 잡지 않고 PR 코멘트에서 대부분 해결된다.

현실적인 함정

팀 전체가 한번 합의해야 할 사안을 개인의 재량에 계속 맡겨두면, 에러 응답 포맷이 API마다 다르고 로그 레벨 기준이 사람마다 달라진다.
코드는 동작하지만 일관성이 없는 상태. 이것이 느리지만 확실하게 팀의 속도를 갉아먹는다.
프로젝트 초기에 컨벤션 문서 하나만 만들어두면 이후의 고민 시간이 크게 줄어든다.


Tier 4. 언제든 쉽게 바꿀 수 있는 결정

어떤 결정들인가

고민보다 실행이 빠른 영역이다.

  • 라이브러리 / 유틸 선택 — 날짜 처리, 검증 라이브러리, HTTP 클라이언트
  • 개별 알고리즘 / 쿼리 최적화 — 특정 API의 N+1 해결, 정렬 로직
  • 변수명 / 코드 스타일 — 린터와 포매터로 일괄 적용 가능
  • 배포 스크립트 / CI 세부 설정 — 도구가 바뀌어도 개념은 동일

어떻게 결정하는가

  • 소요 시간: 5분 ~ 1시간
  • 참여 범위: 본인 1명
  • 프로세스: 없다. 구현하다 바로 선택하고, 아니면 바꾼다. 코드 자체가 기록이다.

현실적인 함정

의외로 여기서 시간을 잡아먹히는 개발자가 많다.
변수명 하나에 20분, 날짜 라이브러리 비교표를 만드느라 반나절.
이 정도 무게의 결정에 과도한 에너지를 쓰는 건 완벽주의가 아니라 우선순위 감각의 부재다.
"5분 안에 안 정해지면 아무거나 고르고 넘어가기"가 이 티어의 좋은 원칙이다.


결정의 무게에 맞는 프로세스를 태우는 감각

네 개의 티어를 관통하는 원칙이 두 가지 있다.
 
첫째, 데이터에 가까울수록 신중하게, 코드에 가까울수록 과감하게. 코드는 지우고 다시 쓸 수 있지만, 데이터 구조는 그 위에 쌓인 모든 것의 기반이다. DB 스키마를 바꾸는 것과 유틸 함수를 바꾸는 건 같은 "변경"이라는 단어로 묶을 수 없다.
 
둘째, 티어가 올라갈수록 "혼자 고민하는 시간"보다 "사람들과 합의하는 시간"의 비중이 커진다. Tier 4는 혼자 5분이면 충분하고, Tier 1은 혼자서 일주일을 고민해도 부족하다. 무거운 결정을 혼자 안고 있는 것도, 가벼운 결정에 팀 전체를 소집하는 것도 둘 다 낭비다.
 
시니어와 주니어의 차이는 코드 실력이 아니라, 이 무게를 가늠하는 감각에 있는 경우가 많다.
"이건 빨리 정하고 넘어가야 해"와 "이건 한번 더 모여서 이야기해봐야 해"를 구분하는 눈.
그 눈은 경험에서 오기도 하지만, 의식적으로 "이 결정은 몇 티어짜리인가?"를 스스로에게 물어보는 습관에서 시작된다.
 
결국 좋은 아키텍처는 좋은 코드가 아니라 좋은 의사결정의 누적이다.
그리고 좋은 의사결정이란 항상 깊이 고민하는 것이 아니라, 고민의 깊이를 결정의 무게에 맞추는 것이다.