The Database Was Relational, But the Decision Was Not
The Database Was Relational, But the Decision Was Not
I joined a new team a few months ago. On the team there is another junior who already worked with the agency for about a year. As a new joiner, I had to accept a new atmosphere and a new culture.
The plot
One of the first projects I was assigned to is a custom CMS the agency was building. At first, a few things felt like red flags. For example, the choice of Next.js was mentioned early on, not that I have anything against it (I am not a fan of React, personally), but I was new to the team. I did not really have a say yet, and I figured it made sense to respect decisions made by people more senior than me. So I did not push back on that one.
Then there was the database: MongoDB. This one decision did not sit well with me.
The why behind it
The reason for my discomfort was that deciding on a stack before clearly identifying the problem it needs to solve is, in my experience, a recipe for chaos, especially for juniors. Add AI-assisted development into that mix and bugs can compound fast.
I am a junior myself, but I have been lucky enough to watch and even contribute in small ways to some open source projects run by people I really respect. From that experience, I noticed a clear pattern: decisions are not free. Every decision made in those projects had a clear reason behind it, nothing arbitrary.
Every tool, every tradeoff, is chosen not just because it solves a problem, but because it serves a purpose.
With this new project, I never got that clarity. For months it kept nagging at me: was MongoDB really the right call, at least for this kind of app? The more I thought about it, the more I felt I should raise the idea of migrating to a more suitable database, at least for our specific case.
Our case
Our CMS has a lot of relational logic. Just from reading the general data model, it is clear this is not really a “collections” problem, it is a relational problem. Users show up in many places, and there are parent, child, and grandchild relationships that go both ways.
That is not documents with the occasional relation. That is relational data wearing a document database as a costume. The signs were already there.
For developers who have mostly worked with MongoDB, this might sound like just another case Mongo can handle. It reminds me of the old saying: “To a hammer, every problem looks like a nail.”
But when you put a lot of relational structure into MongoDB, what you mostly get is complexity and awkward patterns, even for things that should be simple.
Life is good until MongoDB puts down its happy mask
For anyone who does not immediately see why this is a problem: the deeper issue is not any single missing feature. It is that the data itself is relational, and the database it lives in is not.
Take soft deletes as an example. On the surface it looks simple: add an isDeleted flag and toggle it. That works fine when a record stands alone. But once that record has children, deleting the parent means you also need to think about the children, and if you later add a restore feature, you need logic to walk back up and restore parents and ancestors too. In a relational database, this is largely handled through foreign keys and cascading rules. In MongoDB, there is no built-in cascade, you have to build that traversal and consistency logic yourself, by hand, for every relationship that needs it.
I am mentioning this specific example because I ran into exactly this kind of task last week. I am not complaining. I am saying that with a bit more experience, I might have seen earlier where this decision would lead, and I might have been more willing to raise the concern, or at least ask more questions, before the project got this far.
Soft delete matters here as a concrete case, but it is really a symptom. The root issue is a relational data model sitting on top of a database that was not built to enforce relationships.
That is what happens when a junior who mostly knows tutorial-level stacks, and who was too hesitant to speak up about a gut feeling, goes along with a decision instead of questioning it.
Lesson
Critical decisions need to be questioned and tested before any real work starts. That matters a lot.
Not expressing concerns early is harmful to the team. Speaking up, especially about things that affect the whole team, should be part of how we work, not an afterthought.
I am not upset about any of this, honestly I am glad it happened, because it means I am learning and moving forward. Next time I am in a similar situation, I want to do proper research before a decision like this gets locked in, rather than after.
I am still thinking it through, but in the coming days I plan to bring this up with the team and suggest we look at moving to PostgreSQL for the parts of the CMS that are clearly relational. Better late than never, and I would rather raise it now than let it sit as a problem I quietly pushed aside.