or run

npx @tessl/cli init
Log in

Version

Files

docs

attachments.mdbulk-queries.mdchanges-events.mddatabase-operations.mdindex.mdreplication-sync.md
tile.json

replication-sync.mddocs/

Replication & Synchronization

PouchDB's replication system provides comprehensive data synchronization between local and remote databases. It supports both one-way replication and bidirectional sync with extensive configuration options, conflict resolution, filtering capabilities, and robust error handling.

Capabilities

Static Replication Methods

PouchDB.replicate()

Replicates data from a source database to a target database using the static method.

/**
 * Replicate from source to target database
 * @param source - Source database (PouchDB instance or URL string)
 * @param target - Target database (PouchDB instance or URL string)
 * @param options - Replication configuration options
 * @param callback - Optional callback function (err, result) => void
 * @returns Replication object with event emitter interface
 */
PouchDB.replicate(source, target, options, callback);

Usage Examples:

// Basic replication
const replication = PouchDB.replicate('local-db', 'https://example.com/remote-db');

// Continuous replication with options
const replication = PouchDB.replicate(localDB, remoteDB, {
  live: true,
  retry: true,
  batch_size: 100
});

// One-time replication with callback
PouchDB.replicate(sourceDB, targetDB, {
  filter: 'myfilter/active-docs'
}, (err, result) => {
  if (err) {
    console.error('Replication failed:', err);
  } else {
    console.log('Replication completed:', result);
  }
});

PouchDB.sync()

Performs bidirectional synchronization between two databases using the static method.

/**
 * Bidirectional sync between two databases
 * @param source - First database (PouchDB instance or URL string)
 * @param target - Second database (PouchDB instance or URL string)
 * @param options - Sync configuration options
 * @param callback - Optional callback function (err, result) => void
 * @returns Sync object with event emitter interface
 */
PouchDB.sync(source, target, options, callback);

Usage Examples:

// Basic bidirectional sync
const sync = PouchDB.sync(localDB, remoteDB);

// Continuous sync with custom options
const sync = PouchDB.sync(localDB, 'https://example.com/db', {
  live: true,
  retry: true,
  push: { batch_size: 50 },
  pull: { batch_size: 100 }
});

// Sync with separate push/pull configuration
const sync = PouchDB.sync(localDB, remoteDB, {
  push: {
    filter: 'myfilter/outgoing',
    live: true
  },
  pull: {
    filter: 'myfilter/incoming',
    live: true
  }
});

Instance Replication Methods

db.replicate.to()

Replicates from the current database instance to a target database.

/**
 * Replicate this database to target
 * @param target - Target database (PouchDB instance or URL string)
 * @param options - Replication configuration options
 * @param callback - Optional callback function (err, result) => void
 * @returns Replication object with event emitter interface
 */
db.replicate.to(target, options, callback);

Usage Examples:

// Push local changes to remote
const replication = localDB.replicate.to(remoteDB, {
  live: true,
  retry: true
});

// Filtered push replication
const replication = localDB.replicate.to('https://example.com/db', {
  filter: (doc) => doc.type === 'public',
  live: true
});

db.replicate.from()

Replicates from a source database to the current database instance.

/**
 * Replicate from source to this database
 * @param source - Source database (PouchDB instance or URL string)
 * @param options - Replication configuration options
 * @param callback - Optional callback function (err, result) => void
 * @returns Replication object with event emitter interface
 */
db.replicate.from(source, options, callback);

Usage Examples:

// Pull remote changes to local
const replication = localDB.replicate.from(remoteDB, {
  live: true,
  retry: true
});

// Pull specific documents
const replication = localDB.replicate.from('https://example.com/db', {
  doc_ids: ['doc1', 'doc2', 'doc3']
});

db.sync()

Performs bidirectional synchronization between the current database instance and a target database.

/**
 * Bidirectional sync with target database
 * @param target - Target database (PouchDB instance or URL string)
 * @param options - Sync configuration options
 * @param callback - Optional callback function (err, result) => void
 * @returns Sync object with event emitter interface
 */
db.sync(target, options, callback);

Usage Examples:

// Basic sync
const sync = localDB.sync(remoteDB);

// Continuous sync with error handling
const sync = localDB.sync('https://example.com/db', {
  live: true,
  retry: true
});

sync.on('error', (err) => {
  console.error('Sync error:', err);
});

Replication Events

All replication and sync objects emit events that can be listened to for monitoring progress and handling errors.

Event Types

/**
 * Replication change event - fired when documents are replicated
 * @param info - Change information object
 */
replication.on('change', (info) => {
  // info.direction: 'push' | 'pull' (for sync operations)
  // info.change.docs: array of changed documents
  // info.change.docs_read: number of documents read
  // info.change.docs_written: number of documents written
});

/**
 * Replication complete event - fired when replication finishes
 * @param info - Completion information object
 */
replication.on('complete', (info) => {
  // info.ok: boolean indicating success
  // info.start_time: replication start timestamp
  // info.end_time: replication end timestamp
  // info.docs_read: total documents read
  // info.docs_written: total documents written
});

/**
 * Replication error event - fired when replication encounters an error
 * @param err - Error object
 */
replication.on('error', (err) => {
  // err.status: HTTP status code (if applicable)
  // err.name: error name
  // err.message: error message
});

/**
 * Replication denied event - fired when document replication is denied
 * @param err - Denial information
 */
replication.on('denied', (err) => {
  // err.id: document ID that was denied
  // err.reason: reason for denial
});

/**
 * Replication active event - fired when replication becomes active
 */
replication.on('active', () => {
  // Replication is actively transferring data
});

