Skip to main content

NoSQL databases

The term NoSQL encompasses a diverse family of non-relational distributed databases engineered to overcome the horizontal scaling limits of traditional single-node relational systems. To deliver predictable, single-digit millisecond latency and linear write scaling across massive datasets, NoSQL databases trade away multi-table SQL joins, arbitrary ad-hoc queries, and multi-record transactions.

In exchange for these constraints, NoSQL systems provide elastic write throughput, continuous global availability, and flexible data models that evolve without disruptive schema migrations. Rather than viewing NoSQL as a wholesale replacement for relational databases, experienced systems architects treat it as a specialized set of engines tailored for specific data access patterns.

Architectural models

Cloud providers offer several distinct NoSQL architectures, each optimized for different data shapes and query patterns:

  • A is the simplest and most performant distributed database shape. It maps opaque data payloads to unique alphanumeric keys via internal hash rings. Because lookups bypass complex query parsing and relational joins, key-value stores deliver ultra-low-latency point lookups regardless of dataset size. This architecture is the standard foundation for user session management, shopping cart state, distributed caching, and feature flags.
  • A manages semi-structured data as hierarchical, schema-free JSON or BSON documents. Unlike pure key-value systems, document stores index fields within the documents, enabling expressive filtering, nested attribute queries, and range evaluations within individual collections. Document stores excel at e-commerce product catalogs with heterogeneous attributes, dynamic content management, and user profiles that gain fields over time without formal database migrations.
  • A (descended from Google Bigtable and Apache Cassandra) organizes data into rows with dynamic, sparse column sets ordered sequentially on disk by partition and clustering keys. This sorted layout enables rapid sequential range scans across ordered keys. Wide-column stores are built for high-throughput write ingestion, making them ideal for time-series telemetry, IoT sensor events, and financial transaction logs.
  • An in-memory cache is a volatile, RAM-based key-value store that sits in front of persistent storage tiers to serve frequent reads with sub-millisecond latency, preventing read-heavy traffic from overwhelming primary databases.
ArchitecturePrimary lookup keyQuery & filtering capabilitiesCommon operational use cases
Key-value storeSingle primary partition keyDirect key lookups only; no secondary query capabilitiesSession management, shopping carts, feature toggles, distributed state
Document storeDocument identifier or any indexed attributeRich queries, range scans, and secondary indexes within collectionsE-commerce product catalogs, user profiles, content management
Wide-column storePartition key followed by clustered sorting keySequential range scans across sorted rows within a partitionHigh-throughput telemetry, IoT time series, financial ticker logs
In-memory cacheSingle primary keyIn-memory key lookups; complex data structures (sets, sorted sets)Low-latency caching layers, rate limiting, leaderboards

Why distributed stores scale

Traditional relational databases maintain foreign keys and transaction logs on a single primary node, making vertical CPU and memory limits an unavoidable architectural ceiling. Distributed NoSQL databases achieve horizontal scalability through (also called sharding), which divides datasets across a cluster of independent storage nodes.

Each node owns a subset of the total keyspace. Because write and read operations against different keys execute on separate physical machines without inter-node locks or shared memory contention, adding more nodes yields linear increases in total cluster throughput.

The trade-off is that queries spanning multiple partitions require coordinating across multiple nodes. A query that does not specify a partition key must execute as a distributed scan across every machine in the cluster, resulting in high latency and heavy resource consumption. Consequently, NoSQL schema design must always begin by identifying the exact queries the application needs to run, selecting keys that align directly with those access patterns.

The partition key

The is the specific attribute passed to the database's internal hash function to determine which physical storage node holds a given record. Selecting the partition key is the single most critical decision in NoSQL architecture.

An effective partition key exhibits high cardinality and distributes writes and reads uniformly across all cluster partitions. Conversely, a poorly chosen key directs disproportionate traffic to a single node, creating a "hot partition." A hot partition quickly exhausts its provisioned throughput, throttling queries and degrading application performance even when the overall cluster is running well below capacity.

Common partition key anti-patterns include:

  • Sequential timestamps: Directing all current writes for a given second or minute to the same physical partition.
  • Low-cardinality values: Partitioning by status flags, categories, or country codes that group millions of records under a handful of keys.
  • Skewed tenant identifiers: In multi-tenant systems where a single enterprise client generates 80% of all traffic, using tenant ID as the sole partition key creates severe partition skew. High-entropy keys (such as user UUIDs or composite keys combining tenant IDs with entity hashes) provide much more balanced data distribution.
Choosing a partition key

Derive partition key design directly from your application's primary query access patterns.

  1. Document every specific query the application will execute, noting the exact fields known at query time.
  2. Select a partition key that is present in the majority of queries and provides high cardinality across distinct values.
  3. Verify that write and read volumes will distribute uniformly across partitions, avoiding sequential timestamps or skewed tenant IDs.
  4. If secondary queries require searching on non-partition attributes, create targeted global secondary indexes rather than performing full table scans.

Consistency

Relational databases guarantee that every read receives the most recent committed write. In a distributed NoSQL store, data is replicated across multiple nodes and zones. When a write is accepted by the primary partition replica, changes propagate asynchronously to secondary replicas.

A read that queries a replica before the update has propagated may return stale data; this behavior is known as . Eventual consistency provides maximum read throughput and resilience against node outages, making it appropriate for product reviews, social feeds, and recommendation engines. However, for critical workflows where reading stale state causes financial or business errors (such as verifying account balances or validating user authorizations), applications must explicitly request strongly consistent reads. Strongly consistent reads query a quorum of replicas to guarantee data freshness, which incurs slightly higher latency and reduced availability during network partitions.

Billing and cost management

