AlgoMaster Logo

Document Databases

Medium Priority15 min readUpdated July 4, 2026
AI Mock Interview

Practice this topic in a realistic system design interview

Listen to this chapter
Unlock Audio

Document databases store records as JSON-like documents instead of spreading every piece of data across many tables.

They are useful when the data naturally belongs together: a product with its specifications, a user profile with preferences, an article with extra details, or an application setting with nested options.

The core idea is simple: store data in the shape your application usually reads and writes.

If the application usually needs one complete object, storing that object as one document can be efficient and easy to work with.

Document databases are not just "relational databases without schemas." They have their own strengths and their own ways to get into trouble.

With good modeling, they make nested data simple to store and query. With careless modeling, they can create duplicated data, inconsistent records, and documents that grow without limit.

This chapter covers the document model, how to design documents well, and where document databases fit.

Loading simulation...

1. The Document Model

A document is a structured record, usually represented as JSON or a binary JSON-like format such as BSON. It can contain simple values, nested objects, arrays, and optional fields.

Document Structure

Here is a document representing a blog post:

Nested objects like author and stats group related fields. Arrays such as tags and comments store repeated values.

Other posts might have optional fields such as featured_image or series_id. Some posts might have no comments at all.

The comment also stores a copy of user_name. That makes rendering the post easier because the application does not need another read just to show the commenter's name.

Collections

Documents are grouped into collections. A collection is similar to a table, but every document in the collection does not have to contain the exact same fields.

The terminology maps fairly directly:

  • a table becomes a collection
  • a row becomes a document
  • a column becomes a field
  • a join table is often replaced by embedded data or references to other documents

Document databases are often called schemaless, but in production, schemaless should not mean "anything goes."

Documents in the same collection usually share a common shape because the application needs predictable data. The flexibility is for controlled change and natural variation, not for skipping data design.

Document IDs

Every document needs a unique ID. MongoDB uses _id; other databases have similar fields.

Common ID choices include:

  • Database-generated IDs: convenient and often tuned for the database.
  • UUIDs or time-ordered IDs: useful when services need to create IDs before writing.
  • Application IDs: useful when the business already has an ID, such as an order number.

The ID choice affects indexes, URLs, data imports, replication, and sharding. Random IDs spread writes well but may make indexes less cache-friendly. Time-ordered IDs keep nearby records closer together, but they can create write hotspots if used carelessly as shard keys.

2. Embedding vs Referencing

The most important modeling decision in a document database is whether related data should live inside the same document or be referenced by ID.

Relational design often starts by separating data into tables. Document design starts with a different question:

What does the application usually read and write together?

Embedding

Embedding means storing related data inside the parent document:

This is often a good model for orders. An order should preserve customer and product details as they were at purchase time. If the customer changes their email later, old order history usually should not change.

Advantages of embedding

  • Single read: The application can fetch the whole object in one operation.
  • Atomic document updates: Changes inside one document are all-or-nothing in most document databases.
  • Data stored together: Related fields live together.
  • Simple rendering: The application does not need to assemble many records for common reads.

Disadvantages of embedding

  • Duplication: Repeated data appears in many documents.
  • Update work: If copied data must change everywhere, the application needs a plan to update all copies.
  • Document growth: Large arrays, or arrays with no clear limit, can make documents slow or hit size limits.
  • Contention: A document that many requests update at once can become a bottleneck.

Referencing

Referencing means storing IDs that point to other documents:

To display the full order, the application usually fetches the order, customer, and products separately, or uses a database feature that performs a lookup.

Advantages of referencing

  • Less duplication: Shared records live in one place.
  • Smaller documents: Parent documents stay compact.
  • Independent updates: Customer or product records can change without rewriting every order.
  • Better for large relationships: References handle relationships that can grow very large, or many-to-many relationships, more safely.

Disadvantages of referencing

  • More reads: The application may need multiple queries to assemble a view.
  • Weaker relationship rules: The database may not enforce foreign-key-like relationships.
  • More cleanup work: Deletes, updates, and data repair jobs need careful handling.
  • Less data stored together: Related data may live on different partitions or shards.

When to Embed vs Reference

Several factors push the decision one way or the other. The table below gives a practical rule of thumb.

