Snapshots are automatic copies of the model state that Multisynq saves to the cloud. This system provides seamless persistence and enables new users to join existing sessions efficiently without replaying the entire event history.

What Are Snapshots?

📸 Snapshot Definition

Snapshots are serialized copies of your complete model state, saved periodically to the cloud. They capture:

  • All model properties and data
  • Current object relationships
  • Session state at a specific moment
  • Everything needed to restore the exact state

Snapshots are taken automatically by the Multisynq system - you don’t need to manually create them.

How Snapshots Work

1

Automatic Creation

The Multisynq reflector periodically requests one of the session participants to create a snapshot of the current model state.

// This happens automatically - no code needed
// The system serializes your entire model state
2

Cloud Storage

The snapshot is compressed and stored in the cloud, associated with your session ID.

// Snapshots are stored with metadata:
// - Session ID
// - Timestamp
// - Model state hash
// - Event sequence number
3

Restoration

When needed, the snapshot is loaded and your model state is restored exactly as it was.

// Your model's init() method won't be called
// The state is restored directly from the snapshot

Snapshot Use Cases

Automatic save functionality for your application

When users quit or reload:

  1. Session state is preserved in the latest snapshot
  2. When they return, the exact state is restored
  3. No progress is lost
// Example: Game state preservation
class GameModel extends Multisynq.Model {
    init() {
        this.level = 1;
        this.score = 0;
        this.playerPositions = new Map();
    }
    
    // All of this state is automatically saved in snapshots
    // and restored when the session resumes
}

New User Join Process

View Initialization Considerations

Important: When writing your View initialization, account for the fact that the Model may have been restored from a snapshot and already contains data.

class GameView extends Multisynq.View {
    init() {
        this.players = new Map();
        
        // This assumes the model starts empty
        // But it might already have players from a snapshot!
        this.subscribe("player", "joined", this.addPlayer);
    }
    
    addPlayer(player) {
        this.players.set(player.id, new PlayerVisual(player));
    }
    
    // Missing: handling existing players from snapshot
}

Snapshot Performance

Current Limitation: The snapshot system is currently unoptimized and may cause performance hitches when snapshots are taken.

  • Performance hitch: Brief pause when snapshot is taken
  • Visible to users: May notice application freeze
  • Depends on model size: Larger models = longer pause
// During snapshot creation:
// 1. Model state is serialized
// 2. Data is compressed
// 3. Snapshot is transmitted
// 4. Normal execution resumes

Best Practices

📊 Model Design

Keep your model state snapshot-friendly

  • Use simple, serializable data types
  • Avoid circular references
  • Keep the state tree flat when possible
  • Clean up unused objects regularly
// Good for snapshots
this.score = 100;
this.players = new Map();
this.gameState = "active";

// Avoid complex nested structures
this.deepNestedData = {...};

🎨 View Initialization

Design views to handle existing state

  • Check for existing model data in init()
  • Create visuals for pre-existing objects
  • Subscribe to future events
  • Handle both fresh starts and snapshot loads
init() {
    // Handle snapshot case
    this.initializeExistingState();
    
    // Handle future events
    this.subscribeToEvents();
}

🧪 Testing

Test your snapshot behavior

  • Test fresh session starts
  • Test joining existing sessions
  • Verify state restoration
  • Check view initialization
// Test both scenarios:
// 1. Fresh session (init() called)
// 2. Snapshot join (init() not called)

⚡ Performance

Optimize for snapshot performance

  • Monitor your model size
  • Use efficient data structures
  • Clean up regularly
  • Avoid storing view-specific data in models
// Good: Store only essential state
this.gameLogic = essentialData;

// Bad: Store view-specific data
this.uiElements = domElements;

Debugging Snapshots

Detect if your model loaded from a snapshot

class GameModel extends Multisynq.Model {
    init() {
        // This only runs for fresh sessions
        this.fromSnapshot = false;
        console.log("Fresh session start");
    }
    
    // Called after snapshot restore OR fresh init
    start() {
        if (!this.fromSnapshot) {
            this.fromSnapshot = true;
            console.log("Loaded from snapshot");
        }
    }
}

Common Patterns

Future Improvements

The Multisynq development team is working to make snapshots invisible to both users and developers:

  • Invisible performance: No more hitches during snapshot creation
  • Optimized storage: Smaller snapshots, faster loading
  • Better compression: Reduced network overhead
  • Incremental snapshots: Only save changes since last snapshot

Next Steps

Snapshots are fundamental to Multisynq’s persistence and scalability. Understanding how they work will help you design better models and views that handle session continuity seamlessly.