Skip to main content
A batch write groups multiple Firestore operations into a single atomic commit. Either every operation in the batch succeeds, or none of them do — there is no partial state. Batch writes also reduce network round-trips: regardless of how many operations you include, only one RPC is sent to Firestore. This makes them ideal for tasks like seeding data, bulk updates, or any workflow where you need a consistent snapshot after multiple mutations.

The BatchOperation Enum

The BatchOperation enum defines the three operations a batch can perform:

batch_write() — Executing the Batch

batch_write() is a class method on any model that inherits BaseFirestoreModel. Pass a list of (BatchOperation, model_instance) tuples:
The method commits all operations in a single Firestore batch.commit() call.
UPDATE and DELETE operations require the model instance to have an id set. Passing an instance without an id for these operations will raise a ValueError before the batch is submitted.

Batch Create

Create multiple documents in one call. Instances without an id are assigned auto-generated IDs before the batch is committed, so you can read instance.id immediately after batch_write() returns:

Batch Update

Update multiple documents atomically. Each instance must already have an id:

Batch Delete

Delete multiple documents in one atomic operation. Each instance must have an id:

Mixed Operations in One Batch

You can combine CREATE, UPDATE, and DELETE operations in a single batch call. All three happen atomically:

Auto-ID Assignment

When a CREATE operation is added to the batch with an instance that has no id, the ODM calls collection_ref.document() to pre-allocate a Firestore document reference and assigns its auto-generated ID to model_instance.id before batch.commit() is called. This means IDs are available synchronously in your code as soon as batch_write() returns:

Batch with Subcollections

To batch-write subcollection documents, set the _parent_path private attribute on each instance before passing it to batch_write(). This tells the ODM which parent document path to write under without requiring a live parent instance:
object.__setattr__ is used because _parent_path is a Pydantic private attribute (PrivateAttr). Direct assignment via post._parent_path = ... is also valid in Pydantic v2, but object.__setattr__ works across both Pydantic v1 and v2.

Firestore’s 500-Operation Limit

Firestore enforces a hard limit of 500 operations per batch. If you need to write more than 500 documents, split your operations into chunks:
Exceeding 500 operations in a single batch raises an error from the Firestore backend. Always chunk large batches before calling batch_write().

Complete Batch Example

Querying

Fetch, filter, and paginate documents with the expressive query API.

Models

Learn how to define models and collection settings.