How do you implement distributed counters in Firestore?
Answer
Firestore's 1 write/second per document limit makes naive counters (increment a single field) insufficient for high-traffic scenarios. The distributed counter pattern solves this by spreading writes across multiple documents: (1) Initialize shards: for (let i = 0; i < NUM_SHARDS; i++) { setDoc(doc(db, "counters", `likes_${i}`), { count: 0 }) }; (2) Increment: pick a random shard and increment: const shardId = Math.floor(Math.random() * NUM_SHARDS); await updateDoc(doc(db, "counters", `likes_${shardId}`), { count: increment(1) }); (3) Read total: sum all shards: const snaps = await getDocs(collection(db, "counters")); const total = snaps.docs.reduce((sum, d) => sum + d.data().count, 0). With 10 shards: 10 writes/second capacity. With 100 shards: 100 writes/second. Trade-off: reads become more expensive (N document reads instead of 1). For read-heavy counters, cache the aggregated total in a separate document updated periodically by Cloud Functions. The newer Firestore aggregation queries (getCountFromServer(), getAggregateFromServer()) provide server-side counting without reading all documents.
Previous
How do you handle Firestore rate limits and quota exhaustion?
Next
How do you migrate from Firebase Realtime Database to Firestore?
More Firebase / Firestore Questions
View all →- Advanced How do you design a scalable data model in Firestore?
- Advanced How do you handle Firestore rate limits and quota exhaustion?
- Advanced How do you migrate from Firebase Realtime Database to Firestore?
- Advanced What are the performance optimization techniques for Firestore queries?
- Advanced How do you implement multi-tenant architecture with Firebase?