Course contentsShow
← Databases & SQL
Lesson 1211 of 1,95311. NoSQL and Document ModelsFree lesson

Data Integrity in Denormalized Models

Implement background synchronization tasks to maintain consistent state across denormalized documents.

In this lesson, you will learn how to use background synchronization tasks to maintain eventual consistency when duplicating data across multiple documents.

When you denormalize data—such as embedding a user’s username inside their posts—you gain performance by reducing joins, but you introduce a data integrity challenge: what happens when the user updates their username? If you only update the main users document, your posts documents now hold stale, inconsistent information.

The Background Synchronization Pattern

Because updating thousands of posts documents in a single transaction can lock collections and hurt performance, we use background synchronization tasks. Instead of forcing an immediate, synchronous update, we decouple the write from the propagation.

  1. The Trigger: When a core entity changes (e.g., users.username updates), you mark the records as "dirty" or push a reference to the affected documents into a dedicated sync_queue collection.
  2. The Worker: A background process (a cron job, a change stream listener, or an event worker) reads the sync_queue. It performs the necessary updates in batches to avoid overwhelming the database.
  3. The Resolution: The worker identifies documents that need the new value and uses an atomic update operation to patch them.

Consider a snippet of a background worker task:

// Fetch pending sync tasks
const tasks = db.sync_queue.find({ status: "pending" }).limit(100);

tasks.forEach(task => {
  // Propagate the change to the denormalized location
  db.posts.updateMany(
    { "author_id": task.user_id },
    { $set: { "author_name": task.new_name } }
  );
  
  // Mark as processed
  db.sync_queue.updateOne({ _id: task._id }, { $set: { status: "completed" } });
});

This approach shifts the burden away from the user-facing request, keeping your application responsive. While the system may exist in a state of eventual consistency (where the posts briefly show the old name), it guarantees that the integrity of your denormalized data is restored automatically without impacting system availability.

Key Takeaway: Background synchronization maintains integrity in denormalized models by offloading widespread updates to asynchronous workers, ensuring eventual consistency without sacrificing write performance.