Managed NoSQL databases decouple billing from traditional server provisioning, charging based on consumed read and write throughput alongside stored gigabytes. Providers offer both provisioned capacity (reserving fixed reads and writes per second) and on-demand pricing (billing per individual operation).

On-demand billing is ideal for unpredictable or bursty workloads with intermittent traffic. However, unindexed queries that perform full-table scans read every record in the table, consuming immense capacity units and producing shocking billing spikes. Enforcing strict query patterns that leverage partition keys protects both system latency and operational budgets.

When NoSQL is the right answer

NoSQL databases are the right architectural choice when write throughput exceeds the physical capacity of a single relational primary, when records are inherently semi-structured and dynamic, or when systems require predictable, microsecond-to-millisecond point-lookup latencies at global scale.

If your data model is deeply relational, requires multi-table joins, or demands strict transactional atomicity across multiple entities, a relational database remains the superior tool. Attempting to implement manual joins across multiple NoSQL tables within application code is inefficient, prone to concurrency bugs, and essentially rebuilds an unoptimized relational database engine.

Terms introduced

  • Key-value store: a database that returns a value for a key, at any scale, and does nothing else.
  • Document store: a database that holds JSON-like documents and indexes fields inside them.
  • Wide-column store: a database of keyed, ordered rows with sparse columns, read by range.
  • Partitioning: splitting data by key across machines so that writes to different keys never contend.
  • Partition key: the field that decides which machine holds a record, and therefore which queries are fast.
  • Eventually consistent: a read that may return a value written a moment ago rather than the latest one.

How providers do it

Distributed NoSQL offerings reflect differing provider philosophies: AWS maintains distinct, specialized products for each data shape; Azure consolidates multiple NoSQL data models under Azure Cosmos DB; and Google Cloud provides two purpose-built engines in Cloud Firestore and Cloud Bigtable.

ConceptAWSAzureGoogle Cloud
Key-value storeAmazon DynamoDBAzure Table Storage, Cosmos DB Table APICloud Firestore (or Cloud Bigtable for high throughput)
Document storeAmazon DynamoDB; Amazon DocumentDB (MongoDB API)Azure Cosmos DB (NoSQL or MongoDB API)Cloud Firestore
Wide-column storeAmazon Keyspaces (Apache Cassandra compatible)Azure Cosmos DB (Cassandra API)Cloud Bigtable
In-memory caching layerAmazon ElastiCache, DynamoDB Accelerator (DAX)Azure Cache for Redis, Azure Managed RedisGoogle Cloud Memorystore
Partitioning identifierPartition key (with optional sort key)Partition key (defined at container creation)Row key (Cloud Bigtable); automatic document indexing (Firestore)
Throughput capacity metricRead/Write Capacity Units (RCU/WCU), or On-DemandRequest Units per second (RU/s)Per-operation pricing (Firestore); node provisioning (Bigtable)
Change data capture streamDynamoDB StreamsCosmos DB Change FeedFirestore triggers, Bigtable change streams
Multi-region active writesDynamoDB Global Tables (last-writer-wins)Cosmos DB multi-region writesMulti-region Spanner (Firestore and Bigtable are regional/dual-region)

Every product name and technical mapping above is confirmed against provider documentation. Specific feature compatibility limits for DocumentDB and operational tiers for Azure Managed Redis are marked unconfirmed in the provider tabs below.

A crucial behavioral difference involves default read consistency:

  • Amazon DynamoDB defaults to eventually consistent reads, requiring an explicit SDK parameter (ConsistentRead = true) to enforce strong consistency.
  • Google Cloud Firestore provides strong consistency by default for document and collection queries. Migrating application logic between these platforms without reviewing consistency configurations can introduce subtle read-after-write bugs.

What this maps to: Amazon DynamoDB is the key-value and document store. It is also what most people mean when they say "NoSQL on AWS". The cache is Amazon ElastiCache. If you arrive with Cassandra or MongoDB code, Amazon Keyspaces and Amazon DocumentDB are the compatibility products for running it.

ConceptOn AWSStatus
Key-value and document storeDynamoDB. Items are keyed by a partition key and an optional sort keyconfirmed
BillingOn-demand per request, or provisioned read and write capacity units with autoscalingconfirmed
ConsistencyReads are eventually consistent by default; a strongly consistent read costs twice as much and is not available on global secondary indexesconfirmed
Queries without the keyGlobal secondary index (any key) or local secondary index (same partition key, different sort)confirmed
Hot partitionDynamoDB spreads throughput across partitions; a single key taking a large share is throttled. Adaptive capacity softens thisconfirmed
CacheElastiCache for Redis OSS, Valkey, or Memcached. DAX is a cache built specifically for DynamoDBconfirmed
Wide-columnKeyspaces, Cassandra-compatibleconfirmed
Document, MongoDB APIDocumentDB, MongoDB-compatible, with the API version it supports lagging upstreamunconfirmed; check current compatibility
Change feedDynamoDB Streams, which can trigger a Lambda function on every writeconfirmed
Multi-regionGlobal tables, replicating a table across regions with last-writer-wins conflict resolutionconfirmed

Their vocabulary

Standard termTheir term
RecordItem
Partition keyPartition key (hash key in older docs)
Range within a partitionSort key (range key in older docs)
ThroughputCapacity units

Where to look

Consumed capacity and throttled requests are on the table's Metrics tab in the DynamoDB console. To see which keys are hot, turn on Contributor Insights.

Last verified: never.


Check your understanding

0 of 4 answered

  1. Why can a partitioned NoSQL store take more writes than a relational database?
  2. A time-series table uses the timestamp as its partition key. What goes wrong?
  3. An application keeps orders, customers, and products in three separate key-value stores and joins them in code. What has it built?
  4. Which read must not be eventually consistent?