Firestore Batch Writes
A batch write groups multiple create, update, and delete operations into a single request. All operations in the batch either succeed together or fail together. Batches are faster than individual writes because they make one network round trip instead of many.
Batch vs Transaction
Batches and transactions both group operations atomically, but they serve different purposes:
Batch Write: - Write-only (no reads inside the batch) - Does not retry on conflicts - Faster — just sends the writes and commits - Best for: creating multiple documents at once, seeding data, mass updates Transaction: - Reads and writes allowed - Retries if conflicting changes detected - Slower — reads first, then writes, then checks - Best for: operations where writes depend on current values (e.g., decrement stock)
Creating a Batch
import { writeBatch, doc, collection } from "firebase/firestore";
import { db } from "./firebase";
const batch = writeBatch(db);
The batch object collects operations. Nothing runs until you call batch.commit().
Adding Operations to a Batch
// Create new documents
const post1Ref = doc(collection(db, "posts"));
batch.set(post1Ref, {
title: "Introduction to Firebase",
authorId: "uid_alice",
status: "published"
});
const post2Ref = doc(collection(db, "posts"));
batch.set(post2Ref, {
title: "Firestore in 10 Minutes",
authorId: "uid_alice",
status: "draft"
});
// Update an existing document
const userRef = doc(db, "users", "uid_alice");
batch.update(userRef, { postCount: 2 });
// Delete a document
const oldPostRef = doc(db, "posts", "old_post_001");
batch.delete(oldPostRef);
// Commit all operations at once
await batch.commit();
console.log("All batch operations completed.");
Batch Limits
A single batch supports a maximum of 500 operations. Each set, update, or delete counts as one operation. If you need more than 500 operations, split them across multiple batches.
// Splitting a large batch
async function batchDeletePosts(postIds) {
const BATCH_SIZE = 500;
for (let i = 0; i < postIds.length; i += BATCH_SIZE) {
const batch = writeBatch(db);
const chunk = postIds.slice(i, i + BATCH_SIZE);
chunk.forEach((id) => {
batch.delete(doc(db, "posts", id));
});
await batch.commit();
console.log(`Deleted batch ${i / BATCH_SIZE + 1}`);
}
}
Practical Example: User Registration with Profile
When a new user signs up, you often want to create multiple documents simultaneously — the user profile, initial settings, and a welcome notification. A batch handles all of these in one operation:
async function setupNewUser(uid, email, displayName) {
const batch = writeBatch(db);
// Create user profile
batch.set(doc(db, "users", uid), {
displayName,
email,
createdAt: new Date(),
plan: "free"
});
// Create default settings
batch.set(doc(db, "settings", uid), {
theme: "light",
notifications: true,
language: "en"
});
// Create welcome notification
const notifRef = doc(collection(db, "users", uid, "notifications"));
batch.set(notifRef, {
message: "Welcome to the app, " + displayName + "!",
read: false,
createdAt: new Date()
});
await batch.commit();
console.log("New user setup complete.");
}
Mass Update Example
Updating many documents to reflect a price change or category rename:
async function updateCategory(oldCategory, newCategory) {
// First, find all affected documents
const q = query(
collection(db, "products"),
where("category", "==", oldCategory)
);
const snapshot = await getDocs(q);
// Process in batches of 500
const docs = snapshot.docs;
for (let i = 0; i < docs.length; i += 500) {
const batch = writeBatch(db);
docs.slice(i, i + 500).forEach((d) => {
batch.update(d.ref, { category: newCategory });
});
await batch.commit();
}
console.log(`Updated ${docs.length} products.`);
}
Key Takeaway
Batch writes group up to 500 Firestore write operations into a single atomic request. Use batches when you need to create, update, or delete multiple documents at once without reading any values inside the batch. Batches are faster and simpler than transactions for write-only operations. For large datasets exceeding 500 documents, split operations across multiple consecutive batches.
