Skip to content
AB

Safe MongoDB Writes with Unique Indexes and Atomic Upserts

Replace check-then-write races with database-enforced uniqueness, conditional updates, and deliberate duplicate handling.

Ashish BhakhandPublished

This code looks safe but contains a race:

Code
const existing = await collection.findOne({ userId, day });
if (!existing) {
  await collection.insertOne({ userId, day, count: 1 });
}

Two Lambda invocations can both observe no document and both insert. Application checks improve error messages; they do not enforce invariants under concurrency.

Let an index enforce uniqueness#

Code
await collection.createIndex({ userId: 1, day: 1 }, { unique: true });

Now the database is the final authority. The application should handle duplicate-key errors according to the operation: return the existing resource, report a conflict, or treat the retry as a no-op.

Use atomic upserts#

For create-if-absent behavior:

Code
await collection.updateOne(
  { userId, day },
  {
    $setOnInsert: {
      userId,
      day,
      createdAt: new Date(),
    },
    $inc: { count: 1 },
  },
  { upsert: true },
);

One database operation avoids the gap between read and write. Confirm that the filter is supported by the unique index; otherwise concurrent upserts can still surprise you.

Put state conditions in the write#

Conditional updates safely claim work:

Code
const job = await jobs.findOneAndUpdate(
  { _id: jobId, status: "pending" },
  { $set: { status: "processing", claimedAt: new Date() } },
  { returnDocument: "after" },
);

Only one worker changes pending to processing. A missing result means another worker won or the state is no longer eligible.

Multi-document transactions are useful when several documents must change together, but they add latency and operational constraints. Prefer one-document atomic designs when the domain allows them.

Test writes concurrently, not only one after another. Safe MongoDB code expresses the invariant in an index or atomic filter, close to the place that arbitrates competing writes.

← Back to all writing