Ravendb vs CosmosDB
Tags: nosql, cosmosdb, ravendb, database
Published: 2020-03-12 11:26:20

# Selecting the right NoSQL document database

When it comes to choosing a platform for a new application there is a lot to consider at different levels. For the CTO or Architect the focus is on providing the required scale, resiliency, maintainability, elasticity. And all of it within a certain price range. For the developers, the preference goes to elegant solutions, well integrated with the preferred technology stack and with smooth (pain-free) development experience.

All these factors come into play for selecting the right document-oriented NoSQL database. And for ones using the .NET technology stack or Azure customers, the options may include _Cosmos DB_ and _RavenDB_. Hope that the below comparison between the two popular NoSQL databases will help to make the decision.

# The CTO/Architect point of view

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1e3wkouby3gk1cyze7r3.jpg)

Ploughing your way through all the marketing buzzwords you can quickly determine that both databases have high performance, availability, fully managed and allow unlimited scaling (limited only by your budget). It means the devil is in the details.

## Hosting

The hosting story for _Cosmos DB_ is quite short – _Azure_ only. In exchange it gives a very good integration with the _Azure_ infrastructure.

_RavenDB_ works on the [three major cloud providers](https://ravendb.net/docs/article-page/latest/csharp/cloud/cloud-overview): _AWS_, _Azure_ and _Google Cloud_ (currently in beta). Also [on Docker](https://ravendb.net/docs/article-page/latest/csharp/start/installation/running-in-docker-container) and as a [service](https://ravendb.net/docs/article-page/latest/csharp/start/installation/running-as-service) on Windows, Linux and MacOS (not to mention a _Raspberry Pi_ option). Though, the cloud instance is managed independently from the cloud provider's portal (at own [RavenDB Cloud](https://cloud.ravendb.net) portal), which comes with independent authentication, billing and lack of native automation tools.

It all depends on what you value more – platform independence or _Azure_ integration.

## Pricing

_RavenDB_ has a wide variety of options – a [simple table](https://ravendb.net/buy) for offline licenses and [several pricing tiers](https://cloud.ravendb.net/pricing) for hosting in the cloud allowing some tweaking of the hardware (CPU cores and priority, RAM, storage). The cloud [production tiers](https://ravendb.net/docs/article-page/latest/csharp/cloud/cloud-instances#a-production-cloud-cluster) provide 3 options: _Basic_ with a burstable instance and predefined CPU credits; _Standard_ with pre-allocated resources dedicated to the cluster; _Performance_ – a custom-tailored solution. Either way, at the end you get a flat price with minor extras like Internet traffic costs.

[_Cosmos DB_ pricing](https://azure.microsoft.com/en-us/pricing/details/cosmos-db/) is monotonously based on provisioning throughput expressed in [Request Units per second (RU/s)](https://docs.microsoft.com/en-us/azure/cosmos-db/request-units) plus storage cost. The throughput can be shared across the whole database or be container-based (e.g. per collection, [partitioning](https://docs.microsoft.com/en-us/azure/cosmos-db/partitioning-overview), table or graph). Keep in mind that the provisioned _RU/s_ are used not only for reads and writes, but also for building indexes. Price optimisation is [well documented](https://docs.microsoft.com/en-us/azure/cosmos-db/optimize-cost-throughput) and in spite of some complexity, it provides high flexibility in tuning the resources and applying changes any time through _Cosmos DB_’s REST API.

Due to completely different approaches, it is hard to answer the main question – "_which one is cheaper?_" Perhaps, we could compare _Cosmos DB_ prices with _RavenDB_'s 'Basic' production tier, but it would highly depend on the database design, which can be completely different between the two vendors to gain performance/price benefits. Subjectively, the overall cost would be on par between the two. _Cosmos DB_ gives many options for cost optimisation, but all price benefits can be overturned by the development costs of balancing the containers (more on this later) and some automation for dynamically changing the throughput.

### Free options

Good news is that both vendors give something for free.

_RavenDB_ has a [free Community license](https://ravendb.net/buy) for using locally as a service with some minor constraints and it is absolutely sufficient for testing and development purposes. In addition, there is a very modest free cloud version on AWS (forgive its slowness, it's free) and also an [online testing environment](http://live-test.ravendb.net/studio/index.html) to quickly fiddle with a DB, that would get scraped overnight.

_Cosmos DB_ gives a free [30-day trial](https://azure.microsoft.com/en-us/try/CosmosDB/) to start in the cloud. As for local development/testing, they've got a free [Azure Cosmos DB local emulator](https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator) to run on Windows (no Linux/MacOS) without creating an Azure subscription. Though it has some limitations (like not all consistency levels) it's a good way to spin off a local environment for developers. Alternatively, there is a [free cloud version](https://aka.ms/cosmos-free-tier) with 400 RU/s and 5 GB of storage.

## Security

_RavenDB_ provides a [standard set](https://ravendb.net/docs/article-page/latest/csharp/server/security/overview) including a certificate-based authentication, database encryption, permissions, audit, IP firewall, etc. When _Cosmos DB_ has a bit more [enhanced set](https://docs.microsoft.com/en-us/azure/cosmos-db/database-security), adding more granular user permissions, geo-fencing and role-based access control integrated with Active Directory.

I would question a necessity in so advanced permission settings and other security measures at the database level in the age of microservices. It is common practice of having one database per one [bounded context](https://martinfowler.com/bliki/BoundedContext.html) accessible only via one application/service (again, one per bounded context). So, the database would allow connection from the single source only and the authorisation/authentication concerns would be delegated to the app... But in case you need advanced settings, use _Cosmos DB_.

## Backups & Replication

When it comes to backups, _RavenDB_ does what you need – full and incremental backups, on schedule and on demand, and a straightforward restoration procedure ([link](https://ravendb.net/docs/article-page/4.2/csharp/server/ongoing-tasks/backup-overview)). The DB administrator is in full control of the backups (including location and retention time) and can restore the DB to a previous point in time by a single click. It ticks all the boxes of the usual requirements.

But _Cosmos DB_ does it ... [differently](https://docs.microsoft.com/en-us/azure/cosmos-db/online-backup-and-restore). It hides away the backups and does it automatically every 4 hours, but only the latest 2 backups are stored. To restore, "_you should contact Azure support within 8 hours so that the Azure Cosmos DB team can help you restore the data from the backups_"... Why?!! It may satisfy some amateur users, but for enterprise it sounds less than optimal.

There are [two additional options](https://docs.microsoft.com/en-us/azure/cosmos-db/online-backup-and-restore#options-to-manage-your-own-backups) to manage your own backups, but they come with various constraints and can be considered rather as a workaround than the traditional backup/restore solution.

Regarding replication, _RavenDB_ gives [several options](https://ravendb.net/docs/article-page/latest/csharp/server/ongoing-tasks/general-info) to replicate fully or partially to another Raven database or even a SQL database (with a pre-defined data transformation). Another interesting option is [delayed external replication](https://ravendb.net/docs/article-page/delayed/csharp/server/ongoing-tasks/external-replication) to quickly "go back in time" and undo a faulty change (can be a short-term alternative to a backup). Plus, all cloud production instances [work in clusters](https://ravendb.net/docs/article-page/latest/csharp/server/clustering/overview) (3 nodes by default) to provide redundancy, increased availability and fault tolerance.

_Cosmos DB_ again opts for hiding the concern from the consumers and transparently replicates the data to all the regions associated with your Cosmos account providing eventually consistent reads ([link](https://docs.microsoft.com/en-us/azure/cosmos-db/high-availability)).

Despite all the efforts of the _Cosmos DB_'s marketing team to steer all talks about backups to replication, it can't be a replacement. Backups is a vital safety cushion to protect developers from own mistakes (to revert 'bad' changes) and the owner of the database (e.g. for legal reasons or internal investigations).

This feature is [on the road map](https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/34332178--CosmosDB-be-able-to-manage-backup-and-restore-wi), but with no ETA. Meanwhile, lack of the traditional backup/restore functionality in _Cosmos DB_ can be a real dealbreaker and swing the pendulum in favour of _RavenDB_ for many.

## Resilience to high load

The database may run smoothly until something (or someone) starts challenging its resilience by throwing a high number of requests. Whether it caused by a high number of customers or a malicious DDoS attacker, the system must cope with it.

_Cosmos DB_ [handles high load gracefully](https://docs.microsoft.com/en-us/azure/cosmos-db/optimize-cost-throughput#optimize-with-rate-limiting-your-requests). When the database or container is exceeding the provisioned throughput limit, the server preemptively ends the request with HTTP status code [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) ("Too Many Requests") providing a timeout for a retry. The native SDKs handle it nicely, spitting an exception on exceeding the number of retry attempts. Alternatively, _Cosmos DB_ provides an [Autopilot mode](https://docs.microsoft.com/en-us/azure/cosmos-db/provision-throughput-autopilot) (in preview) for autoscaling provisioned throughput based on workload patterns, but the _RU/s_ under the autopilot are _50%_ more expensive than manually provisioned.

All _RavenDB_'s production instances in the cloud are run in [clusters](https://ravendb.net/docs/article-page/latest/csharp/server/clustering/overview) where each node is self-sufficient. It gives a decent auto recovery from failures, which take some nodes down ([video](https://youtu.be/ijc7j-V2dpQ?t=1397)). On the top of that, handling a peak load depends on the pricing tier. For a less expensive '_Basic_' production tier you get a [burstable instance](https://ravendb.net/docs/article-page/latest/csharp/cloud/cloud-overview#budget-credits-and-throttling) with a certain budget of CPU credit (like provisioned throughput in _Cosmos DB_), where the requests get declined on exceeding the budget. For a more expensive '_Standard_' tier you get a [reserved cluster](https://ravendb.net/docs/article-page/latest/csharp/cloud/cloud-overview#reserved-clusters) with pre-allocated resources, where in case of maxed out CPU and RAM you get slower responses and potential timeouts on the requests.

Seems all good here. Either database would be highly resilient with several strategies in its sleeves.

## Migration Path

Both vendors have solutions for customers migrating from competitors.

At first glance, it may appear that _Cosmos DB_ goes over the top to make the transition as smooth as possible by providing a compatible API and hundreds of articles/videos to guide potential customers to Azure. Apart from the "native" Core (SQL) API, it provides _MongoDB_, _Cassandra_, _Azure Table_ and _Gremlin (graph)_ APIs. On creating a new DB you get to choose one, but you [cannot change it](https://stackoverflow.com/q/57142665/968003) later (only via migrating to another DB). Microsoft keeps the Cassandra API up-to-date, but for some reason support for MongoDB API [stopped at v3.6](https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb-introduction#wire-protocol-compatibility) with [no plans](https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/35324563-support-for-transactions-via-mongo-4-0-api) for later versions.

_RavenDB_ in its turn [gives a way to import data](https://ravendb.net/articles/data-migration-from-CosmosDB-mongodb-sql-to-ravendb) from _Cosmos DB_ / _MongoDB_ and SQL databases (even supports exporting it back to SQL). Sure, it will require a big re-write of the code, but no one migrates to another DB just to change the label (unless you're a believer in amazing cost-reduction stories), likely it's done to leverage some functionality unavailable in the initial database.

Both databases won't disappoint Graph DB users (like [Neo4j](https://neo4j.com) or [OrientDB](https://orientdb.com)). _Cosmos DB_'s Gremlin (graph) APIs supports [Apache TinkerPop's Gremlin](https://tinkerpop.apache.org/gremlin.html) language to simplify migration. Then _RavenDB_ provides [integrated graph support](https://ravendb.net/docs/article-page/latest/csharp/indexes/querying/graph/graph-queries-overview) in its native RQL language, which appears to be [more readable](https://ayende.com/blog/184513-A/graphs-in-ravendb-the-query-language) and intuitive, but will suit greenfield projects only.

## Total score for the CTO/Architect

If you value the Azure integration and costs of developing a 'special' backup solution and the throughput optimisation don't scare you, then go with _Cosmos DB_.

If you need cloud-independence or full control over your data and backups, then _RavenDB_ is your choice.

# The Developer point of view

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v62pefz5keah8xesqk6o.png)

The first thing developers may notice is both vendors support a SQL-like language (`SELECT` operations only) and JavaScript with a handful of extension methods to run on the server-side (ECMAScript [v5.1 in RavenDB](https://ravendb.net/docs/article-page/latest/csharp/server/kb/javascript-engine) and [v6 in Cosmos DB](https://docs.microsoft.com/en-us/azure/cosmos-db/javascript-query-api)). Absence of the traditional SQL-like `DELETE`, `UPDATE` and `INSERT` is compensated by corresponding special commands for individual entries, when bulk operations require custom [stored procedures](https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-write-stored-procedures-triggers-udfs#stored-procedures) in  _Cosmos DB_ and SQL-looking [set-based operations](https://ravendb.net/docs/article-page/latest/csharp/client-api/operations/patching/set-based) in _RavenDB_.

Next one would be consistency. While NoSQL is all about [eventual consistency](https://en.wikipedia.org/wiki/Eventual_consistency), _Cosmos DB_ and _RavenDB_ are flexible enough to provide some flavours of strong (immediate) consistency (different [levels/scopes](https://docs.microsoft.com/en-us/azure/cosmos-db/consistency-levels) in Cosmos DB, or more [explicit waiting](https://ravendb.net/docs/article-page/latest/csharp/users-issues/understanding-eventual-consistency) on writing/reading in _RavenDB_). It is a good start.

Difference between the two databases becomes more noticeable when developers take one step further and start applying the [DDD](https://wikipedia.org/wiki/Domain-driven_design) skills to reflect in NoSQL all carefully designed entities, value objects and aggregates. Convenience of transferring the domain model to the database and ease of maintenance is a big factor affecting overall time/costs of development. Let's use this metric to assess the databases.

## Indexes and Query language

Adding new objects is never an issue – all modern NoSQL platforms provide good integration with all major development environments. All of them are ACID compliant with full support of transactions (more on it for [Cosmos DB](https://docs.microsoft.com/en-us/azure/cosmos-db/database-transactions-optimistic-concurrency) and [RavenDB](https://ravendb.net/docs/article-page/latest/csharp/client-api/faq/transaction-support)). Problems start arise when

- querying data not by the identifier of a document, but various filtering conditions;
- performing bulk operations (e.g. deleting/updating multiple entries at once).

In both cases indexes come into play and they are handled in a special unique way by each NoSQL vendor.

### Cosmos DB

Admittedly, indexes is not the strongest part of _Cosmos DB_. It [does the basics](https://docs.microsoft.com/en-us/azure/cosmos-db/index-overview) and supports 3 kinds of indexes:

- [Range](https://docs.microsoft.com/en-us/azure/cosmos-db/index-overview#range-index) for `>`, `<`, `=`, `IN` clauses, equality match for arrays, string prefix matches and also sorting (single field only).
- [Spatial](https://docs.microsoft.com/en-us/azure/cosmos-db/index-overview#spatial-index) for points, lines and polygons.
- [Composite](https://docs.microsoft.com/en-us/azure/cosmos-db/index-overview#composite-indexes) for sorting/filtering on a combination of fields.

Here is the first pain. Sorting/filtering on multiple fields works only against the [composite index](https://docs.microsoft.com/en-us/azure/cosmos-db/index-policy#composite-indexes) that comes with a [significant constraint](https://docs.microsoft.com/en-us/azure/cosmos-db/index-policy#order-by-queries-on-multiple-properties) – the sequence and order of properties matters:

- The sequence of properties in the index has to match the sequence in the `ORDER BY` clause.
- The ascending/descending order has to either match the order in the `ORDER BY` clause or be fully reversed on all the properties.

[The same](https://docs.microsoft.com/en-us/azure/cosmos-db/index-policy#order-by-queries-on-multiple-properties) is applied to the `WHERE` clause and a combination of `WHERE` and `ORDER BY`.

And that's not it, hold tight. Queries with `COUNT` do not use indexes and perform a full scan ([ticket](https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/36142468-make-count-aware-of-indexes)). Try to use [GROUP BY](https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-group-by) with an `ORDER BY` clause or subqueries – not supported. Need cross-document `JOIN`s? Again, not an option (the [only workaround](https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/6611247-support-cross-document-joins) goes via the Gremlin API). Want to use a string comparison? Mind it is always case-sensitive ([it's recommended](https://stackoverflow.com/a/30513004/968003) to store a "canonicalized" form). Bulk operations via [stored procedures](https://docs.microsoft.com/bs-latn-ba/azure/cosmos-dbhow-to-write-stored-procedures-triggers-udfs)? Remember that the execution can be silently throttled on hitting the limit of provisioned throughput (can run several times to make sure it processes all the records).

Developers will have to steer around such 'features' for most of the usual enterprise applications. Though in some cases, lack of functionality is covered by a decent Azure integration. For example, _Cosmos DB_ does not support full text index/search out-of-the-box, but [Azure Cognitive Search](https://docs.microsoft.com/en-us/azure/search/search-howto-index-CosmosDB) comes to the rescue (for additional [cost](https://azure.microsoft.com/en-us/pricing/details/search/), of course).

### RavenDB

_RavenDB_'s philosophy is different – do as much data transformation as possible in the index, then query against that index. And _RavenDB_'s [indexes support](https://ravendb.net/docs/article-page/latest/csharp/studio/database/indexes/indexes-overview#indexes-types) almost everything you may need:

- The traditional [Map indexes](https://ravendb.net/docs/article-page/latest/csharp/studio/database/indexes/create-map-index) and [Map-Reduce indexes](https://ravendb.net/docs/article-page/latest/csharp/studio/database/indexes/create-map-reduce-index) for complex aggregations of data.
- Single- and Multi-collection indexes, where data can be pulled from several collections. Less need in `JOIN`s in the query, data from other collections get resolved in the index (though, you still can [JOIN in the query](https://ravendb.net/docs/article-page/latest/Csharp/indexes/querying/projections#example-vii---projection-with-a-count-predicate)).
- Tokenized text for [full-text search](https://ravendb.net/docs/article-page/4.2/csharp/indexes/querying/searching) supporting suggestions, [boosting](https://ravendb.net/docs/article-page/latest/csharp/indexes/boosting) and [term vectors](https://ravendb.net/docs/article-page/latest/csharp/indexes/using-term-vectors). RavenDB supports [Lucene](https://wikipedia.org/wiki/Apache_Lucene) out-of-the-box with various [analysers](https://ravendb.net/docs/article-page/latest/csharp/indexes/using-analyzers) and with the [document size limit of 2GB](https://ayende.com/blog/156865/ravendb-net-memory-management-and-variable-size-obese-documents) it eliminates a need in [ElasticSearch](https://www.elastic.co) (that is built over Lucene).
- [Spatial](https://ravendb.net/docs/article-page/latest/csharp/indexes/indexing-spatial-data) indexes for retrieving data based on spatial coordinates with specified precision.
- [JavaScript in indexes](https://ravendb.net/docs/article-page/latest/csharp/indexes/javascript-indexes) for complex data transformation.
- [Dynamic fields](https://ravendb.net/docs/article-page/latest/csharp/indexes/using-dynamic-fields) to allow querying on fields unknown at index creation time.
- [Indexing hierarchical data](https://ravendb.net/docs/article-page/latest/csharp/indexes/indexing-hierarchical-data) for resolving properties of recursively nested objects.

It may appear unusual that `JOIN`s and `GROUP BY`s are handled in the indexes, but it makes sense for minimising querying costs. Anyway, it is a small price for not stumbling over the index related _Cosmos DB_ constraints. Apart from that, the `SELECT` operates as expected – just define the querying properties (either from the collection or the index), add some last minute value transformations (can use JavaScript), [sorting](https://ravendb.net/docs/article-page/latest/csharp/indexes/querying/sorting) (no _Cosmos DB_-like gotchas here), [paging](https://ravendb.net/docs/article-page/latest/csharp/indexes/querying/paging), etc.

Both vendors advertise auto-indexing to ease the learning curve. _Cosmos DB_ [indexes of all the properties](https://docs.microsoft.com/en-us/azure/cosmos-db/index-overview) by default, then _RavenDB_ may generate [indexes in runtime](https://ravendb.net/docs/article-page/latest/csharp/indexes/creating-and-deploying#auto-indexes) for a given query. It may look nice and convenient, but maintenance of unused indexed properties and indexes (e.g. updating them on each change in the collection) will cost extra throughput/IOPS. Therefore, in a real enterprise environment you would not leave indexes unattended and opt to define them explicitly.

## High-level language integration

Both vendors provide SDKs for .NET, Java, Node.js and Python. And both favour the .NET developers more (better documentation, more packages and updates), so let's compare their .NET integration as the most indicative.

### Cosmos DB

The provided SDK is just an unsophisticated wrapper over the API. For a while, even the .NET developers did not have anything better from Microsoft and it sparked a raise of [Cosmonaut](https://github.com/Elfocrash/Cosmonaut) (open source library) to fill the gap. The situation has barely changed after release of [Entity Framework Core 3](https://docs.microsoft.com/en-us/ef/core/providers/cosmos/) last year.

 Surprisingly, Cosmonaut hasn't been ousted by EF Core 3. In spite of being based on an older version of the SDK (a SDK 3 version is [in preview](https://github.com/Elfocrash/Cosmonaut/issues/117)), Cosmonaut is a competitive tool providing handy [extensions](https://cosmonaut.readthedocs.io/en/latest/Reading-and-Querying.html#querying-for-documents-entities), decent documentation and better control over the containers (features like [Collection Sharing](https://cosmonaut.readthedocs.io/en/latest/Collection-sharing.html) for storing different types in one collection). And the EF Core team fairly [admits](https://docs.microsoft.com/en-us/ef/core/providers/cosmos/limitations) limitations of their product:

>Many of these limitations are a result of limitations in the underlying Cosmos database engine and are not specific to EF. But most simply [haven't been implemented yet](https://github.com/aspnet/EntityFrameworkCore/issues?page=1&q=is%3Aissue+is%3Aopen+Cosmos+in%3Atitle+label%3Atype-enhancement+sort%3Areactions-%2B1-desc).

As an example, EF Core 3 _Cosmos DB_ provider [does not support aggregate operators](https://github.com/dotnet/efcore/issues/16146) (`Count`, `Max`, etc.). It seems that `Count` is plagued with problems starting with _Cosmos DB_ itself [not using indexes](https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/36142468-make-count-aware-of-indexes) when counting and draining the _RUs_, so the [best option](https://github.com/dotnet/efcore/issues/16146#issuecomment-543354822) for EF Core 3 is a client-side counting: 

```csharp
query.Select(_ => 1).AsEnumerable().Count()
```

Such limitations do affect structuring the data (entities and aggregates) and add more pressure on the back-end code to handle extra logic.

When it comes to automated tests, the best solution is provided by a third-party package for EF Core ([EfCore.TestSupport](https://github.com/JonPSmith/EfCore.TestSupport)) and works on the top of [Cosmos DB Emulator](https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator), but due to the emulator's constraints it will run on Windows only (can also use Windows containers). Alternatively, it would require mocking DB-related interfaces (e.g. see [this example](https://stackoverflow.com/a/48432085/968003)).

Query execution [metrics](https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-query-metrics#query-execution-metrics) are available in the pure SDK, but accessing them from EF Core or Cosmonaut is not a [trivial task](https://github.com/Elfocrash/Cosmonaut/issues/125).

Integration with other popular .NET packages is quite limited for both, EF Core and Cosmonaut. For example, Dates are [treated as strings](https://docs.microsoft.com/en-us/azure/cosmos-db/working-with-dates) and there are
[no NodaTime](https://github.com/nodatime/nodatime/issues/1477) support.

### RevenDB

_RavenDB_ is designed to describe persistence models and indexes in the code (the Code First approach). Considering very powerful and flexible [indexes](https://ravendb.net/docs/article-page/latest/csharp/indexes/what-are-indexes), ability to maintain them in the code becomes crucial. 

Aggregates defined in a high-level language are neatly transferred to the collections. Take for example [polymorphic data](https://ravendb.net/docs/article-page/latest/csharp/indexes/indexing-polymorphic-data) that can be handled in two ways:
- storing all derived types in one collection;
- storing derived types in dedicated collections, but having a multi-map index combining data from them.

In both cases you can query on a derived or base type/interface and the decision which option to choose would be based on the most common scenario (either querying independently each type or all together). This feature is not flashy, but such subtle options let the developer to structure the data in the most logical way and not getting bogged in bypassing limitations.

The .NET package is native, supports all the features (including a simple way to fetch the [query statistics](https://ravendb.net/docs/article-page/latest/csharp/client-api/session/querying/how-to-get-query-statistics)) and with a decent documentation.

The testing framework ticks all the boxes – a simple package ([TestDriver](https://ravendb.net/docs/article-page/latest/Csharp/start/test-driver)) runs queries against a real in-memory database (leveraging the [RavenDB embedded](https://ravendb.net/docs/article-page/latest/csharp/server/embedded) engine), works on all platforms and provides integration with .NET and Java.

## Community / Tech support

And the last but not the least – community support. It plays a big role when it comes to leaning or resolving technical issues.

_Cosmos DB_ is backed by a giant corporation and just the Microsoft label by itself can lead to [higher popularity](https://db-engines.com/en/ranking/document+store) and bigger community. Imbalance in the number of blog posts and articles between the two (Google gives [100K](https://www.google.com/search?q=blog+%22ravendb%22) search results for _RavenDB_ and [500K](https://www.google.com/search?q=blog+%22cosmos%20db%22) for _Cosmos DB_) is enough for winning someone over via social [conformity](https://en.wikipedia.org/wiki/Conformity).

But apart from that, when it comes to learning and troubleshooting both of them look very similar:

- Documentation is at approximately the same level ([Cosmos DB docs](https://docs.microsoft.com/en-us/azure/cosmos-db/), [RavenDB docs](https://ravendb.net/docs/article-page/latest/csharp)). The _Cosmos DB_'s documentation is mostly focused on the administration aspects, then _RavenDB_ – on coding.
- Number of books is neglectable for both (_Cosmos DB_ - [4](https://www.amazon.com/s?k=cosmos+db&i=digital-text&rh=n%3A133140011%2Cn%3A156117011&dc&qid=1580536744&rnid=133141011&ref=sr_nr_n_1), _RavenDB_ - [3](https://www.amazon.com/s?k=ravendb&i=digital-text&ref=nb_sb_noss)).
- Number of _StackOverflow_ posts is quite small for both ([2,000+](https://stackoverflow.com/questions/tagged/ravendb) for _RavenDB_ and [4,000+](https://stackoverflow.com/questions/tagged/azure-CosmosDB) for _Cosmos DB_)
- Both have prompt and free tech support – on [MSDN](https://social.msdn.microsoft.com/Forums/en-US/home?forum=azureCosmosDB) for _Cosmos DB_ and on [Google Groups](https://groups.google.com/forum/#ravendb) for _RavenDB_. And for both platforms it is the main place for resolving ongoing problems. Small addition – _RavenDB_ provides an [online testing environment](http://live-test.ravendb.net/studio/index.html) for reproducing and demonstrating issues to the tech support.

## Total Developer score

No doubt _Cosmos DB_ creates more buzz in the technical circles, mostly targetting less experienced in NoSQL audience. But from the developer's perspective, _Cosmos DB_ is falling far behind _RavenDB_. Overall and espesially in the .NET environment.

_RavenDB_ is far from ideal, but it gives reliable tools, so developers can focus on achieving the goal rather than finding workarounds.