MattTannahill
MattTannahill

Reputation: 616

Event-Sourcing: Aggregate Roots and Performance

I'm building a StackOverflow clone using event-sourcing. The MVP is simple:

  1. Users can post a question
  2. Users can answer a question
  3. Users can upvote and downvote answers to non-closed questions

I've modeled the question as the aggregate root. A question can have zero or more answers and an answer can have zero or more upvotes and downvotes.

This leads to a massive performance problem, though. To upvote an answer, the question (being the aggregate root) must be loaded which requires loading all of its answers. In non-event-sourced DDD, I would use lazy loading to solve this problem. But lazy loading in event-sourcing is non-trivial (http://docs.geteventstore.com/introduction/event-sourcing-basics/)

Is it correct to model the question as the aggregate root?

Upvotes: 3

Views: 1349

Answers (2)

Dmitry S.
Dmitry S.

Reputation: 8513

With a simple read model it should not be a problem. What is the maximum number of answer you would expect for a question? Maybe a few hundred which is not a big deal with a denormalized data model.

The upvote event would be triggered by a very simple command with a handful of properties.

The event handler would most likely have to load the whole question. But it is very quick to load those records by the aggregate root ID and replay the events. If the number of events per question gets very high (due to answer edits, etc) you can implement snapshots instead of replaying every single event. And that process is done asynchronously which will make the read model "eventually consistent" with the event store.

Upvotes: 0

Dariss
Dariss

Reputation: 1258

Firstly don't use lazy loading (while using ORM). You may find yourself in even worse situation, because of that, than waiting a little bit longer. If you need to use it, most of the times it means, that your model is just simply wrong.

You probably want to think about things like below:

  1. How many answers to the question you expect.
  2. What happens, if someone posted an answer while you were submiting yours. The same about upvotes.
  3. Does upvote is just simply +1 and you don't care about it anymore or you can find all upvotes for user and for example change them to downvote (upvotes are identified).

You probably want to go for separate aggregates, not because of performance problems, but because of concurrency problems (question 2).

According to performance and the way your upvote behave you may think about modeling it as value object. (question 3)

Go ahead and read it http://dddcommunity.org/library/vernon_2011/

True performance hit you may achieve by using cqrs read/write separation http://udidahan.com/2009/12/09/clarified-cqrs/

Upvotes: 5

Related Questions