Domain Event를 배우고 나면 자연스럽게 Event Sourcing을 만나게 된다. 도메인에서 일어난 일을 이벤트로 표현한다면, 아예 상태가 아니라 이벤트를 저장하는 것이 더 좋은 것처럼 보인다.
하지만 Domain Event를 사용한다고 해서 반드시 Event Sourcing을 해야 하는 것은 아니다. 두 개념은 관련이 있지만 같은 개념은 아니다.
Domain Event는 도메인에서 의미 있는 일이 일어났음을 표현하는 객체다. Event Sourcing은 현재 상태를 저장하는 대신, 상태를 만들어낸 이벤트의 흐름을 저장하는 저장 방식이다.
이 차이를 구분하지 않으면 DDD가 필요 이상으로 복잡해진다.
일반적인 상태 저장 방식
대부분의 시스템은 현재 상태를 저장한다. 구독을 예로 들면 데이터베이스에는 현재 구독 상태가 저장된다.
subscription_id: sub_123
status: ACTIVE
plan_id: PRO
started_at: 2026-07-01
expired_at: 2026-08-01
구독이 해지되면 상태가 바뀐다.
status: CANCELED
canceled_at: 2026-07-10
이 방식은 이해하기 쉽다. 현재 상태를 조회하기 쉽고, 대부분의 CRUD 시스템에 잘 맞는다.
Domain Event를 사용하더라도 상태 저장 방식을 유지할 수 있다.
subscription.cancelByMember(reason, now);
subscriptionRepository.save(subscription);
eventPublisher.publish(new SubscriptionCanceled(subscription.id(), reason, now));
여기서 이벤트는 후속 처리를 위해 발행된다. 하지만 저장의 기준은 여전히 현재 상태다.
Event Sourcing은 무엇이 다른가
Event Sourcing에서는 현재 상태를 직접 저장하지 않는다. 대신 상태를 변화시킨 이벤트들을 저장한다.
SubscriptionStarted
PlanChanged
SubscriptionRenewed
PaymentFailed
GracePeriodStarted
SubscriptionCanceled
현재 상태가 필요하면 이벤트들을 처음부터 재생해서 만들어낸다.
Subscription subscription = Subscription.replay(events);
즉, Event Sourcing에서 진짜 저장 대상은 상태가 아니라 사건의 기록이다. 현재 상태는 그 기록으로부터 계산된 결과다.
이 방식은 도메인의 변화 과정을 매우 풍부하게 보존한다. “현재 구독이 해지 상태다”뿐 아니라 “언제 시작했고, 어떤 요금제 변경을 거쳤고, 어떤 결제 실패가 있었고, 왜 해지되었는지”를 모두 알 수 있다.
장점: 시간이 남는다
Event Sourcing의 가장 큰 장점은 시간의 흐름을 잃지 않는다는 것이다.
일반적인 상태 저장 방식에서는 현재 상태만 남는다. 물론 이력 테이블을 따로 만들 수 있지만, 이력은 종종 부가적인 기록으로 취급된다. 반면 Event Sourcing에서는 이력이 곧 원천 데이터다.
이 방식은 다음과 같은 상황에서 강력하다.
감사 추적이 중요하다.
상태가 왜 그렇게 되었는지 설명해야 한다.
과거 특정 시점의 상태를 복원해야 한다.
도메인 이벤트 흐름 자체가 비즈니스 가치다.
이벤트를 기반으로 여러 읽기 모델을 만들고 싶다.
금융, 회계, 주문 처리, 복잡한 워크플로우, 협업 시스템처럼 상태 변화의 이유와 순서가 중요한 도메인에서는 매력적일 수 있다.
예를 들어 구독 상태가 CANCELED라는 사실만으로는 부족할 수 있다. 고객이 직접 해지했는지, 결제 실패로 종료되었는지, 관리자가 직권 종료했는지, 환불 후 종료되었는지를 알아야 한다면 이벤트 흐름이 큰 가치를 갖는다.
비용: 복잡도가 크다
Event Sourcing은 강력하지만 비용이 크다. 단순히 이벤트 테이블을 만들면 끝나는 것이 아니다.
첫째, 이벤트 스키마를 관리해야 한다. 이벤트는 시간이 지나도 계속 남는다. 코드가 바뀌어도 과거 이벤트를 읽을 수 있어야 한다. 이벤트 필드를 바꾸거나 이름을 바꾸는 일이 쉽지 않다.
둘째, 상태 재생 로직이 필요하다. Aggregate는 이벤트를 적용해 자신의 상태를 복원할 수 있어야 한다.
subscription.apply(event);
셋째, 조회 모델을 따로 만들어야 하는 경우가 많다. 이벤트 저장소는 현재 화면 조회에 최적화되어 있지 않다.
넷째, 운영과 디버깅이 어려워진다. 중복 이벤트, 순서 문제, 재처리, 스냅샷, 성능 최적화 같은 문제가 생긴다.
다섯째, 팀의 학습 비용이 크다. Event Sourcing은 단순한 저장 방식 변경이 아니라 사고방식의 변화에 가깝다.
따라서 이벤트 소싱은 멋져 보인다는 이유로 도입하면 안 된다.
Domain Event와 Event Sourcing을 구분하기
다시 강조하자. Domain Event와 Event Sourcing은 다르다.
Domain Event는 다음처럼 사용할 수 있다.
subscription.renew(paymentResult, now);
subscriptionRepository.save(subscription);
eventPublisher.publish(new SubscriptionRenewed(subscription.id(), now));
이때 구독의 현재 상태는 일반 테이블에 저장된다. 이벤트는 알림, 권한 부여, 정산 반영 같은 후속 처리를 위해 사용된다.
Event Sourcing에서는 다음이 원천 저장소다.
SubscriptionRenewed
SubscriptionCanceled
PlanChanged
상태 테이블은 없거나, 있더라도 이벤트로부터 만들어진 조회 모델이다.
Domain Event만으로 충분한 시스템이 많다. 모든 상태를 이벤트로 저장하지 않아도 도메인 사건을 명시하고, 컨텍스트 간 결합을 낮추고, 후속 처리를 분리할 수 있다.
언제 Event Sourcing을 고려할까
Event Sourcing은 다음 조건이 강할 때 고려할 수 있다.
상태 변화의 이력이 현재 상태만큼 중요하다.
감사 추적이나 법적 증빙이 중요하다.
과거 시점의 상태 복원이 필요하다.
이벤트 흐름을 기반으로 여러 Projection을 만들 가치가 있다.
도메인 이벤트가 비즈니스의 핵심 언어다.
팀이 운영 복잡도를 감당할 수 있다.
반대로 다음과 같은 경우에는 과할 수 있다.
현재 상태 조회가 대부분이다.
이력은 단순 감사 로그로 충분하다.
도메인 규칙이 비교적 단순하다.
팀이 이벤트 스키마 진화와 재처리 경험이 없다.
운영 복잡도를 감당할 이유가 부족하다.
구독 서비스에서도 Event Sourcing이 반드시 필요한 것은 아니다. 구독 이력이 중요하더라도 일반 상태 저장과 이력 테이블, Domain Event 조합으로 충분할 수 있다.
이벤트 저장보다 중요한 것
Event Sourcing을 도입하기 전에 먼저 해야 할 일이 있다. 도메인 이벤트의 이름을 제대로 찾는 것이다.
SubscriptionRenewed
PaymentFailed
GracePeriodStarted
SubscriptionExpired
PlanChanged
SubscriptionCanceled
이 이벤트들이 도메인에서 실제로 의미 있는 사건인지, 도메인 전문가와 같은 언어로 설명되는지 확인해야 한다. 이벤트 이름이 기술 이벤트에 가깝다면 Event Sourcing을 해도 좋은 모델이 되지 않는다.
SubscriptionUpdated
StatusChanged
DataSynced
이런 이벤트는 너무 일반적이다. 이벤트 소싱의 가치도 떨어진다. 중요한 것은 이벤트를 저장하는 기술이 아니라 도메인 사건을 잘 모델링하는 것이다.
마치며
Event Sourcing은 매력적인 패턴이다. 상태 변화의 모든 역사를 보존하고, 과거를 재생하며, 다양한 읽기 모델을 만들 수 있다. 하지만 그만큼 복잡하고 운영 비용이 크다.
Domain Event를 사용한다고 해서 반드시 Event Sourcing을 해야 하는 것은 아니다. 많은 시스템에서는 현재 상태를 저장하고, 중요한 도메인 사건만 이벤트로 발행하는 방식으로도 충분하다.
DDD의 목적은 이벤트 저장소를 만드는 것이 아니다. 도메인에서 의미 있는 변화를 이해하고 표현하는 것이다. Event Sourcing은 그 표현을 저장의 원천으로 삼는 강력한 선택지일 뿐이다.
먼저 도메인 이벤트를 잘 찾자. 그 이벤트의 흐름 자체가 비즈니스적으로 큰 가치가 있고, 운영 비용을 감당할 이유가 있을 때 Event Sourcing을 고려해도 늦지 않다.