# ACID vs BASE

> Strong consistency (ACID) or high availability (BASE) — the database design spectrum.

- **Category**: Trade-offs
- **Subcategory**: Distributed Systems
- **Canonical URL**: https://designpattern.fyi/trade_offs/acid-vs-base/

---

## Description
**Intent**: Choose the right consistency model for your database based on whether data correctness or system availability is more important.

**Context**: Traditional relational databases (PostgreSQL, MySQL) provide ACID transactions — every transaction is all-or-nothing, isolated from others, and permanently recorded. NoSQL databases (Cassandra, DynamoDB) embrace BASE — data is always writable, may be briefly inconsistent, but converges over time. The trade-off is strict correctness vs. horizontal scalability.

**Solution**: Use ACID when data integrity is non-negotiable — banking, inventory, orders, user accounts. Use BASE when availability and scale are priorities — social feeds, analytics, caching, IoT sensor data. ACID databases scale vertically — bigger machines, limited horizontal scaling. BASE databases scale horizontally — add nodes linearly, accept eventual consistency. Many systems use both — ACID for core transactional data, BASE for derived analytics.



## Use Cases
Payment processing where ACID is required to prevent double-charging or lost transactions. Real-time analytics dashboard where BASE is acceptable since slight data lag is tolerable for the sake of query performance. User profile service where BASE works well as profile updates can propagate asynchronously.



## Implementation Example

```javascript
// ACID Transaction Example
async function transferMoney(fromAccount, toAccount, amount) {
  const db = await getACIDDatabase();
  
  await db.transaction(async (tx) => {
    // Atomic: both succeed or both fail
    const balance = await tx.query(
      'SELECT balance FROM accounts WHERE id = $1',
      [fromAccount]
    );
    
    if (balance.rows[0].balance < amount) {
      throw new Error('Insufficient funds');
    }
    
    // Isolated: no other transaction sees intermediate state
    await tx.query(
      'UPDATE accounts SET balance = balance - $1 WHERE id = $2',
      [amount, fromAccount]
    );
    
    await tx.query(
      'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
      [amount, toAccount]
    );
    
    // Durable: changes are permanent once committed
  });
}

// BASE Model Example
async function updateUserProfile(userId, profileData) {
  const db = await getBASEDatabase();
  
  // Write immediately to local node
  await db.writeToLocal(userId, profileData);
  
  // Async replication (fire and forget)
  db.replicateToOtherNodes(userId, profileData)
    .catch(err => console.log('Replication failed, will retry later'));
  
  // Data is available immediately but may be stale on other nodes
  return { status: 'written', consistency: 'eventual' };
}

// Tunable Consistency Example
async function readData(key, consistencyLevel) {
  const db = await getDatabase();
  
  switch (consistencyLevel) {
    case 'strong':
      // Wait for quorum acknowledgment
      return await db.readFromQuorum(key);
    case 'eventual':
      // Read from any node, fastest
      return await db.readFromAnyNode(key);
    case 'bounded_staleness':
      // Read from nodes within specific time window
      return await db.readFromRecentNodes(key, '5s');
  }
}

```



## Trade-offs


### Advantages

- ACID provides strong guarantees — prevents data corruption, simplifies application logic

- BASE enables massive horizontal scaling — handle global traffic with linear node addition

- BASE systems remain available during network partitions — AP from CAP theorem

- Clear mental model for choosing database technologies based on use case




### Considerations & Drawbacks

- ACID limits scalability — vertical scaling has hard limits, horizontal scaling is complex

- BASE requires handling inconsistent data in application logic — more complex reasoning

- BASE has latency in convergence — data may be stale for seconds to minutes

- The spectrum is continuous, not binary — many databases offer tunable consistency levels







