Full vs Patch Mode
This guide explains the differences between full and patch modes for record subscriptions in Mesh, and helps you choose the right mode for your application.
Overview
When subscribing to records in Mesh, clients can choose between two modes:
- Full Mode: The client receives the entire record value on every update
- Patch Mode: The client receives only the changes (as JSON patches) between updates
Each mode has its advantages and trade-offs, and the right choice depends on your specific use case.
Full Mode
Full mode is the default and simplest approach. When a record changes, the client receives the complete new value.
How to Use Full Mode
let userProfile = {};
const { success, record, version } = await client.subscribeRecord(
"user:123",
(update) => {
// update contains { recordId, full, version }
userProfile = update.full;
console.log(
`Received full update for ${update.recordId} v${update.version}:`,
update.full
);
}
// No mode option means full mode (default)
);
if (success) {
userProfile = record;
}
Advantages of Full Mode
- Simplicity: No need to apply patches or track state changes
- Reliability: Always have the complete, correct state
- No special handling: Works with any data type, including primitives
- Easier debugging: The complete state is visible in each update
When to Use Full Mode
Full mode is ideal for:
- Small records (typically < 1KB)
- Records that change completely or mostly with each update
- Simple applications where bandwidth isn’t a major concern
- Records containing primitive values (strings, numbers, booleans)
- When you want the simplest implementation
Patch Mode
In patch mode, the client receives only the changes between updates as JSON patches. The client must apply these patches to its local copy of the record.
How to Use Patch Mode
import { applyPatch } from "@mesh-kit/core/client";
let productData = {};
const { success, record, version } = await client.subscribeRecord(
"product:456",
(update) => {
// update contains { recordId, patch?, full?, version }
if (update.patch) {
// Apply the patch to our local copy
applyPatch(productData, update.patch);
console.log(`Applied patch for ${update.recordId} v${update.version}`);
} else {
// Sometimes we'll get a full update for resynchronization
productData = update.full;
console.log(
`Received full (resync) for ${update.recordId} v${update.version}`
);
}
},
{ mode: "patch" } // Explicitly request patch mode
);
if (success) {
productData = record;
}
Advantages of Patch Mode
- Bandwidth efficiency: Only sends the changes, not the entire record
- Better for large records: Significantly reduces data transfer for big objects
- Precise change tracking: You can see exactly what changed in each update
When to Use Patch Mode
Patch mode is ideal for:
- Large records (typically > 1KB)
- Records where only small parts change with each update
- Applications where bandwidth is a concern
- Complex nested objects or arrays
- High-frequency updates to the same record
Limitations of Patch Mode
- Objects and arrays only: Patch mode only works for records that are objects or arrays, not primitive values
- More complex implementation: You need to apply patches and handle resynchronization
- Local state management: You must maintain the local state correctly
How Patching Works
When a record is updated in patch mode:
- The server retrieves the old value from Redis
- The server stores the new value in Redis
- The server computes a JSON patch between the old and new values
- The server broadcasts the patch to clients in patch mode (and full value to clients in full mode)
The JSON patch format follows the RFC 6902 standard. A typical patch looks like:
[
{ "op": "replace", "path": "/email", "value": "newemail@example.com" },
{ "op": "add", "path": "/status", "value": "active" }
]
Versioning and Resync
Both modes use versioning to ensure consistency:
- Every record update increments a version number
- Clients track the current version they have
- In patch mode, clients expect each update to have version = localVersion + 1
- If a gap is detected (missed update), the client is automatically sent a full record update to resync
This ensures that even in patch mode, clients eventually get back in sync if they miss updates.
Mixed Mode Subscriptions
Different clients can subscribe to the same record using different modes:
- Client A can subscribe in full mode
- Client B can subscribe in patch mode
- Both receive the same updates, just in different formats
The server handles this efficiently, computing patches only for clients that need them.
Performance Considerations
Bandwidth Usage
For a 100KB record where only 1KB changes:
- Full mode: Sends 100KB for each update
- Patch mode: Sends ~1KB for each update (plus some overhead)
CPU Usage
- Full mode: Lower CPU usage on client (just assignment)
- Patch mode: Higher CPU usage (computing and applying patches)
Memory Usage
Both modes use similar memory on the client, as they both maintain the complete record state.
Best Practices
-
Choose based on record size and update patterns
- Small records or complete changes → Full mode
- Large records with partial changes → Patch mode
-
Consider update frequency
- High-frequency updates benefit more from patch mode
- Infrequent updates may not need the complexity of patch mode
-
Test both modes with realistic data
- Measure bandwidth usage and performance
- Consider the trade-offs for your specific application
-
Handle resynchronization gracefully
- Be prepared to receive full updates even in patch mode
- This happens automatically when version mismatches occur
-
Use the right data structures
- Patch mode works best with stable object structures
- Frequent restructuring of objects may reduce the benefits of patching