NoSQL Stores
also called Non-Relational Databases
Storage engines that trade query flexibility and cross-entity transactions for predictable performance at scale under known access patterns.
Definition
A family rather than a category: key-value, document, wide-column, graph and time-series stores, united mainly by not being relational. What they share is that you must know your access patterns before you design the schema, because there is no planner to rescue a query you did not plan for.
Why they exist
The Dynamo work at Amazon is the clearest origin story. The requirement was a shopping cart that must accept writes even during a partition or a data-centre problem, because a customer unable to add an item is lost revenue, while a cart that briefly shows a slightly odd state is recoverable.
That requirement — availability over consistency for a specific operation with a bounded business cost — is not something a single-master relational system can satisfy. So the design chose always-writable replicas, conflict detection via version vectors, and reconciliation at read time, with the application deciding how to merge (for a cart, union the items, which errs toward the customer).
The lesson is not "use NoSQL". It is that the choice was made for one operation with a specific business asymmetry, not for a company.
Choosing between them
| Type | Fits | Breaks on |
|---|---|---|
| Key-value | Session state, caches, lookups by known key | Any query that is not by key |
| Document | Aggregates read and written whole; varying shapes | Cross-document consistency; ad-hoc joins |
| Wide-column | Very high write rates; time-series by partition | Queries that ignore the partition key |
| Graph | Deep multi-hop traversal | Bulk aggregation; simple lookups |
| Time-series | Append-only metrics with time-range reads | Updates; joins with business entities |
Failure scenarios
- Chosen for "scale" at a volume a relational database handles trivially, giving up joins, transactions and ad-hoc queries in exchange for nothing.
- Access patterns change. The schema was designed around three queries; the product needs a fourth. The answer is a full data re-model or a secondary index that undermines the performance story.
- Eventual consistency not surfaced to the product. The team assumes read-after-write and the bug appears only under load.
- Unbounded item growth. A document or partition that grows without limit — an order with a million line items, a partition key with too coarse a granularity — hits a hard limit in production.
- Application-level joins hidden in a loop, producing an N+1 pattern across the network.
Trade-offs
Bought: predictable latency at scale, horizontal write scaling, flexible or absent schema, and in some engines multi-region write availability. Sold: ad-hoc querying, cross-entity transactions, referential integrity, and the freedom to change your mind about access patterns cheaply.
The honest default for a new product is a relational database, with a deliberate move to a non-relational store for the specific workload that demonstrably needs it.
Interview question
"A team wants to replace PostgreSQL with a document store because 'it scales'. What evidence would change your mind, and what would you lose?"