FactorFavor EmbeddingFavor Referencing
Access patternRead together most of the timeRead independently
Relationship sizeOne-to-one or one-to-fewOne-to-many or many-to-many
GrowthHas a clear limitCan grow without limit
Update frequencyRarely changes, or changes with parentChanges independently
Consistency needA saved copy is acceptableOne official copy is needed
Write pressureFew writers update itMany writers update related data

Practical Guidelines

Embed small data with a clear size limit that is read with the parent. Also embed saved copies when history should preserve the old value.

Reference data that grows without limit. Also reference data that changes often and must have one official copy.

Avoid arrays that can grow forever, such as all comments on a viral post or all events for a user.

3. Query Capabilities

Document databases can query fields, nested fields, arrays, and indexes. The examples below use MongoDB syntax because many engineers recognize it, but the same ideas appear in other document databases with different APIs.

Basic Queries

These MongoDB queries match on a nested field, a numeric range, array membership, and a date window.

Projection

Projection means returning only the fields the caller needs. It is just a way to ask for a smaller result:

Projection reduces network transfer and parsing work when documents contain fields the caller does not need.

Array Queries

Arrays are a natural fit for tags, small lists, and child records with a clear size limit:

Array queries are useful, but very large arrays are a warning sign. If the array can grow without a clear limit, consider a separate collection.

Aggregation Pipeline

Many document databases support some form of aggregation. In MongoDB, an aggregation pipeline processes documents through steps:

The diagram below shows how documents move through each step, from raw orders to the final ten results.

Query Limitations

Document databases are flexible, but they still work best when the application mostly reads and writes documents.

Single-document reads and writes are usually the best case. Queries by an indexed field work well when the index matches the query. Join-like lookups are possible in some systems, but they are not the main design target.

Multi-document transactions are supported in some systems, but they add extra work. Flexible reporting is often better served by a relational, columnar, or analytical store. Relationship-heavy queries are usually better in a graph database.

If most screens require assembling data from many collections, the model is probably a poor fit for the workload.

4. Indexing

Indexes make queries fast by keeping a searchable structure next to the documents. Without the right index, a query may scan the entire collection.

Index Types

Document databases offer several index kinds. Each one helps a different kind of query.

Index TypeUse CaseExample
Single fieldQuery by one fieldemail
CompoundQuery or sort by multiple fields{customer_id, created_at}
MultikeyQuery values inside arraystags
TextBasic text searchtitle, content
GeospatialLocation queriesnearby stores
TTLExpire old documentssessions or temporary tokens
HashedSpread data evenly for shardinghashed user ID

Creating Indexes

The commands below build common MongoDB indexes: single-field, compound, unique, partial, and TTL.

Index Trade-offs

Indexes speed up reads but slow down writes, because each insert, update, or delete may need to update multiple indexes. Indexes also use memory and storage. In large systems, indexes can become a major part of what the database keeps hot in memory.

Compound index order matters because the index should match how queries filter and sort. Array indexes can grow quickly because a large array may create many index entries for one document.

Indexes do not fix a poor model. If the application constantly needs to assemble many scattered records, another model may be better.

5. Schema Validation

Document databases are often described as schemaless, but production systems still need rules.

Modern document databases usually support some form of schema validation. Applications also commonly validate documents before writing them.

The goal is to keep flexibility where it helps and enforce rules where bad data would be expensive to repair.

The settings control how strictly validation is applied. validationLevel: "strict" checks inserts and updates. validationLevel: "moderate" checks only documents that already match the rules.

For the action, validationAction: "error" rejects invalid documents. validationAction: "warn" allows invalid documents but logs a warning.

Schema validation is not a replacement for modeling. It is a guardrail.

You still need clear ownership of document shape, migrations for old documents, and a plan for old and new application versions to work during rollout.

6. Transactions and Consistency

Most document databases provide atomic updates to a single document. Atomic means all-or-nothing.

This is one reason embedding related data is useful: the whole document can be updated safely in one operation.

Multi-document transactions are supported in several modern document databases, but they are not free. They add extra work between records, error handling, conflicts, and performance cost.

A single-document update is the best fit because it is simple and usually atomic. A transaction across a few documents is useful when correctness requires it.

A large distributed transaction is usually a sign to revisit the model. A workflow across services is often better handled with events, sagas, or explicit state machines.

