Collections Vs Sub-Collections

  • In Firebase Firestore, collections are top-level containers that sit directly at the root of your database, while sub-collections are nested directly inside individual documents to form a hierarchical structure.
  • Neither option is inherently faster or cheaper than the other because Firestore query performance scales based on the size of your result set, not the size of your database. The difference lies completely in how you structure your data, how you query it, and how you manage permissions.

Data Model Rules

Firestore requires an alternating pattern of containers and documents: Collection → Document → Sub-collection → Document. You can never put a collection inside another collection, nor a document inside another document.

Direct Feature Comparison

FeatureRoot CollectionsSub-collections
LocationDatabase root level.Embedded inside a parent document.
Data RelationshipBest for independent data or many-to-many relationships.Best for strict one-to-many “parent-child” ownership.
Shallow FetchingNaturally isolated.Automatically bypassed when fetching the parent document.
Querying Across GroupsSimple collection queries.Requires collectionGroup queries.
Cascade DeletionN/AParent document deletion does not auto-delete sub-collections.
Write ThroughputDistributed across the collection.Inherits individual parent document index/write limits.

Core Structural Differences

Root Collections (Flat Structure)

  • Root collections are perfect for primary entities that need to be queried globally across your entire app.
  • Example path: /users/{userId} or /products/{productId}
  • Advantage: It is highly flexible.
    • If you want to fetch items based on multiple disparate filters, a root collection with references to other documents is often the cleanest approach.
  • Disadvantage: In the Firebase Console, managing millions of unlinked, flat documents can sometimes feel disorganized or visually messy.

Sub-collections (Hierarchical Structure)

  • Sub-collections bind data to a specific parent document.
  • They are ideal for lists that will continuously expand over time, ensuring you bypass the 1 MB maximum document size limit that applies if you try to use local arrays instead.
  • Example path: /chats/{chatId}/messages/{messageId}
  • Advantage (Shallow reads): When you query the parent document /chats/{chatId}, Firestore does not download the sub-collection data.
    • This saves you bandwidth and read costs until you explicitly ask for the messages.
  • Disadvantage (Orphaned Data):
    • If you delete the parent document, the sub-collection data remains in your database.
    • You must delete sub-collection documents manually using custom application code or Cloud Functions.

Key Decision Factors## 1. Security Rules Integration

  • Sub-collections allow you to cascade access permissions automatically.
  • You can easily write a rule stating that a user can only read a sub-collection if they own the parent document.
  • With root collections, you must perform separate reference lookups to achieve this.

2. Querying Scope

  • If you frequently need to fetch data belonging to one specific parent (e.g., “Get items inside User X’s cart”), use a sub-collection.
  • If you frequently need to fetch data across the entire database regardless of ownership (e.g., “Get all active items across all user carts”), a root collection is usually easier, though you can achieve this with sub-collections using a Collection Group Query.