Skip to content
intermediatePhase 46 · Caching

Write-Behind

Write to cache first, asynchronously persist to database for performance.

30m
0 problems
Topic Progress0%

How Write-Behind Works

How Write-Behind Works

Write-Behind (also called Write-Back) writes to cache immediately and asynchronously persists to the database.

Flow Diagram

Write-Behind Flow:

App → Write to Cache → Return Success (immediate)
                         ↓
              [Background] → Batch write to DB

Fast writes, eventual persistence!

Implementation

class WriteBehindCache:
    def __init__(self, cache_client, db_client):
        self.cache = cache_client
        self.db = db_client
        self.write_queue = Queue()
        self.start_background_writer()
    
    def set(self, key, value, ttl=3600):
        """Write-behind: write to cache immediately, queue DB write"""
        # Write to cache (fast)
        self.cache.set(key, value, ttl)
        
        # Queue database write (async)
        self.write_queue.put({'key': key, 'value': value})
        
        return True  # Return immediately
    
    def start_background_writer(self):
        """Background thread to persist queued writes"""
        def writer():
            while True:
                batch = []
                # Collect batch of writes
                while not self.write_queue.empty() and len(batch) < 100:
                    batch.append(self.write_queue.get())
                
                if batch:
                    # Batch write to database
                    self.db.batch_upsert(batch)
                
                time.sleep(0.1)  # Small delay between batches
        
        thread = threading.Thread(target=writer, daemon=True)
        thread.start()

Characteristics

  1. Immediate cache write (fast response)
  2. Async database persistence
  3. Batch writes for efficiency
  4. Eventual consistency with database

Async Persistence

Async Persistence in Write-Behind

Persistence Strategies

Strategy Options:

1. Immediate Async:
   Write to cache → Queue for immediate DB write
   Pros: Low latency, simple
   Cons: Many small DB writes

2. Batched Async:
   Write to cache → Batch queue → Periodic DB write
   Pros: Efficient DB writes
   Cons: More data at risk

3. Time-Based Flush:
   Write to cache → Flush every N seconds
   Pros: Predictable DB load
   Cons: Fixed interval may not be optimal

Batch Implementation

class BatchedWriteBehind:
    def __init__(self, cache, db, batch_size=100, flush_interval=1.0):
        self.cache = cache
        self.db = db
        self.batch_size = batch_size
        self.flush_interval = flush_interval
        self.buffer = []
        self.lock = threading.Lock()
    
    def set(self, key, value, ttl=3600):
        # Immediate cache write
        self.cache.set(key, value, ttl)
        
        # Buffer for batch DB write
        with self.lock:
            self.buffer.append({'key': key, 'value': value})
            if len(self.buffer) >= self.batch_size:
                self.flush()
    
    def flush(self):
        """Flush buffer to database"""
        with self.lock:
            if self.buffer:
                self.db.batch_upsert(self.buffer)
                self.buffer = []

Durability Considerations

  • WAL (Write-Ahead Log): Persist to disk before acknowledging
  • Replication: Replicate cache to multiple nodes
  • Checkpointing: Periodic full snapshots to DB
  • Recovery: Rebuild cache from DB on failure

Risk Management

Risk Management in Write-Behind

Data Loss Scenarios

Risk Analysis:

1. Cache Failure:
   - Risk: Unpersisted writes lost
   - Mitigation: WAL, replication, short flush intervals

2. DB Failure:
   - Risk: Writes pile up in queue
   - Mitigation: Overflow to disk, circuit breaker

3. Process Crash:
   - Risk: In-memory buffer lost
   - Mitigation: Persistent queue, WAL

4. Network Partition:
   - Risk: Can't reach DB
   - Mitigation: Local persistence, retry with backoff

Safety Implementation

class SafeWriteBehind:
    def __init__(self, cache, db, wal_path='/data/wal'):
        self.cache = cache
        self.db = db
        self.wal = WriteAheadLog(wal_path)
    
    def set(self, key, value, ttl=3600):
        # 1. Write to WAL first (durability)
        self.wal.append({'op': 'set', 'key': key, 'value': value})
        
        # 2. Write to cache (performance)
        self.cache.set(key, value, ttl)
        
        # 3. Queue DB write (async)
        self.queue.put({'key': key, 'value': value})
    
    def recover(self):
        """Recover from WAL after crash"""
        pending = self.wal.replay()
        for entry in pending:
            self.cache.set(entry['key'], entry['value'])
            self.queue.put(entry)

When to Use Write-Behind

Good for:

  • High write throughput requirements
  • Write-heavy workloads
  • When slight data loss is acceptable
  • Analytics and logging
  • Session storage

Not ideal for:

  • Financial transactions
  • Critical data requiring strong consistency
  • Low-latency write requirements
  • Systems that can't tolerate data loss

Practice Problems

0/3solved
Design Write-Behind System

Design a scalable Write-Behind system. Cover high-level architecture, data model, and API design.

Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliability
Write-Behind Scaling

How would you scale Write-Behind to handle 10x the current load? Identify bottlenecks and solutions.

Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decomposition
Write-Behind Failure Modes

Analyze potential failure modes for Write-Behind and design mitigation strategies.

Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradation

Quiz

1. In Write-Behind, when is the database updated?

Question 1 options

2. What is the main risk of Write-Behind?

Question 2 options

3. How does batching help Write-Behind?

Question 3 options

4. What is a WAL (Write-Ahead Log) used for in Write-Behind?

Question 4 options

5. When should you NOT use Write-Behind?

Question 5 options

Flashcards

Question

What is Write-Behind caching?

Answer

A pattern where data is written to cache immediately and persisted to database asynchronously in the background

Question

What is the main risk of Write-Behind?

Answer

Data loss if cache fails before database persistence - mitigated by WAL and replication

Question

Why batch writes in Write-Behind?

Answer

Batching reduces database round trips and improves throughput by grouping multiple writes into single operations

Question

What does WAL stand for and why use it?

Answer

Write-Ahead Log - persists writes to disk before cache write to ensure durability and enable crash recovery

Question

Best use cases for Write-Behind?

Answer

High write throughput, analytics, logging, session storage - where eventual consistency is acceptable

Revision Notes

Key Takeaways

  • 1.Write-Behind provides fast writes by only writing to cache synchronously
  • 2.Main risk: data loss if cache fails before DB persistence
  • 3.Use WAL (Write-Ahead Log) for durability protection
  • 4.Batch writes improve database efficiency
  • 5.Not suitable for data requiring strong consistency

Interview Tips

  • Clearly explain the async nature and trade-offs
  • Discuss data loss scenarios and mitigations (WAL, replication)
  • Compare with Write-Through: speed vs consistency trade-off
  • Mention batching as a key optimization technique

Cheat Sheet

Cheat Sheet: Write-Behind

Flow

App → Cache Write → Return (immediate) → [Async] → DB Write

Key Points

  • Fast writes (cache only)
  • Eventual consistency
  • Risk of data loss
  • Use WAL for durability
  • Batch writes for efficiency

Risk Mitigation

  • Write-Ahead Log (WAL)
  • Cache replication
  • Short flush intervals
  • Overflow to disk

When to Use

  • High write throughput
  • Eventual consistency OK
  • Analytics/logging
  • NOT for financial data