A family of databases that gave up some SQL guarantees to win something else: horizontal scale, schema flexibility, sub-millisecond latency, or a data shape relational struggles with. Pick the right family, then design for the queries you'll actually run.
← Back to Database SideJSON-like records keyed by ID. Nested structures, flexible fields. MongoDB, Couchbase, Firestore, DynamoDB (single-table).
Just get(key) / set(key, value). Blazing fast. Redis, Memcached, DynamoDB, etcd.
Rows with sparse, dynamic columns; sorted by clustering key within a partition. Cassandra, ScyllaDB, HBase, Bigtable.
Nodes and edges as first-class citizens. Traversals over relationships. Neo4j, Neptune, ArangoDB, TigerGraph.
Adjacent stores worth knowing: Search (Elasticsearch, OpenSearch) for full-text and log analytics; Time-series (InfluxDB, TimescaleDB) for metrics; Vector (Pinecone, Weaviate, pgvector) for embeddings & RAG.
Cassandra and Bigtable are built around write-optimized log-structured merge trees. Tens of thousands of writes per second per node, linearly scalable. Use them for telemetry, event logs, IoT — anything that ingests faster than a single relational primary can handle.
DynamoDB and Redis answer "given this key, give me the value" in single-digit milliseconds at any size. Sessions, shopping carts, feature flags, user profiles by ID. The trade: queries that aren't keyed by the partition key get slow or expensive (or impossible).
Product catalogs across categories, third-party API payloads, CMS content. When fields differ per record and you don't want a hundred nullable columns, document stores fit. (But Postgres JSONB does too — only reach for a document DB when you also need its scaling model.)
"Friends of friends who liked the same artist." In SQL, that's a chain of joins that gets exponential. Graph databases store relationships as edges and traverse them in constant time per hop. Fraud detection, recommendation engines, identity graphs, knowledge bases.
Elasticsearch / OpenSearch invert documents into token indexes for relevance-scored search, faceting, and aggregations across billions of records. Postgres full-text gets you surprisingly far; reach for a dedicated search store when ranking quality, scale, or analytics outgrow it.
Relational: model the entities, then write any query. NoSQL: list every query first, then design tables/items so each query hits one partition. If a new query type appears, you may need a new table populated by a stream — that's the cost of denormalization.
Put multiple entity types in one table, distinguished by partition key prefix. Composite sort keys (USER#42, ORDER#2026-04-27#…) make hierarchical queries ("all orders for user 42 in April") a single key range scan. Powerful and unintuitive — read Alex DeBrie before you design.
The partition key decides which node owns the data. Choose it for even distribution. user_id with one whale customer = one node on fire while the rest idle. Bucket / salt high-cardinality writes; pre-split when you know the distribution.
In Cassandra, local secondary indexes are usually a trap — they fan out across the cluster. Prefer building a second table keyed by the alternate access path and writing to both. DynamoDB's GSIs are essentially exactly that, managed for you (and billed accordingly).
Most NoSQL stores default to eventual consistency on reads — you may briefly see stale data after a write. Many offer a strongly consistent read mode that costs more (DynamoDB doubles RCUs; Cassandra raises the consistency level, hurting availability and latency). Reach for it on read-after-write paths; tolerate eventual for everything else.
MongoDB has multi-document ACID transactions (4.0+). DynamoDB has TransactWriteItems across up to 100 items in one region. Cassandra has lightweight transactions via Paxos — slow, use sparingly. None of these are free; design so you rarely need them, and isolate hot money-paths in a relational DB if you do.
Eventual consistency means writes can land out of order or be retried. Make writes idempotent (deterministic key, upsert semantics). For concurrent updates, use last-writer-wins with a logical clock, conditional writes (IF version = N), or CRDTs for true merge.
ALTER TABLE. Plan for old shapes coexisting with new — versioned documents, dual-read, lazy upgrade on write.$lookup. If your query pattern is relational, use a relational DB.