/**
 * Replication paused event - fired when replication is paused
 * @param err - Error that caused pause (if any)
 */
replication.on('paused', (err) => {
  // Replication has been paused (may resume automatically with retry: true)
});

Event Handling Examples

const replication = PouchDB.replicate(localDB, remoteDB, {
  live: true,
  retry: true
});

// Track replication progress
replication.on('change', (info) => {
  console.log(`Replicated ${info.change.docs_written} documents`);
  info.change.docs.forEach((doc) => {
    console.log(`Document updated: ${doc._id}`);
  });
});

// Handle completion
replication.on('complete', (info) => {
  console.log('Replication completed successfully');
  console.log(`Total documents: ${info.docs_written}`);
});

// Handle errors
replication.on('error', (err) => {
  console.error('Replication error:', err);
  if (err.status === 401) {
    console.error('Authentication required');
  }
});

// Monitor active/paused status
replication.on('active', () => {
  console.log('Replication is active');
});

replication.on('paused', (err) => {
  if (err) {
    console.log('Replication paused due to error:', err);
  } else {
    console.log('Replication paused');
  }
});

Replication Control

Canceling Replication

/**
 * Cancel an ongoing replication
 */
replication.cancel();

Usage Example:

const replication = PouchDB.replicate(localDB, remoteDB, { live: true });

// Cancel after 30 seconds
setTimeout(() => {
  replication.cancel();
  console.log('Replication canceled');
}, 30000);

Replication Status

// Check if replication is cancelled
if (replication.cancelled) {
  console.log('Replication has been cancelled');
}

Configuration Options

Core Replication Options

interface ReplicationOptions {
  /** Enable continuous replication that stays open and listens for changes */
  live?: boolean;
  
  /** Automatically retry replication on failure */
  retry?: boolean;
  
  /** Number of documents to process in each batch */
  batch_size?: number;
  
  /** Maximum number of concurrent batches */
  batches_limit?: number;
  
  /** Use checkpoints to resume interrupted replications */
  checkpoint?: boolean;
  
  /** Filter function or design document filter name */
  filter?: string | ((doc: any, params: any) => boolean);
  
  /** Array of specific document IDs to replicate */
  doc_ids?: string[];
  
  /** Parameters to pass to filter functions */
  query_params?: { [key: string]: any };
  
  /** Include or exclude document conflicts */
  style?: 'main_only' | 'all_docs';
  
  /** Authentication credentials */
  auth?: {
    username: string;
    password: string;
  };
  
  /** Custom headers for HTTP requests */
  headers?: { [key: string]: string };
  
  /** HTTP timeout in milliseconds */
  timeout?: number;
  
  /** Heartbeat interval for continuous replication */
  heartbeat?: number;
}

Sync-Specific Options

interface SyncOptions extends ReplicationOptions {
  /** Separate options for push replication */
  push?: ReplicationOptions;
  
  /** Separate options for pull replication */
  pull?: ReplicationOptions;
}

Advanced Configuration Examples

// Filtered replication with custom function
const replication = PouchDB.replicate(localDB, remoteDB, {
  live: true,
  filter: (doc) => {
    // Only replicate documents modified in last 24 hours
    const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
    return new Date(doc.modified).getTime() > dayAgo;
  }
});

// Replication with authentication and custom headers
const replication = PouchDB.replicate(localDB, 'https://example.com/db', {
  auth: {
    username: 'myuser',
    password: 'mypassword'
  },
  headers: {
    'Custom-Header': 'custom-value'
  },
  timeout: 30000,
  batch_size: 50
});

// Asymmetric sync with different push/pull settings
const sync = PouchDB.sync(localDB, remoteDB, {
  push: {
    filter: 'myfilter/outgoing',
    batch_size: 25
  },
  pull: {
    filter: 'myfilter/incoming', 
    batch_size: 100
  },
  live: true,
  retry: true
});

Error Handling

Common Error Types

interface ReplicationError {
  /** HTTP status code (if applicable) */
  status?: number;
  
  /** Error name/type */
  name: string;
  
  /** Human-readable error message */
  message: string;
  
  /** Detailed error information */
  error?: any;
  
  /** Error reason/cause */
  reason?: string;
}

Error Handling Patterns

const replication = PouchDB.replicate(localDB, remoteDB, {
  live: true,
  retry: true
});

replication.on('error', (err) => {
  switch (err.status) {
    case 401:
      console.error('Authentication failed');
      // Handle authentication error
      break;
    case 404:
      console.error('Database not found');
      // Handle missing database
      break;
    case 409:
      console.error('Conflict occurred');
      // Handle conflict
      break;
    default:
      console.error('Replication error:', err.message);
      // Handle other errors
  }
});

// Network error handling
replication.on('paused', (err) => {
  if (err) {
    console.log('Replication paused due to error, will retry...');
    // Replication will automatically retry if retry: true
  }
});

Performance Considerations

Optimizing Replication Performance

// Optimize for throughput
const replication = PouchDB.replicate(localDB, remoteDB, {
  batch_size: 500,        // Larger batches for better throughput
  batches_limit: 10,      // More concurrent batches
  live: true,
  retry: true
});

// Optimize for responsiveness
const replication = PouchDB.replicate(localDB, remoteDB, {
  batch_size: 50,         // Smaller batches for quicker updates
  batches_limit: 5,       // Fewer concurrent batches
  heartbeat: 10000,       // More frequent heartbeats
  live: true
});

// Memory-conscious replication
const replication = PouchDB.replicate(localDB, remoteDB, {
  batch_size: 100,
  batches_limit: 2,       // Limit memory usage
  live: true,
  retry: true
});