A Document Database

Chat must use Courselore’s relational database. But suppose we were building Courselore from scratch, or building chat as an application of its own. Would we store chat in a document database?

One document per room

A room holds a list of messages, and the app shows a room’s messages together. So a natural first design puts each room in one document, with its messages in an array:

{
  "_id": 12,
  "title": "Team 4",
  "messages": [
    {
      "id": 61843,
      "authorId": 7,
      "body": "Design doc: https://docs.example/team-4-design",
      "createdAt": "2026-10-13T14:02:11Z"
    },
    // more messages
  ]
}

How large a room gets

Each new message makes the room’s document larger, and a document has a size limit. But a room belongs to a course, and a course lasts one semester, so a room stops growing when the semester ends. How large does it get by then?

Our load assumptions say each person posts 10 messages a day. If the five members of a project team, such as Team 4, post all of theirs in the team’s room, that is 50 messages a day, or about 5,000 over a semester of about 100 days. A stored message is about 300 bytes, so the room document grows to about bytes, or about 1.5 MB. MongoDB, the document database we used for Shopend, limits a document to 16 MB. The room stays well under it.

A public room can be much larger. A course has 50 participants. If they posted all of their messages in General, General would collect 500 messages a day, about 50,000 over the semester. That is about 15 MB, just under the limit. At twice that load, which our scalability requirement covers, General would pass the limit before the semester ends. In practice, a course’s messages are spread over several rooms, so this is the worst case.

Reading and posting

Size is not the only problem. When a member opens the room, the app shows the newest messages, but the database loads the whole room document to return them. It does that every time a member opens the room or scrolls up for older messages. Every new message also changes the same document, so when two members post at the same moment, their updates conflict, and the database retries one of them. MongoDB’s documentation lists arrays that keep growing as a design mistake, and the documentation of Firestore, a document database from Google, uses a chat room as its example of keeping messages in their own collection.

So even with a document database, we would keep the messages out of the room’s document. The messages go in a collection of their own, and each message document records the identifier of its room:

{
  "_id": 61843,
  "roomId": 12,
  "authorId": 7,
  "body": "Design doc: https://docs.example/team-4-design",
  "createdAt": "2026-10-13T14:02:11Z"
}

To show a room, the app finds the messages whose roomId is the room’s identifier. This is the design we already have in the relational database: chat_rooms holds the rooms, and each row in chat_messages records its room_id. So a document database would give chat nothing that the relational design does not.