Overview
Delta compression reduces bandwidth usage by sending only the differences between consecutive messages instead of full messages. With conflation keys, messages are grouped by entity (e.g., stock symbol, device ID) for dramatically improved compression efficiency when broadcasting updates for multiple entities on a single channel. Bandwidth Savings: 60-90% typical, 80-95% with conflation keysQuick Start
Server Configuration
config/config.json
Client Implementation
Key Features
Core Capabilities
- Backwards Compatible - Standard Pusher clients work without changes
- Opt-in - Clients explicitly enable delta compression
- Per-Socket State - Independent delta state per connection
- Per-Channel Tracking - Separate state for each subscribed channel
- Thread-Safe - Lock-free concurrent access (DashMap)
- Automatic Fallback - Sends full messages when deltas are larger
- Encrypted Channel Detection - Automatically skips
private-encrypted-*channels
Conflation Keys
- Entity Grouping - Messages grouped by entity (e.g., “BTC”, “ETH”)
- Per-Key Delta State - Each entity maintains independent delta history
- Cache Synchronization - Clients receive initial state on subscription
- FIFO Eviction - Configurable cache size with automatic cleanup
- Pattern Matching - Wildcard support (
"market-*","*-data") - Per-Channel Configuration - Different settings per channel
Publisher Control
- Per-Publish Delta Flag - Publishers can force delta or full messages per-event
- Channel-Level Configuration - Different compression settings per channel pattern
Client Negotiation
- Per-Subscription Delta Settings - Clients can negotiate delta per-channel
- Algorithm Selection - Clients can request specific algorithms per-channel
- Flexible Formats - Support for simple string, boolean, or object configuration
Compression Algorithms
Fossil Delta (Default)
Best for: General purpose, text-heavy messages| Metric | Rating | Notes |
|---|---|---|
| Speed | ⭐⭐⭐⭐⭐ | 500ns - 2µs per message |
| Compression | ⭐⭐⭐⭐ | 70-85% bandwidth savings |
| Small messages | ⭐⭐⭐⭐⭐ | Excellent for < 1KB |
| Large messages | ⭐⭐⭐ | Degrades above 5KB |
Xdelta3
Best for: Maximum compression, large messages| Metric | Rating | Notes |
|---|---|---|
| Speed | ⭐⭐⭐⭐ | 1-2µs per message |
| Compression | ⭐⭐⭐⭐⭐ | 80-90% bandwidth savings |
| Small messages | ⭐⭐⭐ | Slower than Fossil |
| Large messages | ⭐⭐⭐⭐⭐ | 4x faster than Fossil at 5KB |
| Standard | ✅ | VCDIFF (RFC 3284) |
Algorithm Selection
Why Conflation Keys?
The Problem (Without Conflation)
When multiple entities share a channel, sequential comparison produces poor compression:The Solution (With Conflation Keys)
Grouping messages by entity dramatically improves compression:Real-World Impact
| Scenario | Without Conflation | With Conflation | Improvement |
|---|---|---|---|
| 5 messages, 2 assets | 32.6% savings | 40.1% savings | +7.5% |
| 100 messages, 10 assets | ~50% savings | ~75% savings | +25% |
| 1000 messages, 100 assets | ~50% savings (500KB) | ~85% savings (145KB) | +35% |
Configuration
Global Settings
| Option | Default | Description |
|---|---|---|
enabled | true | Enable/disable globally |
algorithm | "Fossil" | Compression algorithm ("Fossil" or "Xdelta3") |
full_message_interval | 10 | Send full message every N deltas |
min_message_size | 100 | Minimum size (bytes) to compress |
max_state_age_secs | 300 | Max state age before cleanup |
max_channel_states_per_socket | 100 | Max channels per socket |
Per-Channel Configuration
Simple Format (String-based)
"Fossil", "Xdelta3", "disabled", "inherit"
Full Format (With Conflation Keys)
| Option | Description | Example |
|---|---|---|
enabled | Enable for this channel | true |
algorithm | Algorithm to use | "Fossil", "Xdelta3" |
conflation_key | JSON path to entity key | "asset", "data.symbol" |
max_messages_per_key | Cache size per entity | 100 |
max_conflation_keys | Max entities to track | 1000 |
enable_tags | Include tags in messages | true |
Pattern Matching
Supports wildcard patterns with priority-based matching:| Pattern | Matches | Priority |
|---|---|---|
"market-data" | Exact: "market-data" | 1 (highest) |
"market-*" | Prefix: "market-btc", "market-eth" | 2 |
"*-data" | Suffix: "market-data", "sensor-data" | 2 |
"*" | All channels | 3 (lowest) |
Per-Publish Delta Control
Publishers can control delta compression on a per-message basis:When to Use
| Scenario | delta value | Reason |
|---|---|---|
| Incremental updates | true or omit | Small changes benefit from delta compression |
| Full state snapshots | false | Large state changes won’t compress well |
| Critical messages | false | Ensure clients get full data |
| Schema changes | false | Breaking changes need full message |
Per-Subscription Delta Negotiation
Clients can negotiate delta compression settings on a per-channel basis:Subscription Message Formats
Priority Order
Delta compression settings are resolved in this order (highest priority first):- Encrypted channel detection - Always disabled for
private-encrypted-* - Per-subscription settings - Client’s subscription-time request
- Per-channel server config -
channel_delta_compressionin app config - Global socket state -
pusher:enable_delta_compressionevent - Server default -
delta_compression.enabledin server config
Horizontal Scaling
Node-Local Intervals (Default)
By default, each node tracks delta intervals independently:- Zero coordination overhead
- No additional latency
- Works with any adapter
- Simpler architecture
- Full messages may be sent more frequently (still ~60-90% savings)
- Each node resets intervals independently
Cluster Coordination (Optional)
Enable synchronized full message intervals across all nodes:- Synchronized full message intervals cluster-wide
- Maximum compression efficiency
- Optimal for high-throughput scenarios
- Adds ~0.5-1.2ms latency per message
- Requires Redis or NATS adapter
Use Cases
✅ Perfect For
1. Market Data Feeds- Channel:
"market-data", Key:"asset" - Groups: BTC, ETH, ADA, etc.
- Savings: 80-90%
- Channel:
"sensors", Key:"device_id" - Groups: sensor-1, sensor-2, etc.
- Savings: 70-85%
- Channel:
"game-lobby", Key:"player_id" - Groups: player1, player2, etc.
- Savings: 60-80%
- Channel:
"presence", Key:"user_id" - Groups: user-123, user-456, etc.
- Savings: 65-75%
❌ Not Beneficial
- Only one entity per channel (use proper channel design)
- Completely random data with no recurring patterns
- Very few messages per entity (overhead not worth it)
- Messages < 100 bytes (overhead exceeds savings)
Performance
Bandwidth Savings
| Scenario | Compression | Typical Savings |
|---|---|---|
| Similar sequential messages | Yes | 60-90% |
| Interleaved entities (no conflation) | Yes | 30-50% |
| Interleaved entities (with conflation) | Yes | 80-95% |
| Completely different messages | No (fallback) | 0% |
CPU Overhead
| Operation | Time | Impact |
|---|---|---|
| Fossil delta generation | 500ns - 2µs | Minimal |
| Xdelta3 delta generation | 1-2µs | Low |
| Key extraction | <1µs | Negligible |
| Cache lookup | O(1) | Negligible |
| Pattern matching | O(n) patterns | ~1µs |
Memory Usage
Encrypted Channel Detection
Delta compression is automatically disabled forprivate-encrypted-* channels:
- Why: Encrypted payloads have no similarity (unique nonces)
- Result: Zero compression benefit, wasted CPU cycles
- Detection: Automatic - no configuration needed
Best Practices
1. Start Conservative
Begin with global settings, add per-channel optimization later:2. Monitor Memory
Adjust cache limits based on actual usage:3. Use Patterns
Group similar channels:4. Test First
Verify compression ratio before deploying to production.Troubleshooting
Delta Compression Not Working
Check 1: Is it enabled in config?min_message_size is 100 bytes
Cache Sync Not Received
Check 1: Is conflation key configured?Poor Compression Ratio
Symptom: Delta messages as large as original Causes:- Messages differ significantly between updates
- Wrong conflation key (not grouping correctly)
- Message size too small (< 100 bytes)
- Verify conflation key matches your data structure
- Check
full_message_interval- may be too low - Consider disabling for channels with random data
Migration Guide
From No Compression
1. Add global config:Adding Conflation Keys
1. Identify entity field: e.g.,"asset", "device_id"
2. Configure per channel:
Next Steps
Tag Filtering
Combine with server-side filtering for maximum efficiency
Rate Limiting
Control message throughput per application