187 comments

[ 2.0 ms ] story [ 254 ms ] thread
This is from 2013 - honest question from someone that doesn't know, is it still relevant?
If you read the post, the problem wasn't Mongo as much as they chose the new hotness (document db/graph model) when in reality their problem was already well solved by a RDBMS and tabular model, they had classic problems like duplicate data and performance issues when they tried to use a document db as a RDBMS.

They changed over and everything was fine.

before: mongodb is bad because it imposes we handle the case where we'd like to shard the db (which breaks joins).

after: mysql is sooo much easier with joins. Who cares about sharding anyway.

I hope people understand distributed systems a bit better today, but I don't have high hopes.

Without any knowledge of mongodb; if using it means you have to handle sharding right away, and using MySQL means you have to handle sharding when you outgrow a single instance, isn't that a big deal? MySQL scales pretty well these days, I think, so you can get a huge box -- a lot of stuff will fit in 2TB of ram.
MySQL can't scale horizontally if you're using it like it's a relational database.

No joins between shards means Sarah Mei could throw away her data model if she needs sharding.

She would then need to denormalize her data to avoid joins, which is the main argument in the article.

The project they were working on was a social network, a free alternative to Facebook. So I guess it's safe to say a single box, even the biggest you can imagine, could not ensure scalability. Beyond certain limits, sharding is the only option.

Facebook has implemented exactly the denormalization despised in the article, and they're using MySQL, albeit just as a dumb key/value store ;-)

I meant scale on a single box, sorry for confusion. It used to not be a great idea to get a really big SMP box to run MySQL because locking would kill performance; I think the locks are fine grained enough these days.
OK, I read it, and that was my reaction as well, but I wasn't sure if it was due to my lack of Mongo knowledge or not. Apparently I understood it! :)

I always struggle with when not to use an RDBMS, because I work with Teradata at the office and so far it hasn't let me down and there's been little pressure to find something new. And my industry (insurance) does not do new for the sake of new.

> Error establishing a database connection

...but this is not a reason to stop using a RDBMS, just a reason to use it in the right places and for the right things. Using it to retrieve objects to fulfill every request is not the proper way. There are caching solutions which shine at performing this task.

...just as there are applications for which a variety of key-value stores shine.

I stopped reading where it said "never".
I'm usually against absolutes, but I'm really in agreement here. It's almost always better to use a relational database, and in the rare cases where you wouldn't want a relational database, MongoDB is the worst of the major options. It literally memory leaks and drops data without warning or provocation. If you're not going to go with a relational database, RethinkDB, Cassandra, Redis, or BerkeleyDB would all be better choices (which one depends on situation).
Do you know which role each of those (RethinkDB, Cassandra, Redis, and BerkeleyDB) excel at?
RethinkDB is targeted at soft real time applications which have a need to update data across many clients. Additionally, although its a schemaless document DB, it offers functionality similar to joins/relational queries. This is a good presentation on RethinkDB: https://www.youtube.com/watch?v=Ee1v_SuECRk
I'd usually start from a problem and choose a store rather than looking at what stores excel at. So I won't speak to places where I haven't seen something solved, but here are some examples:

1. Redis is great for caching in front of a relational database, and also for running task queues. I've used it personally in both cases. Unlike MongoDB it drops data based on cache invalidation criteria, rather than dropping it randomly. Caching is one of the cases other people are proposing MongoDB for, but it's ridiculous to use MongoDB here when Redis exists.

2. Cassandra is used by Reddit and Twitter--search around and you can find lots of good writing about how they use it. Personally I've only used it indirectly via Stream.io.

So you never read articles if they say never?
aka. The Mongodb hater's bible

EDIT: guys, be honest... if this article appears again on HN today, it's because mongodb haters are still alive and well. Downvoting my comment doesn't make the arguments in this article more valid. At least my comment downplays the importance of this article which is on HN's first page, which makes it relevant.

I stopped reading when "Babylon 5" was used in an example.
Is it a joke?

> Error establishing a database connection

Or is it truly an error? In a page that from the title is bashing another DB

Amusingly ironic, eh? ;)
Mildly, but less so when you consider that it's a blog not a product. And even less so when you consider it likely fell over due to load and didn't silently delete the blog data.
No matter the load. A blog is only reads. Any db system should be able to hold up.

It's a different kettle of fish when there's writes; but for reads, it should be a walk through the park.

There's comments on the article, although I doubt the volume of writes there would be troublesome I have no idea really.
And yet many blog dbs fall over under what is ostensibly read-only loads. It could be inefficient connection reuse, shitty disks or it could be something as stupid as writing visitor data on each visit. But it's irrelevant to the main point which is that it's a blog.

This comes up every time a blog falls over that discusses or criticizes a database on HN and it's just as shallow as it ever was. Do we really expect anyone to spend significant time optimizing their blogs for load that may not ever come? We talk about "pre-optimization" and "core competency" routinely on here and then shoot the messenger when a wordpress blog using MySQL falls over that's criticizing something like MongoDB. It's irrelevant to the point of silliness.

It's truly an error. This blog post was written in 2013.
Unfair comparisons aside, no one is "bashing" MongoDB. These criticisms have been levied for years (as the article demonstrates by its byline). These complaints have been levied not just because we should expect more reliability from corporate-backed database products, but because _they run counter to the advertising and technical literature_ that 10gen produced.

It is not "bashing" to say, "I do not like this and by the way, it's unsafe." Especially when the Mongo project has been so resistant to fixing these core issues and instead are happy to sell expensive consulting and training on workarounds for the issue rather than addressing their core technology's issues.

Sorry didn't read the article due to the error and I truly wasn't sure if it was an error or a joke; so from my limited knowledge I wrongly assumed it was an article bashing MongoDB
That particular class of error is caused by bad application programming, not the actual database.
Blank page with "Error establishing database connection."

Is that why you should never use MongoDB? :-)

> Error establishing a database connection

Why you should never use database

I know there is a sense of biting irony here, but it really a valid comment for relatively static sites. Look at the Git based systems out there. If you can generate your site without a tier, generate it without a tier.
Your "I'm better at it than you are" is childish. I can't take you seriously after you post something like this.

Furthermore, again, as stated in the previous discussion, using something badly and not learning the ropes, but then claiming such an awful title is joke-worthy.

"Why you should never use MongoDB" - You mean "Why you should never use MongoDB if you aren't capable of learning how to use it correctly". Infact, just because it doesn't fit your instance doesn't mean it doesn't fit another persons instance.

Awful article.

I think it's ironic that the page says "Error establishing a database connection".

As someone who used MongoDB extensively in the past (8TB+ of data) and also managed the devops side of things, I can tell you straight out that MongoDB has a place in a lot of startup stacks.

I would likely not use it as a main source of truth for any application. However for a lot of things, it's a good database.

Since I can't read the post I can't really address the points made in it, so at this point enough said.

> I would likely not use it as a main source of truth for any application but for a lot of things, it's a good database.

I really don't understand this. In what case is it every acceptable for a data store to lose data? And that's not even MongoDB's only problem: it memory leaks!

I have to say that I did not experience a single data loss that was a result of the database misbehaving.

Memory leaks weren't a huge issue for us as well. After stabilizing the setup I have to say it was basically a fire and forget part of the stack for us.

