NextdoorSlava MarkeyevExplainer
Scaling Nextdoor’s Datastores: Part 1
Summary
Nextdoor relies on a Django backend connected to monolithic PostgreSQL databases and Redis look-aside caches. Migrating to distributed SQL datastores proved impractical because legacy business logic depends heavily on multi-table joins that could not be rewritten. Intermediate mitigations, including read replicas and data partitioning by severing foreign keys, extended infrastructure runways but left primary databases vulnerable to load bottlenecks. Furthermore, look-aside caching and replica usage introduced data staleness risks, atomicity losses across partitioned databases, and inconsistent cache-population behaviors. To address these limitations, Nextdoor initiated an architecture redesign focused on dynamic query routing to replicas, replica-driven cache hydration, time-bounded eventual consistency, and schema-resilient cache serialization.
Context
Nextdoor's Django backend relies heavily on relational PostgreSQL data models with complex multi-table joins. Transitioning to distributed SQL was infeasible due to widespread legacy queries that a small team could not rewrite without halting product development. Over time, primary databases remained bottlenecks and single points of failure despite using Redis look-aside caches, read replicas, and partitioned databases.
Approach / What changed
Nextdoor evaluated the limits of their existing mitigations—severed foreign keys, look-aside caching, and read replicas—and initiated an architecture redesign. Their goals include dynamically routing read queries to replicas, populating caches directly from read replicas, guaranteeing time-bounded eventual cache consistency, and maintaining cache compatibility across schema modifications.
Takeaways
Adopting distributed SQL datastores can be blocked when entrenched application codebases rely heavily on multi-table joins across monolithic relational models.
Partitioning databases by severing foreign-key relationships extends scaling runway but can subtly break transactional atomicity during successive writes across databases.
Querying the primary database during a cache miss does not guarantee that the value written to the cache reflects the most up-to-date data.
Source and freshness
- Source
- engblog.nextdoor.com
- Published
- Added to Yomu
- Last updated
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.