ACID vs BASE
ACID vs BASE explained: atomicity, consistency, isolation, durability, and the basically-available, eventually-consistent alternative.
ACID and BASE describe two philosophies for data correctness. ACID databases guarantee that transactions are all-or-nothing, isolated and durable, which makes reasoning simple. BASE systems relax those guarantees (basically available, soft state, eventually consistent) to gain availability and horizontal scale. Most real systems use both, in different places.
ACID
| Property | Guarantee | Example |
|---|---|---|
| Atomicity | All operations in a transaction succeed, or none do | Debit account A and credit account B: never only one of them |
| Consistency | A transaction moves the database from one valid state to another; constraints (foreign keys, uniqueness, checks) always hold | A balance can't go below zero if a CHECK constraint forbids it |
| Isolation | Concurrent transactions don't see each other's partial work; the result is as if they ran in some order (to a degree set by the isolation level) | Two transfers on the same account don't lose an update |
| Durability | Once committed, data survives crashes and power loss | Committed data is in the write-ahead log on disk (and often on replicas) |
Under the hood: atomicity and durability come from a write-ahead log (WAL), where changes are logged before they're applied and replayed after a crash. Isolation comes from locks or MVCC (multi-version concurrency control). Isolation has levels with real trade-offs; see transactions and isolation levels.
BASE
- Basically available: the system keeps answering, even if some answers are stale or some features are degraded.
- Soft state: replicas may hold different values for a while; state changes even without new input as replication catches up.
- Eventually consistent: given no new writes, all replicas converge to the same value. See consistency models.
BASE came out of large-scale web systems (Amazon's Dynamo, early NoSQL) where staying up during failures and scaling writes across many machines mattered more than multi-row transactions.
Side by side
| ACID | BASE | |
|---|---|---|
| Focus | Correctness of each transaction | Availability and scale |
| Consistency | Strong, immediate | Eventual |
| Multi-record updates | Transactions across rows and tables | Usually single-item atomicity; multi-item needs app logic or sagas |
| Scaling writes | Harder: one primary, or distributed transactions | Easier: partition and replicate freely |
| Failure behaviour | May reject writes to stay correct | Keeps accepting writes, reconciles later |
| Typical stores | PostgreSQL, MySQL, Oracle, SQL Server; Spanner and CockroachDB (distributed ACID) | Cassandra, DynamoDB (default), Riak, CouchDB |
The lines have blurred. DynamoDB and MongoDB now offer ACID transactions, and distributed SQL databases (Spanner, CockroachDB, YugabyteDB) provide ACID across many machines. The useful question isn't "SQL or NoSQL" but which operations need transactional guarantees.
Getting ACID-like outcomes across services
Once data is split across services or databases, a single ACID transaction can't cover it. The common patterns are:
- [Sagas](/learn/saga-pattern): a sequence of local transactions with compensating actions on failure (cancel the order, refund the payment).
- [Transactional outbox](/learn/outbox-pattern): write the business change and the event to publish in one local transaction, so they can't diverge.
- [Idempotency](/learn/idempotency): make retries safe so at-least-once delivery doesn't double-apply.
- [Two-phase commit](/learn/two-phase-commit): true atomic commit across resources, at the cost of blocking and coupling.
Where it’s used
Double-entry ledgers rely on ACID transactions so every debit has a matching credit, and on constraints to forbid invalid states.
The order and payment records use ACID within a service; cross-service flows (inventory, shipping) use sagas and events.
Likes, view counts and follower counts live happily in BASE stores where a few seconds of disagreement is invisible.
The original BASE design: always-writable shopping carts with conflict resolution instead of transactions.
In an interview
- Identify the invariants that must never break (no double booking, balances never negative) and keep those operations in an ACID store.
- Use BASE where staleness is acceptable and say so explicitly: "the like count can lag by seconds".
- When a flow spans services, propose a saga with compensations rather than hand-waving "a transaction".
- Don't confuse ACID consistency (constraints hold) with CAP consistency (replicas agree).