The role of MongoDB was to act as a fast-insert and aggregation framework for other parts of the system.

So, we would insert BIG amounts of data at a time and aggregate it into a K/V store where we pulled the data from.

After a while, the setup became to expensive to run, at this point we turned it off for a cheaper solution, but in terms of functionality, it functioned pretty well.

Fire-and-forget is awesome for when you do not care at all about your data. I'm sure those types of writes are super (duper) fast. What exactly is the use case for that? Serious question.
Don't know about the guy you replied to, but e.g. consider any application that regularly crawl feeds, api's etc. where the data is rapidly changing and only a portion of the data is necessary to give good output. There are lots of applications like that where you just need "enough" data to give good results and/or where any loss will auto-heal next time you crawl the original source.
That makes sense to me. If your MongoDB cluster under preasure will only actually persist 90% of your writes and this is something you anticipate, then MongoDB seems like a good choice, if writing in this style is faster than other nosql systems (that make grander promises about persistance) that is.
Exactly - the important thing is you need to actually understand the risk, and make an informed decision what level of loss is ok to you (and you should understand whether or not it's actually saving you anything - as you say, it makes sense if it is faster; there's no point losing data if you don't gain something from accepting the risk).

This is also perhaps the biggest problem with MongoDB: It's fast but unsafe "out of the box", and not everyone will know that when they use it. I think that's a large part of the problem a lot of people have with it.

I understand that some data loss is acceptable sometimes, but you can get the super-fast writes with a store that doesn't drop your data at random (such as Cassandra) so why would you choose the store that does?
> I have to say that I did not experience a single data loss that was a result of the database misbehaving.

How do you know? Was your data checksummed? Did you read back changes after writes to verify what was written?

> I have to say that I did not experience a single data loss that was a result of the database misbehaving.

Okay, but numerous people have experienced data loss using MongoDB. You can spend 10 minutes on Twitter and find someone talking about it.

> Memory leaks weren't a huge issue for us as well. After stabilizing the setup I have to say it was basically a fire and forget part of the stack for us.

"After stabilizing the setup"? So basically you worked around MongoDB's stability problems instead of choosing a solution that didn't have stability problems?

> The role of MongoDB was to act as a fast-insert and aggregation framework for other parts of the system.

Sure, but there are other solutions that can do this without MongoDB's issues (i.e. Cassandra).

> After a while, the setup became to expensive to run, at this point we turned it off for a cheaper solution, but in terms of functionality, it functioned pretty well.

Sure, you can build something stable on sand, but it's going to be a lot harder than just building on a solid foundation.

> Okay, but numerous people have experienced data loss using MongoDB. You can spend 10 minutes on Twitter and find someone talking about it.

Never said people didn't.

> "After stabilizing the setup"? So basically you worked around MongoDB's stability problems instead of choosing a solution that didn't have stability problems?

No, I haven't worked around the limitations, after tweaking heap sizes, machine sizes and disk speeds the setup was very stable.

> Sure, but there are other solutions that can do this without MongoDB's issues (i.e. Cassandra).

Again, I DO NOT disagree, there are other solutions and today we are running a completely different setup to replace the same component.

> Sure, you can build something stable on sand, but it's going to be a lot harder than just building on a solid foundation.

I'm trying to ignore the snarky/attacking nature of your comment. Not sure if this is addressable.

Here's one: I have an aggregation engine where 99.99something% of the data is cycled out within 3 days, and where the system can be functional again within about ~5 minutes of ingesting new data after a total data loss.

There are a lot of applications where your database is not the or even a source of truth, but effectively a big cache that you can either fully rebuild or where rebuilding isn't necessary (the data is too "fast moving" for there to be much point).

Here is another: A search engine for classifieds where the source of truth of 99%+ of listings were external feeds that'd get re-crawled at least once a day. If we lost a few million updates, who cared? If it was few enough, we'd just let the normal updates take care of it. If we had a major problem, or needed to do a major update that'd have compatibility implications, we could just do a re-crawl of all the feeds.

Here's another one:

You're scaling reads by replication, and so the vast majority of your data exists in multiple data stores. You may choose one you consider reliable for the source of truth, and the rest are basically caches, but you may want/need something more capable than a straight up key/value store for various reasons.

I believe the vast majority of data stores I've worked with have been ok to suffer a total loss of because most of them are not the source of truth, and the source of truth can be re-queries fast enough for it to not be a big deal to deal with losses in secondary copies.

> There are a lot of applications where your database is not the or even a source of truth, but effectively a big cache that you can either fully rebuild or where rebuilding isn't necessary (the data is too "fast moving" for there to be much point).

This use case doesn't mean it's okay to lose data randomly. Cache invalidation should happen intentionally via an intelligent algorithm, and other data stores (such as Redis) provide this.

> Here is another: A search engine for classifieds where the source of truth of 99%+ of listings were external feeds that'd get re-crawled at least once a day. If we lost a few million updates, who cared? If it was few enough, we'd just let the normal updates take care of it. If we had a major problem, or needed to do a major update that'd have compatibility implications, we could just do a re-crawl of all the feeds.

Just because some data loss is acceptable doesn't mean it's desirable, and while I agree that most of the time some data loss doesn't matter, I don't think you can actually say it never will. What if the 1% listing happens to include an client's feed when the client is doing a major product launch?

> You're scaling reads by replication, and so the vast majority of your data exists in multiple data stores. You may choose one you consider reliable for the source of truth, and the rest are basically caches, but you may want/need something more capable than a straight up key/value store for various reasons.

Again, cache invalidation should happen intelligently via a well-thought-out algorithm, not by randomly dropping data, and there are solutions which supply that.

> I believe the vast majority of data stores I've worked with have been ok to suffer a total loss of because most of them are not the source of truth, and the source of truth can be re-queries fast enough for it to not be a big deal to deal with losses in secondary copies.

Okay, I don't buy this, but let's say it's true. What about the memory leaks?

And what if your needs change, and you're no longer okay with data loss? Are you willing to take the risk that you're going to have to rewrite your storage layer because you chose a data store that drops data randomly, and your needs changed?

First of all, let me make it clear that none of these points are specific to MongoDB. I have used (and do use) it for some projects, and I have used many other storage setups where we accepted risks of data loss. The specific technology doesn't matter.

> This use case doesn't mean it's okay to lose data randomly.

It often does, as long as the frequency is low enough. I've worked on many systems where the decision was explicitly taken to do things in ways we knew would lose data because we could do an easy calculation of "up to x% lost on ingestion will lead to y% increased average increase in updates" and determined that was worth it if it reduced the time spent on a feature or the server costs by a certain amount. It's a completely reasonable tradeoff as long as you can quantify the risk and quantify the cost (here's a tip for something that scarily few engineering organizations does: track not just time spent on projects, but calculate the cost per feature and report on it; it very quickly changes organisational priorities when managers see that what they thought was a minor change ended up costing $10k engineering time)

> and other data stores (such as Redis) provide this

I love Redis, but Redis doesn't offer the same query abilities as document stores like MongoDB. There are plenty of cases where Redis is the better choice, and there are plenty of cases where MongoDB is an option where Redis simply isn't. It depends entirely on the use case.

> Just because some data loss is acceptable doesn't mean it's desirable,

It's never desirable, but other properties of such a change may make the change desirable enough to make it worth dealing with any such data loss.

E.g. I've run platforms putting message queues entirely in memory because the performance / cost reduction was more important than not losing messages in the case of a crash, for example.

> What if the 1% listing happens to include an client's feed when the client is doing a major product launch?

For the case in question it didn't matter at all. Clients would use an XML-RPC call to indicate feed updates, and if they wanted to force re-indexing, they could, and the system adjusted "last ditch" scheduled re-retrievals based on typical update frequency anyway. Or we could force re-indexing too. In any case they had no guarantees of their data being made available on a specific time frame. In practice this was not a problem even once.

This is not hypothetical - we had cases where we restarted servers with said in-memory message queues mentioned above, purging millions of messages without issue, as the system was designed from the outset with the explicit intention that losing data most places was perfectly ok.

> Again, cache invalidation should happen intelligently via a well-thought-out algorithm, not by randomly dropping data, and there are solutions which supply that.

Do you think we just randomly say "oh, lets just lose data for fun?" In each instance I've designed systems like this, it has been a very deliberate choice of determining 1) what the cost and risks of losing data would be. In the above mentioned systems, data was refreshed so regularly, with abilities to do it faster, that the cost was deemed to be extremely low, with virtually no risks (nobody had any guarantees of getting their data into our system). 2) what the costs of avoiding/mitigating the risk of a loss would be.

In these cases, deciding to accept the risk because of the low cost meant that we could opt for less redundancy and fewer servers (e.g. the in-memory queue processing cost us 1/10th as much in server resources as if we hit disk). 3) Other factors: The "cache invalidation" in the case above was the reason for the frequent re-retrieval of feeds. We had no way of knowing whether or not a feed had changed without trying to retrieve it, and we could not depend on the sender supporting E-tag etc. (it was c...

> It's a completely reasonable tradeoff as long as you can quantify the risk and quantify the cost (here's a tip for something that scarily few engineering organizations does: track not just time spent on projects, but calculate the cost per feature and report on it; it very quickly changes organisational priorities when managers see that what they thought was a minor change ended up costing $10k engineering time)

Except it's not a tradeoff: you don't get anything for it that you couldn't get from another data store option. Maybe MongoDB was the only option for some things 5 years ago, but it's not now. There are other options that don't leak memory and lose data.

> Do you think we just randomly say "oh, lets just lose data for fun?"

Basically, yes. You're claiming you weighed the benefits agains the tradeoffs, but I'm saying that you can get all those benefits without making a tradeoff.

>As above: Serves crash. So if your system needs to be available, you need according redundancy. The typical additional scaling cost (accounting for a slightly increased risk of simultaneous restarts, requiring a small amount of extra capacity) of dealing with restarts on resource constraints are often perfectly ok. I tend to design all systems I work on to allow as many components at possible to be restarted at will, because you need to be able to accommodate upgrades etc. anyway. If you first do that, then allowing automatic restarts in the case of failure-types where that is acceptable tends to be trivial.

Of course you should build redundancy into the system, but that's to handle unforseen problems, not to handle problems which you know are there from the start.

No idea about what MongoDB would be good for, but:

> In what case is it every acceptable for a data store to lose data?

This is usually acceptable on analytics data, session data, on most of the "big data" applications... In fact, data that you can not lose whatever happens is the exception, not the rule.

Anyway, when in doubt, it's certainly better to err to the side of security, not risk. Even more because all that security is already written into some middleware that you can simply install and use.

> I would likely not use it as a main source of truth for any application

what the point then ? MongoDB isn't even good for analytics and big data. What do you store in MongoDB ?

Commented above what we used MongoDB for.
I think you use it as a cache, but not what I would define as a database.
Over the last 20 years, the vast majority of databases I have seen have been partly or wholly used as caches in some sense or other.
I'd agree with that - DBs only record things that have actually happened elsewhere in most cases - but if a DB isn't considered reliable as a source of truth (in particular, if it's backed by another piece of software that is considered the source of truth) it's not a database and is a cache.
The placement of the commas in your post is blowing my mind!
Edited my comment for your sanity. I tend to overcomma when I am tired :)
Did you signup to HN just to make a snarky comment on my comma placement?

Not sure if I'm flattered or disturbed by this

Can you give me a few examples of what it's good for? I haven't used it in production, but have researched it a fair amount, and can't find many situations where it would be suitable. Maybe analytics where it's somewhat arbitrary/changing JSON blobs and you don't care about losing individual messages?
"Error establishing a database connection" The irony is thick.
The post should probably be titled "Why you should not pick a technology based on hype and without evaluating it first". While MongoDB has (and probably still has) some flaws and is not the perfect DB system, there are valid use cases where it can be a good choice. Building a social networking site that requires rich queries along a relationship graph is most definitely not one of them.
The HN consensus seems to be that MongoDB is good only for toy projects, and that you should switch to a real database as soon as things start getting more complex.
Actually, when you have a toy project that needs a RDBMS, go ahead and use SQLite.

The consensus is that relatively few applications are a good fit for MongoDB, irrespective of scale.

And for those few where you think MongoDB might be a good fit, you should probably use something like RethinkDB instead.
Or leveldb for those even more trivial storage needs.
(comment deleted)
Why? Now I have to learn a crappier version of SQL (no support for real date types, no user management, etc) and heaven help me if my toy project actual gets traction. I'll have to migrate everything over to Postgres or I'll have to keep my DB on a single server because it's just a single file.

Compared to just using Postgres or even MySQL I do not understand the benefit. It takes less than an hour to spin up a PG database with user permissions and migrations to make tables and indexes.

What's an example of an application that is a good fit for MongoDB?
I actually don't have any experience, but I heard this from wise people:

If you have a file store service, where you're storing relatively big files (big images, videos, etc) and some metadata associated to them which need to be queried.

It's easier to implement than "traditional" solutions (metadata goes in a RDBMS and actual files go to some directory, NAS, or whatever).

Also, apart from being a nicer solution from a programmer's perspective, you'll be able to easily scale horizontally because it supports sharding.

Like I said, I didn't tried this myself so take it with a grain of salt. Also, I don't know how that compares to storing blobs in a RDBMS.

> Also, apart from being a nicer solution from a programmer's perspective, you'll be able to easily scale horizontally because it supports sharding.

Sharding file storage is pretty easy.

On the other hand, I'm not familiar with the MongoDB APIs, but I assume it doesn't support handing a socket file descriptor from the webserver over to MongoDB so Mongo can sendfile(2) the data directly from the kernel's page cache to the TCP socket for locally resident data.

With the files stored directly on disk and metadata in an RDBMS, your webserver can sendfile(2) those files that are permanently stored locally or cached to local disk, and act as a proxy for other shards. Extra context switches and coping your data one or two times more than necessary can add up quickly.

If you have a fairly complex object structure that is logically a single unit, and you only need/want to query on a small number keys. Or anytime you might think "It would be better to just serialize this and shove it into a VARCHAR column."

eg, the rate structure for a vacation rental. The fancier ones (not AirBnB) can have lots of different seasons, stay durations, various upcharges/discounts, etc. It's difficult to model in SQL, and even if you could it's not usually useful. Dealing with the entire thing as a single document just makes more sense.

Another example: if you need to handle data that your app doesn't really own. eg, you're going to read it, maybe wrap it up with some other data, and pass it on. In that case being able to handle and store that data as a mostly-opaque blob is handy.

Of course that's an argument for a document DB in general, not Mongo in particular. Dynamo, Rethink, etc might be better choices.

I think the consensus is closer to: use Postgres unless you have a very good reason to use something else. SQLite good for dev and toys.
Tldr; They tried to use a relational data model in a document database and failed.

I am not sure the author realize that a relational model is actually a graph.

My first introduction to databases was with PHP/MySQL, where normalization was the name of the game. The whole point of normalization is that there is no duplication of data anywhere. If it's possible for duplicate data to exist, that's a symptom of a design flaw in the schema.

I've been using Mongo recently, and every time I raise criticism of it, the counterargument I hear is "forget about normalization! Duplication is okay."

Like the author, I really cannot wrap my head around this. While I understand that duplicating documents across collections may make querying faster, what about when you want to change the document? You need to propagate the change across every duplicate of the document in every collection where it exists. This means that any "de-duplication" logic needs to happen at the application level, rather than the database level.

Parse.com provided an interesting abstraction around that with "cloud code" and beforeSave and afterSave triggers. To maintain consistency, they encourage propagating updates to a document within its collection's beforeSave function. So if a document changes in one collection, you write code to change all instances of the document in other collections. That's nice in that it almost feels like you're writing the dedeuplication logic in the database layer, because you can view the "beforeSave" and "afterSave" functions as extensions of the schema. As long as those functions are up to date, the schema and any pseudo-linked documents will stay up to date.

But I really don't buy it. The strengths of mongo encourage a design that necessitates complexity for any significant write operation.

I think the real issue is that "if you have a hammer, everything looks like a nail." Mongo and other NoSQL stores have some real use cases, but people who are more familiar with Mongo than RDBMS are too trigger happy to employ it as a solution to problems where a RDBMS is the clear solution.

It has always seemed to me that the solution to the duplication/normalization dilemma is an approach that gets "normalized" data (not necessarily normalized in the sense that it is scattered among many tables, but in the sense that there is a single source of truth for each data point) and uses it to write materialized views, automatically and efficiently recomputed and stored for fast querying.

CouchDB does this to a certain extent, but its JSON-document approach is not appropriate enough.

Have a look at RethinkDB, it's the best of MongoDB and MySQL with real time feeds. A relational document store.
(comment deleted)
I've always looked on 'duplication' (or denormalization) as an optimization to be used sparingly when performance dictates.

Regarding it as essentially a form of caching has been helpful. In fact there is a spectrum that goes from simple caching to denormalized schema with many points inbetween.

While not a fan of mongoDB for many reasons, any sufficiently large scale application will have denormalization. Caching layers cause all sorts of cache invalidation bugs because of this exact problem. Indexes, while often managed by the DB, are essentially denormalization. One could even argue that syncing data between a client and server is a class of the same problem.

My point is that we deal with these problems out of necessity. If you don't get a ton of traffic, then sticking with a normalized RDBMS is probably best. However, large scale systems will have redundant logic. Generic solutions (letting the normalized DB do the work) will often be slower than specific ones (denormalizing your schema and moving logic into the application layer). These are pretty simple principles that I've seen on almost every large-scale application I've worked on.

If you excuse the buzzword, data warehouses are built for this very reason. So you are right in the sense that cache invalidation and denormalization are problems in sql based large scale systems, but they are largely solved problems whereas in mongodb you would need to do this work manually.
> [...] data warehouses are built for this very reason. [...] [cache invalidation and denormalization] are largely solved problems [...]

Uhm, no. Data warehouse is not a database with operational (i.e. current) data, it's a database with historical data. If it is out of sync with production for a day or a week, it's totally OK, depending on its design.

So no, cache invalidation is not a solved problem there.

dozzie, could you remove the "Uhm, no." from that? It only adds snark to an otherwise good comment.
I've worked with data warehouses which were replicated like a multimaster, YMMV.
Indexes are not an example of denormalization. Normalization means that there is one canonical element that describes an object, not that there's only one copy or representation of that element.
Indexes are basically a copy of the original data, only sorted in the right order.

They are denormalized data, sort of.

Indexes are often only a pointer to that data, and they are not denormalized, they are better described as projections of your data (this way saving the work of ordering/filtering on that same projection in the future.)
Not only that, they're projections which you don't have to spend effort on keeping up to date, and which the engine automatically uses to optimize your queries. While there's an argument to be made that the same can be accomplished in a non-relational database with suitable application code or a translation layer, all else equal it's better not to need those things in the first place.
And as we saw from a recent Uber post about Postgresql, that automatic updating is not actually free.
Was going to say the same, but I realized the OP was talking about in your code, not so much as overhead.
Of course it's not, but if you're not Uber, that almost certainly isn't a problem for you. When you use MongoDB, you get to roll your own indexes no matter who you are.
Yes, they are pointers. But the indexed fields have to be duplicated for efficient reading. From Wikipedia:

"An index is a copy of select columns of data from a table that can be searched very efficiently that also includes a low-level disk block address or direct link to the complete row of data it was copied from." [1]

When you reference a field in an index, you're effectively duplicating this column on disk.

We can discuss semantics, but at the end of the day, indexes are glorified copies of your columns in a specific order.

[1] https://en.wikipedia.org/wiki/Database_index

Are you suggesting that RAID-1 and RAID-5 are also examples of denormalized data, sort of?
Not really, for two reasons:

- It's done at the hard disk level, so no database or data schema is involved.

- It's not done for performance reasons, but for security reasons (not to lose any data).

"In computing, denormalization is the process of trying to improve the read performance of a database, at the expense of losing some write performance, by adding redundant copies of data or by grouping data."

It's a technique that involves copying data for some very particular reason, an abstraction to hide the nasty duplication because the desirable thing is to have only one source of truth.

So while there's some remote similarity (the copying of data), the goals are completely different.

A good RAID controller exactly fits your included quote. It will speed up reads by distributing to all disks, but writes will be slower because they have to be written to all disks before the controller will signal the write as completed.
What you're really after is materialized/indexed views, or having the NoSQL DB be a layer after your primary DB...
This is a problem I've had to explain to too many developers recently. It's not faster just because you throw away data modeling practices and jam bits of info all over the place.

If you have semi normalized data relationships, Mongo really doesn't fit the bill that well as your primary data store.

Where it shines is when you've got computed pieces of data to display (parts of a user data feed for example, data for a live graph, etc), you want to quickly store some data to be processed later (analytics, event processing), or you just use it as an object cache for expensive queries.

I have found that with a decently tuned DB, and I mean barely tuned, a decent data model, and sane fetching strategies (don't eager load everything always), a database can be good enough for quite a while, if not forever.

The answer I pretty much always get from people when I ask, "Why did you start with (whatever NoSQL they chose)?" Is, "Because (whoever) said it's faster and scales better."

I think younger devs that have options besides relational DBs find the barriers to entry on NoSQL lower (it looks mostly like how it went in and it's just JSON) so they pass over the learning SQL and basic data normalization fundamentals.

I agree with you, but would like to add that by using SQL to query a relational database it is very, very easy to denormalize the data that is copied into an application, so while a relational schema is essentially "static", query results are very dynamic, and can easily strip away all of the "goodness" that results from a normalized data structure.

In other words, the application probably needs to deal with normalization and schema if it's taking copies of data, and using a relational database doesn't remove this requirement. (Of course, small applications often get away without enforcing schema, with the understanding that frequent database write failures due to malformed data are ok.)

> find the barriers to entry on NoSQL lower

Not having to think rigorously about the logical structure of your data is a huge selling point for many. For programmers, because it means they don't have to think. And for employers, because it means they can make do with programmers who don't want to think.

That is a scary thought.
Only scary if you are locked into the past and/or closed-minded. (disclaimer: I'm not a mongo fan).
I was mainly referring to "And for employers, because it means they can make do with programmers who don't want to think."

Sorry, but I don't want to work in an environment where programmers don't want to think or don't have to think. That is a scary thought. Has nothing to do with being locked into the past or being closed-minded. Just the opposite actually.

How else do you think we arrived at webpages that need hundreds of MB of RAM?
It isn't that scary once you take into account the fact that our brains are just as finite as any other resource available to us. It's a virtue not to make more mental effort than what is strictly necessary to complete the task at hand.
I agree with "It's a virtue not to make more mental effort than what is strictly necessary." but to have an environment with only "programmers who don't want to think" is not appealing at all to me. I personally want to be surrounding by thinkers.
> Not having to think rigorously about the logical structure of your data is a huge selling point for many

I'll play the devils advocate: what ever logical structure of the data you come up with will not line-up with relational DB tables - I have had the pleasure of designing relational schemas for cyclic graphs. Hell, we have been trying and failing to do Object-Relational Mapping for years now, and it's still a shit-show. I could name a long list of ORM libraries and an even longer list of their various deficiencies.

Say you've thought rigorously about the logical structure of your data and v1 is out, and now a change comes along and you need an extra field or 5. Renormalize your structure, write some migration scripts (in both directions, just in case you want to downgrade). With NoSQL I'll just dump the new document structure and call it a day (or rather, deal wiht the differences in the application layer).

I suspect you read too much into my comment. I wasn't making a value judgment. If anything, I'm actually in favor of thinking no more than necessary to get high-quality results - but also no less than that.

> I'll play the devils advocate: what ever logical structure of the data you come up with will not line-up with relational DB tables

That contradicts my experience. The relational model isn't a panacea, but it lets me model most scenarios adequately. Whenever the relational model is deficient, what I want is more powerful schemas (sum and product tables, constraints spanning several tables, etc.), not less.

> Hell, we have been trying and failing to do Object-Relational Mapping for years now, and it's still a shit-show.

I'm inclined to think the problem is actually at the object-oriented end of the bridge: https://news.ycombinator.com/item?id=11861520

> With NoSQL I'll just dump the new document structure and call it a day (or rather, deal with the differences in the application layer).

Correctly managing these differences without help from schema-aware tools is rather painful.

> The answer I pretty much always get from people when I ask, "Why did you start with (whatever NoSQL they chose)?" Is, "Because (whoever) said it's faster and scales better."

Pretty much the classic http://www.mongodb-is-web-scale.com/?

Why does this comment feel like an ad?
An ad for what, Parse.com? It doesn't even exist anymore, lol.
>"Like the author, I really cannot wrap my head around this. While I understand that duplicating documents across collections may make querying faster, what about when you want to change the document? "

That's a trade-off you have to analyze to see if it is worth it. If that data is not maintained often then is OK to have duplicated data. One thing you have to realize is that there is no a silver bullet in the CAP theorem and you always would give up something.

The other thing to realize is that not everybody needs a distributed database and most problems will live happily with an old-fashioned relational database.

There are two paradigms with databases. Normalization for high volume insert/update transaction requirements (faster writes). Denormalization for (faster reads), typically used for data warehouses and reporting.

NoSQL is designed to support both of these scenarios well. And with lower overhead requirements by not having to update a central store... It is used in particular for Big Data solutions. Rather than having to be optimized for one or the other as an RDBMS would require.

Not being optimized for a particular use case, makes it a poor choice for anything outside toy, or best case, medium sized applications.
The point is you have the level of control that lets you optimize for your use case. RDBMSes are a jack-of-all-trades solution and have the advantage of needing very little customization, but they can't be as well-optimized for specific use cases.
> Normalization for high volume insert/update transaction requirements (faster writes). Denormalization for (faster reads), typically used for data warehouses and reporting.

Normalization also better supports ad hoc inquiries and reporting compared to denormalization; denormalization is an optimization for regularized reporting patterns (responding to a question that a denormalized reporting design didn't anticipate often requires effectively renormalizing the data, which recovers the logical benefits of normalization, at a potentially very high performance cost.)

> NoSQL is designed to support both of these scenarios well.

Without the integrity benefits of normalization on updates, and without the benefits of normalization for ad hoc queries.

OTOH, there are very few uses of normalized RDBMSs where only the write performance benefits are sought -- usually at least integrity is a concern, and sometimes ad hoc querying as well.

> Like the author, I really cannot wrap my head around this. While I understand that duplicating documents across collections may make querying faster, what about when you want to change the document? You need to propagate the change across every duplicate of the document in every collection where it exists. This means that any "de-duplication" logic needs to happen at the application level, rather than the database level.

You're assuming that you need to change things. Almost all big-data approaches work better when you abandon that and go for a log-structured model where you only ever append.

> I think the real issue is that "if you have a hammer, everything looks like a nail." Mongo and other NoSQL stores have some real use cases, but people who are more familiar with Mongo than RDBMS are too trigger happy to employ it as a solution to problems where a RDBMS is the clear solution.

True enough, but I think the converse is more true. If you're using a traditional RDBMS you're accepting a big series of constraints in exchange for functionality you often don't use. Indices are updated synchronously on every insert, slowing your writes, for the sake of transactional guarantees that most applications aren't written to take advantage of. Queries have to be passed over the wire as strings, so your application will spend a significant chunk of its time building them (hopefully using a library without vulnerabilities to send them over the wire so the database can spend a significant chunk of its time parsing them), or else you get to deal with the db-specific and per-connection quirks of prepared statements, for the sake of supporting ad-hoc querying in a language that frankly isn't great for humans. Tables, materialized views and the like occupy this awkward in-between condition where it's not clear whether you're supposed to create and modify them ad-hoc (and manipulate them programatically) or not; if you really do need to do ad-hoc reporting then they're what you want, but often the performance implications of that make it unacceptable to do in production.

I don't think a lot of cases are good fits for RDBMS. If you don't need ad-hoc reporting then you're better off building a data processing pipeline where you produce your results directly rather than the sort of semi-aggregating you end up with with an RDBMS. If you don't need full ACID then it's not worth paying the performance cost of it. And I don't know why there aren't RDBMSes without better query languages and schema definition languages, but there aren't.

Indices are updated synchronously on every insert, slowing your writes, for the sake of transactional guarantees that most applications aren't written to take advantage of. Queries have to be passed over the wire as strings

Those are implementation details, not inherent properties of the relational model.

If they're pervasive then it's irrelevant. Looking at this stuff from a purely academic viewpoint isn't useful to people who care about implementation details.
> You're assuming that you need to change things. Almost all big-data approaches work better when you abandon that and go for a log-structured model where you only ever append.

That depends on your loads. If you're write heavy, then yes. If you're read heavy, then you're adding extra work to find the current row out of all the appends. If you're read and write heavy, then get used to buying really expensive beefy machines and maybe sharding...

>>Queries have to be passed over the wire as strings, so your application will spend a significant chunk of its time building them... or else you get to deal with the db-specific and per-connection quirks of prepared statements...

Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like.

>>I don't know why there aren't RDBMSes without better query languages and schema definition languages Huh... I always thought SQL was pretty straightforward for most cases. It only gets really arcane when you get into advanced cases (eg, recursive queries) and/or vendor extensions. It does take a bit of a mental shift, but no more so than imperative-style to functional-style, IMO.

There are certainly tradeoffs to using an RDBMS. But I think a lot of people jump to the conclusion that they have a big-data situation when they really don't. I also think a lot of people underestimate the value of very easy ad-hoc querying and already-solved backup/restore.

> Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like.

The trouble is testability, versioning, deployment, and SQL just not being a pleasant language for expressing business logic. And the lack of a library ecosystem. And poor IDE support. And...

>>SQL just not being a pleasant language for expressing business logic

No kidding - don't do that. Sprocs are great to present a query interface and avoid sending queries over the wire every time. They can be handy to decouple the actual storage architecture from the query interface, so you can do tricky stuff in SQL without screwing up the clients. That doesn't mean you should stick your business logic in there.

>>testability, versioning, deployment... library ecosystem...

And how would any of those problems be solved by using raw SQL strings or a document DB? That just moves the problems back into the schema or the data, where it's even harder to deal with.

>>poor IDE support

So your code editor has a better IDE for SQL? Or are we talking about a document DB? I haven't seen any of them that were anywhere close to SSMS.

> And how would any of those problems be solved by using raw SQL strings or a document DB? That just moves the problems back into the schema or the data, where it's even harder to deal with.

I'm arguing for using a non-SQL interface. Either a structured binary query protocol (which leaves you shipping a lot of data around sure, but at least removes the constructing-and-parsing SQL overhead), or a map-reduce style setup where you can run your queries where the data is but in a first-class programming language.

It seems to me that you're advocating changing implementation details (binary query protocol instead of SQL, map-reduce queries instead of sprocs) and claiming that it is somehow fundamentally different. But I don't see how that would be the case.

How is a binary query protocol fundamentally different than calling a sproc?

How is a map-reduce job in Javascript any different on the attributes you mentioned than ad-hoc SQL or a sproc?

Obviously map-reduce is a fundamentally different approach to data processing, but it seems to have similar traits in regards to source control, testability, etc.

Binary query protocol is just a tweak, but it's a tweak that most RDBMSes are missing, and it matters for some workloads.

Switching to a model where you supply your own map-reduce or pipeline is a real shift, I think, from the DB as a framework that manages querying for you to more of a library/toolkit you can use to write your own computations. The indexed tables model is an incredibly effective compromise, but it's still a compromise - if you know specifically what you need to do, you can do it better.

Running a first-class programming language with full support for usual programming language tools is a major difference for developability, testability, libraries and so on. Deployment model depends on the datastore - plenty of non-SQL ones have room for improvement here - but I think the traditional RDBMS still has the worst of it.

Huh, interesting. I wonder if this is down to us having used different RDBMSes?

Most of my experience has been with SQL Server, which I think does use a (mostly) binary wire protocol, at least when calling sprocs. It also has a pretty good query optimizer - I've spent a lot of time trying to beat it with hand-tuned queries and only come up with something better about 50% of the time. And there are a lot of tools for source controlling the DB scripting and testing everything. It's not hard to do unit test style runs that set up and tear down tables and DBs.

Has that not been your experience?

> which I think does use a (mostly) binary wire protocol, at least when calling sprocs

Hmm. I'm used to invoking storedprocedures via "select mysproc(param1, param2, ...)" which still has to be formed into a string and then parsed on the DB side using the arbitrary-SQL parser (because there's no way for the DB to know a priori that it's not a "regular" query). Does SQL server have some special case binary protocol for invoking them directly?

> It also has a pretty good query optimizer - I've spent a lot of time trying to beat it with hand-tuned queries and only come up with something better about 50% of the time.

The query planner can usually run the best query possible with the indices that exist, sure. But you have to fit your calculation into this model of indices that are built on insert and everything else happening at query time. Or you go down the route of lazy materialized views that make use of other lazy materialized views, specifying indexing strategies... I mean I think you can ultimately express any data processing pipeline in a RDBMS if you try hard enough (though you have to use database-specific features that tend to be less-well supported by the ecosystem), but at some point it's easier to just have a first-class programming language that has access to the data, and write the code that you want to run.

> And there are a lot of tools for source controlling the DB scripting and testing everything. It's not hard to do unit test style runs that set up and tear down tables and DBs.

Up to a point. It's easy to end up with "unit" tests that take a second for each test, which mean it's not really practical to get good coverage of logic there.

In terms of source controlling and so on I guess the big problem is that you now have a distributed system written in two quite different technologies. So you've got to figure out a release and deployment process that handles both, and a lot of shops don't seem to bother. If you're already running a multi-language microservice architecture then this is probably a lot less of an issue.

TBH I've never really looked at how TDS (the SQLServer wire protocol) works. From a code level, in ADO.NET you would create a query object, set the type to "sproc", set the name of the sproc, and attach parameters as objects. I bet the sproc name is going across as text, and maybe the param names, but that's probably it.

>>So you've got to figure out a release and deployment process that handles both, and a lot of shops don't seem to bother.

Yeah, that's true. Setting up something along the lines of Rails' migrations isn't really that hard, but many don't bother.

> > Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like.

> The trouble is testability, versioning, deployment, and SQL just not being a pleasant language for expressing business logic.

Most of those, to the extent they are valid, are trouble with using stored procs in SQL for that purpose, but most RDBMSs support stored procs in languages other than SQL.

Testability, versioning, deployment, IDE support and library support are still very much issues with non-SQL stored procedures.
> And I don't know why there aren't RDBMSes without better query languages and schema definition languages, but there aren't

Well, better is subjective, but there are RDBMSs with languages other than SQL (e.g., Dataphor with its D4 language.)

It's a trade-off. There are a lot of reasons to duplicate (faster reads, etc.), with the big drawback being consistency. The duplications are basically caches, with similar pros and cons.

I think a good solution is to use something like DynamoDB and use hot/cold tables. Like, if you're storing something high read/write (i.e. today's olympic stats), keep it in the hot table with a frequent cache timeout. Later, when they become yesterday's stats, move them to the cold table which will basically be read-only, with a longer valid cache.

The problem with MongoDB is that it discourages this type of data management, at least how I've seen it used.

If it's like Cassandra, then you can kind of get around consistency problems by, for instance if you have a "replication" factor of 2, by instructing it to write to "2 instances before returning" (and then you turn around and read it after that, if you want to double check). Though of course while it's writing to the first, then second replica, it'll be inconsistent, but not for too long :)
Yes, that is the difference between strongly consistent and eventually consistent.
> "if you have a hammer, everything looks like a nail."

I don't like MongoDB either, but normalization is not the answer for every project. For some projects, reading efficiency is so important that people are willing to pay for of it in disk space, an increase in writing costs, and even app complexity.

Normalisation is a good starting point though. If you hit the limits of normalisation then you can always denormalise.
It depends on the problem and current circumstances. Just because MongoDB doesn't work, it doesn't mean alternatives to relational DBs should be ignored.
> "forget about normalization! Duplication is okay."

Not just duplication. I did some work on a platform that used ElasticSearch as a relatively relational "document" store (that is, a purpose to which a true RDBMS would have been better suited). Besides data duplication, we ran into the problem of data consistency: using the author's TV show example, we would end up with some actor's whose birthdates would be recorded, but some whose age was recorded instead. Some TV shows would list the actors by role, some would just list the actors and the roles in two different lists. Sometimes the TV show start and end dates would be milliseconds since the epoch, some would be dates in YYYY/MM/DD formatted strings. Some would be dates in DD-MM-YY formatted strings. All scattered randomly throughout the data store. Elastic schema means random schema.

On the surface, that sounds more like a problem of data cleanup before insertion. Were you doing any validation/normaliztion of the data beforehand?
> Were you doing any validation/normaliztion of the data

Of course we (they) were - lots of it! Just inconsistently...

Also this weird adversion against using the power of a RDBMS.

NO VIEWS! NO STORED PROCEDURES! NO TRIGGERS! YOU SQL MUST BE AGNOSTIC!

and stuff like that. However, they pick Mongo or anything like that and yep, they must use anything it provide just by necessity.

---

People:

Using views is easy. Is probably the most simple thing you can get to leverage what a DB can give (plus indexes) and let model the data in different ways and even help in transition from a data model and another.

On the flip side... joins are expensive... I worked on an application, where presenting a single page, representing a single item in the application (classifieds site) required upwards of around 40 joins (iirc 36 or 46, I don't remember)... under load (including search result pages), the app was crushed by its' own weight.

I think the bigger issue is that people are afraid of separating data at clear boundaries, so long as the orchestration is in place. Having definitive data in SQL, and having denormalized documents in elasticsearch/mongo/rethinkdb works very well... other instances (huge read and/or write throughput) may work better in a Cassandra (or other bigtable solution) with application-generated lookup tables may be better. It just depends on your need.

With better support for JSON/XML nested structures and indexes in sql rdbms, it's becoming less of an issue for a lot of types of data/documents.

40 joins for a classified ad?
"Normalized" It comes down to there being a lot of "options" for cars/trucks, and each type was a separate set of mappings (2-joins), etc... it could have been simpler and more flat, but it was excessively normalized to be "flexible".

Like I said, it was pretty crushing on the database... there were a lot of other expensive calculations that ran per request... pre-calculating, caching, and a few other things got some longevity, bit it was a tangled mess of a beast for what would have been 3-4 collections for a document database (mongodb, rethinkdb, etc).

An interesting article. I'm always wary with no approaches in technology due to the "trendy" factor that often pushes for the novel for no reason other than its novelty. That said, I am curious if there are use cases where non-relational databases like MongoDB make sense as data caches for quick read only access, since the data could be formatted in the way that API calls would already expect it to be post extraction.
It takes that article a long time to get to the point. What I'd like to know is, "why is emulating joins bad?"

Specifically, why is it bad to load a MongoDB document, and then load downstream documents that it links to? What kind of problems does this lead to?

Granted, when I worked with MongoDB, I encountered problems due to its lack of transactions. (It's surprisingly unreliable if you end up needing to update multiple documents; when a relational database can do that easily in a transaction.)

But, assuming you can pick an application design that does single-document updates; why is following links in a document bad?

Can you do it at the database level? Since MDB doesn't have joins wouldn't emulation require a lot more transactions across the wire? And in a distributed system couldn't that add up very quickly?
I'm looking for a more quantitative answer. For example, if I write a message board in MDB:

- An entire discussion (think hacker news story and all corresponding discussion) is a single document - Each post, reply, ect, has a user ID - I load the post object and then do a "where uid in (all uids in document)" query

Obviously, that has scalability limits, but what are they? In practice, when do you hit them?

Sounds like a great article. Take some of the open sourced reddit comments, or just create a small script to generate lorem ipsum posts for "users". Deploy mongo somewhere. Scale the data and scale the number of requests per second and see when things fall off. I've got so many projects I'd like to do but that does sound neat. I'd like to compare it to couchbase and postgres as well, two databases I'm much more interested in, and also Neo4j which I'm sure I've heard of but rediscovered when looking up graph databases after reading this article.

Could be a couple of solid weekends maybe with a few friends. A lot of good experience gained from my end that I could see.

Lack of isolation and multi document atomic updates is one of the biggest difficulties. If you are updating multiple associated documents under a semantic transaction, it's possible there will be a window in which the partial update is visible. Sometimes this is harmless, other times quite harmful (changing constraints and budget on a bidding platform can result in overpaying for undesired inventory for example).

This can be worked around somewhat. If you only ever update the parent documents, then you can create new associated documents and atomically update the parent document to point to all the new ones. It's a bit of a song and dance, and definitely has limitations and gets complicated fast.

I'm painfully aware of the "Lack of isolation and multi document atomic updates is one of the biggest difficulties" problem, as I encountered it when I tried working with MongoDB. (I chose MongoDB because I was working with very fluid requirements and needed a very flexible schema.)

But that's not really what the article complains about!

The context is that I met some of the Diaspora leads in the summer of 2010. At the time, they were ambitious, but very inexperienced. (They did teach me some valuable lessons about encryption!) The reason why I say this, is without some kind of data, it's hard to know if "don't emulate joins in MongoDB" is a conclusion of inexperience; and something that a more experienced developer would understand how to do correctly.

For example, in a message board application, if a join is emulated between a discussion and user objects that just have username and avatar; the penalty of seeing an incomplete update is inconsequential. Either the user sees the old name / avatar, or the user sees the new name / avatar. So the incomplete update problem (in theory) can be handled by restricting "joins" to only when it's okay to see old data.

So, assuming that the incomplete update problem is solvable, at what point do emulated joins stop scaling?

> by restricting "joins" to only when it's okay to see old data.

So what do you do when it's not OK to see old data? That's when it breaks down.

There are definitely ways around the issues, but you have to make compromises in how you build the application. If you don't make those design decisions early, you find yourself doing it wrong.

In describing large scale systems, a friend of mine said "Imagine a scenario that has a one in a billion chance of happening. On a 10k qps system, it happens almost daily."

That's how this breaks down at scale. Awkward corner cases that don't really seem likely suddenly become daily events.

So, would you say that it's a solvable problem, but it's so time consuming or difficult that a traditional relational database is a more appropriate database for average developers? (Remember, the Diaspora guys were right out of college and inexperienced.)

It's as if MongoDB is great for prototyping, and great for lossy data at scale, but it can't hit the middle.

Mongo's problem isn't really the lack of schema or joins or anything. It's the mountain of false assumptions people make around its behavior. If you understand the limitations of the libraries and systems you use, you can solve most problems. The issue is that most people don't understand those limitations. Mongo gets an especially bad rap because it actively pushed misleading information as part of its sales pitch.
At this point in time, making a statement about MongoDB on HN should almost be considered trolling. We already know about the short-comings of that code-base. It will work fine until it doesn't and you'll loose some of your data. Some folks are using it and enjoying it. Others aren't. "Your shouldn't use it" is like saying you shouldn't use javascript for things other than UI. Noone cares anymore.
To be fair, I think your comment shows why this sort of post _can_ still be useful. You're very unlikely to lose data on a modern Mongo system using default configuration (their troubles with durability have largely been solved), but there are many other good reasons not to use it, and it's enlightening to read about and understand what they are.
If "their troubles with durability have largely been solved" were true then I'm sure HN would be flooded with posts about "MongoDB solves durability with an entirely new architecture". I might be wrong here. How did they solve the "your data is lost when a disk fails"?
I'm talking about "durability" here in the context of the "D" in "ACID".

Previously, Mongo had very serious problems in that are because its client would assume that any message sent to the outgoing socket buffer was persisted "well enough", which was an obvious untruth [1]. This was also one of the somewhat underhanded techniques they used to achieve their early benchmarks.

As of version 3, they have defaulted their client's "write_concern" value to "1", which means that it will wait for confirmation from a replica set's primary before considering a value persisted [2]. This puts Mongo roughly on the same level as any other database in terms of durability guarantees.

Disk failure is entirely tangential to your original premise that "Mongo loses data". I'm not getting into it, but there a variety of techniques that Mongo (and every other known database) can use to protect against that.

[1] http://hackingdistributed.com/2013/01/29/mongo-ft/

[2] https://docs.mongodb.com/manual/reference/write-concern/

MongoDB was initially designed to beat other nosql systems in benchmarks, is what I take away from reading about it. Someone took issue with that and wrote an article. "MongoDB lies" and "is slow" were some of the claims made from your link #1.

Now that these issues are gone, by having reasonable default settings for write concern and journaling, how well does MongoDB do in the benchmarks today?

Rewgarding default settings, how is "w=1" considered a safe write? The data exists in a single node and has not been propagated. If you only have one node then I guess it's as safe as can be. Is MongoDB suitable as a single node installation though? I would have thought "w=2" or "w=majority" would be the "safe" setting.

> Now that these issues are gone, by having reasonable default settings for write concern and journaling, how well does MongoDB do in the benchmarks today?

Reports differ by benchmark, but the answer can be summarized as "not well". From [1] above:

> MongoDB is now a lot slower compared to v2.0. On the industry-standard YCSB benchmark, MongoDB used to be competitive with Cassandra, as seen in the performance measurements we did when benchmarking HyperDex. Ever since the change, MongoDB can no longer finish the entire benchmark suite in the time allotted.

I'm not sure I'd call what they were doing "cheating" per se because I honestly don't think they understood what they were doing, but it's fair to say that even if performance has improved since those benchmarks were run, Mongo definitely doesn't have any secret sauce.

I got "Error establishing a database connection", maybe this wouldn't have happened if they had used MongoDB :-)
Yeah, the post would have never even have been saved to disk in the first place :P
More than a story about MongoDB, this is a story about hype. The unquestioning, unthinking acceptance of some technology just because someone enjoying his 15 minutes of fame has tweeted about it. The designers of Diaspora set out to build a distributed database that needed to support complex queries and transactional updates. Only they didn't realize it. And they chose MongoDB because of hype. And of course it failed.

TFA says: "In 2010, when the Diaspora team was making this decision, Etsy’s articles about using document stores were quite influential, although they’ve since publicly moved away from MongoDB for data storage. Likewise, at the time, Facebook’s Cassandra was also stirring up a lot of conversation about leaving relational databases. Diaspora chose MongoDB for their social data in this zeitgeist. It was not an unreasonable choice at the time, given the information they had."

Yes, it was an unreasonable choice. This is basically saying that the cool kids are using document stores, so we should too. There is no discussion of requirements, no recognition of the obvious conflict between Diaspora's data model and MongoDB's, and no discussion at all of the need for transactions, let alone distributed transactions!

TFA says: "In this post I’ve talked about how we used MongoDB vs. how it was designed to be used. I’ve talked about it as though all that information were obvious, and the Diaspora team just failed to research adequately before choosing. But this stuff wasn’t obvious at all."

Of course it was obvious. If you have a highly recursive data structure, and you decide to basically store the result of a seven-way join in a single document, then there is duplication. You should know, just from your earliest programming days, that duplicating data in data structures leads to grief. How are updates going to be handled? And if you decide against duplication, you have to do the joins, and clearly MongoDB doesn't solve that problem. So even before worrying about transactions it is obvious that you have a problem.

Finally, they migrate to MySQL and (then also? in addition?) Postgres. Although I don't quite see how this fits their database per pod architecture. I'm guessing that each pod talks to -- what -- one centralized database? Maybe they will eventually figure out what's wrong with that.

Oy.

>>Yes, it was an unreasonable choice. This is basically saying that the cool kids are using document stores, so we should too. There is no discussion of requirements...

You hit the nail on the head. I posit that this problem is caused by the Agile mindset that says "we don't need to collect or discuss requirements upfront. They change too often! Instead, we will just start hacking and change things as we go along." Two years later, the team is running into all kinds of complex, hard-to-reproduce problems, and they realize that they have made a terrible mistake picking MongoDB and they have to undertake a very painful migration and rewrite of the backend.

Yes, I agree, it is easy to see how Agile could lead to this particular, disastrous, dead end.
This article has little to do with the specific failings of MongoDB at all. The author takes offense with document databases and denormalization. I disagree with the blanket statement.

Denormalization. It's not always the answer, but sometimes making reads easy and writes more difficult isn't bad for the problem set. The funny thing is a social network at scale isbt going to be able to use a traditional SQL database without sharding it and killing joins. It will be a documebt DB with limited SQL features.

As for Mongo, it is sold as the answer to everything just like any other product. It actually fits some problems sets. I actually had great success with it, at scale, in an Amazon division. It ain't the answer for a lot of problem sets though.

I give this blog post two of five for bringing up a mildly interesting topic HN already beat to the ground with misguided conclusions.

I like document oriented databases. It seems odd I should need to change the data structure of an item in order to persist it.

After about 5 years of the many/varied cases of Mongo losing data, I switched to rethinkdb for my current project. It's an uninteresting, surprise-less database and I like it very much.

Not this FUD again! It is true that MongoDB created a lot of unexpected problems for the early adopters who did not do enough due diligence and testing. I encountered them during my POC with Mongodb but I was able to get past them easily thanks to a robust user community. I have experiences no such issues with current version with Mongodb.

Today I am fighting my enterprise bureaucracy to get MOngoDB for our enterprise applications .FUD like this allows armchair architects to quote this article to spook the management and we are stuck with stuffing json as in a RDBMS tables.

The article is from 2013, so its very much likely that some of the issues has been handled by MongoDB itself or some agreed practices.
Finally, great comment - had to scroll too far to get to this!

1) The developers clearly weren't experienced enough to know what document storage is and when/where it shines/fails. 2) Author jumped on the ever-boring 'i hate mongo' easy train. 3) I am so sick of technology becoming a religious war.