"중복은 낭비된 요청만이 아냐. 진실이어야 할 로그에 박힌 두 번째, 틀린 턴이야."
왜 '그냥 다시 보내기'가 공짜처럼 느껴지나 (근데 아냐)
부주의한 재시도가 그렇게 흔한 건, 더블 전송이 데모에선 보통 무해해 보이기 때문이야: 답이 뜨고, 사용자는 행복하고, 아무도 중복을 눈치 못 채. 비용은 진짜지만 미뤄지고 눈에 안 보여 — 딱 견제 없이 쌓이는 종류의 비용이야. 늘어놓으면 '그냥 다시 보내기'가 공짜로 안 보여:
- 중복된 대화 턴. 같은 질문이 canonical 로그에 두 번 들어가. 이제 대화 기록에 유령 반복이 생기고, 모든 미래 컨텍스트 리플레이가 그걸 이어가.
- 이중 모델 지출. 모델에 닿는 중복 하나하나가 두 번째 완전한 추론이야 — 진짜 컴퓨트, 진짜 비용, 사용자가 이미 가진 답에.
- 헷갈리는 UX. 한 질문에 두 답, 어쩌면 약간 다른, 사용자가 어느 게 진짜인지 고민하게 만들어. 클라이언트의 일은 의심을 줄이는 거였지 만드는 게 아니었어.
- 망가진 ground truth. canonical 로그가 진실의 출처일 때, 중복 턴은 겉치레 결함이 아냐 — 진실 자체가 틀린 거고, 파생된 모든 뷰가 그 에러를 물려받아.
로그는 성역; 중복은 그걸 더럽힌다
append-only 로그가 ground truth 인 시스템에선, 그 로그의 무결성이 전부야. 아래의 DB, 검색 인덱스, UI 전부 거기서 다시 지어지니까, 한 번 쓰인 중복이 어디에나 전파되고 되돌리기 아파 — 역사가 이제 두 번 기록한 질문을 깔끔하게 '안 물음'으로 만들 순 없어. 그래서 멱등 재시도가 있으면 좋은 최적화가 아냐. 로그 무결성의 수호자야. dedupe 키랑 호출 전 확인이 존재하는 건, 어떤 불안-네트워크 부산물도 기록 속 영구적 거짓이 못 되게 하려고야.
비싼 손상에 대한 싼 보험
양쪽을 재봐. 멱등성의 비용은 UUID 하나랑 상태 확인 — 몇 줄, 턴당 한 번. 건너뛴 비용은 중복된 역사, 낭비된 추론, 사용자 혼란, 그리고 고치기 비싼 망가진 진실의 출처. 그 한쪽으로 쏠린 거래가, canonical 기록에 쓰는 어떤 클라이언트든 이 규율이 협상 불가인 이유야. 요청을 최적화하는 게 아냐. 불안한 링크가 진실을 망치게 두기를 거부하는 거야.