Thursday, May 17, 2012

Why I Left RavenDB

I've spent the last few months using RavenDB for Presto. I really enjoyed my experience. I fell in love with it for a while. But the more I used it, the more I discovered some things that were hard for me to accept.

It's important to note that I think RavenDB is great for certain scenarios, or for people who don't mind the issues I state below. For me, it just wasn't the right fit. Here's why:

1. The object model is supposed to match the document model in the database. The document model is not how I'm used to dealing with domain entities, and I don’t like that the persistence layer creeps into the domain layer.

2. RavenDB markets itself as “safe by default.” I once thought that was cool, but now I find it limiting. RavenDB only returns 128 documents (rows) by default. One actually has to make an explicit change to get more rows than that.

3. If one makes the change described in point 2, and one wants more than 1024 rows, then another change has to be made on the server side.

4. It is possible to use RavenDB and keep your domain model pure, but that goes directly against the design Zen of RavenDB. And then you have to map documents to your domain model, eliminating one of the main reasons for using it in the first place.

5. RavenDB markets itself as “eventually consistent.” I once thought that was interesting, but now I find it limiting. I don’t want my data to be consistent eventually. I want it to be consistent always.

6. RavenDB’s performance didn't do so well during a prototype.

Raven did have one, big, nice positive: no DB admin work. One doesn’t need to create tables, set foreign keys, etc… It’s a cool feeling to be working with an object variable and just save it. Saves time.

1 comment:

Chris Marisic said...

1. "The document model is not how I'm used to dealing with domain entities" This is your issue, you've been subjected to decades of RDBMS design and can't see outside of blinders you put on. "I don’t like that the persistence layer creeps into the domain layer." I'm with you entirely on this. That's ABSOLUTELY why I use RavenDB. ORMs completely eschew the entire design decisions that are required with document relationships. Relationships between documents is a major design decision, RavenDB requires you to be entirely honest with yourself. ORMs instead lie to you, and let you pretend relationships are an after thought. Do you really honestly believe that marking your entities full of virtual properties so an ORM can dynamic proxy your class ISN'T leaking the database into your domain? My domain objects are my objects, nothing alters them except my design decisions.

2. Safe by default is immensely powerful. These are not sql server table rows, 1024 documents can easily reach multiple megabytes of memory. Very rarely does a person really ever have the capability to consume even over 100 items, let alone 1000 items. For doing bulk export scenarios it does make things slightly more complex, but I'll take those trade offs for safe by design any day.

3. Changing the server to support returning more than 1024 documents per batch IS NOT recommended.

4. I already explained why this bad, you're trying to make RavenDB behave like a SQL ORM which is a complete and total anti-pattern, this is where you're putting persistence behavior into your domain. If you do not do #4, your domain models will be pure agnostic models unlike ORM models.

5. "I want it to be consistent always." Nonsense. Every single system in the entire world has levels of varying consistency. It is completely impossible to ever a system that consistent every single nanosecond forever. There is always lag. Show a user a web page? User 2 changes something, guess what the user 1 is now in an inconsistent state. Once again these are lies to you by ORMs. Most ORMs will not care at all and will just overwrite User2's changes when User1 submits the form. This is lying to you. RavenDB is fully ACID, every single write and every single load action is 100% consistent. This is what matters. This is a feature that is missing from nearly every other NoSQL system.

6. You state nothing about what you tested, how you tested it. Why you concluded it "didn't perform well". I also imagine you probably ended up testing write speed, not read speed. RavenDB is a read orientated database. Almost every single OLTP system on the planet, reads will outpace the writes by orders of usually 1000 to 1.

Your issues stem from fundamental misunderstandings of the technology you're working with. You're looking at blaming the technology because it doesn't behave the way sql server and ORMs do. It's not attempting to behave that way, nor should it. RavenDB was built entirely to solve the relationship of deceit that ORMs create.