The design goal is to model common writes so they usually touch one document, and reserve multi-document transactions for cases where they are needed.

Consistency also depends on read settings, write settings, replication mode, and the database's specific guarantees. Always check the behavior of the system you are using.

7. Scaling Document Databases

Many document databases support scaling across machines through partitioning or sharding. Sharding means splitting documents across nodes based on a shard key.

The concepts below use MongoDB terminology, but the design ideas apply broadly.

Sharding Architecture

A query router sits between the application and the shards. It uses shard mapping information to send each request to the node that holds the matching data.

Shard Key Selection

The shard key determines where documents live. A poor shard key can overload one shard or force every query to touch every shard.

Shard Key PropertyGoodRisky
Number of distinct valuesMany distinct valuesFew values, such as status
DistributionEven loadOne tenant or value dominates
Write patternSpreads writesAll new writes hit one shard
Query patternIncluded in common queriesRarely used in filters
LocalityKeeps related data togetherSplits common reads across shards

Good shard keys depend on the workload. A tenant_id can work for multi-tenant systems if tenant sizes are balanced. A hashed user ID can spread writes evenly. A compound key can keep useful data together while still spreading load.

Bad shard keys usually have too few distinct values, always increase over time, or do not appear in common queries.

Targeted vs Scatter-Gather Queries

When a query includes the shard key, the router can send it to the right shard. When it does not, the router may need to query every shard and merge the results.

Scatter-gather queries may be acceptable for rare admin operations. They are usually a poor fit for high-traffic user requests.

8. Common Document Databases

Document databases differ in query model, consistency guarantees, hosting, and day-to-day operations.

MongoDB

MongoDB is a widely used general-purpose document database. It supports rich queries, secondary indexes, aggregation pipelines, schema validation, replica sets, sharding, change streams, and multi-document transactions.

It is a common choice for flexible application data, catalogs, content systems, user profiles, and event-like records.

Firestore

Firestore is a serverless document database commonly used for mobile and web applications. It provides real-time listeners, offline support in client SDKs, automatic scaling, and a query model built around collections and documents.

Its query model is more limited than MongoDB's. There are no joins. Multi-field queries usually require explicit composite indexes. Firestore does not support an aggregation pipeline. Plan reads carefully when many filters need to combine.

It is a good fit for client-facing apps that benefit from real-time sync and managed operations.

CouchDB

CouchDB is built around JSON documents, HTTP APIs, and replication. It fits offline-first and occasionally connected use cases, where replicas may drift apart and later sync.

It is a good fit when replication and conflict handling are central requirements.

Amazon DocumentDB

Amazon DocumentDB is an AWS-managed document database with MongoDB API compatibility. It can be useful for teams that want a managed AWS service and can work within its compatibility and feature limits.

It is important to check compatibility carefully instead of assuming it behaves exactly like MongoDB.

9. When to Choose Document Databases

Choose a document database when the application usually reads and writes one complete object. They also fit when data is nested or variable, with optional fields, nested structures, or type-specific attributes.

They are useful when the product changes often and you need controlled flexibility in the data shape. They also help when duplicating saved copies of data makes common reads simpler and faster.

Sharding fits best when common queries usually include the partition or shard key.

When to Consider Alternatives

Consider another database type when strict relational rules are central and foreign keys, joins, and constraints are core to the workload. A relational or graph database may model the problem better when many-to-many relationships dominate.

Documents that grow without limit create operational problems through large arrays and ever-growing records. Frequent flexible analytics are usually better served by analytical stores built for broad scans and reports. A key-value store may be simpler when the data is mainly exact-key lookup.

Document databases work best when the document boundary is clear. If you cannot explain what belongs in one document and what does not, the model needs more thought.

Summary

Document databases trade strict table structure for flexible JSON-like documents with nested objects and arrays. The schema is flexible by default, but production systems still need validation and clear rules.

Relationships are handled by embedding small data that belongs with the parent and referencing shared data or data that can grow without limit.

Single-document operations are the natural fit. Multi-document transactions vary by system. Important field, array, sort, and shard-key queries need indexes. Sharding works best when queries include the shard key.

The core design skill is choosing document boundaries: embed what is small, limited in size, and read together; reference what is shared, updated on its own, or able to grow without limit; and add validation and indexes deliberately.

Quiz

Document Databases Quiz

10 quizzes