What are Stateful Subscriptions?
A stateful subscription is a query that usesLIMIT or LIMIT + ORDER BY
clauses. These queries maintain state about which documents are currently within
the limit boundary, which can lead to performance challenges when documents
change.
Why This Matters
When a document within the limit boundary changes in certain ways, Ditto’s sync engine must invalidate its cache and re-execute the entire query. This cache invalidation significantly impacts sync performance, especially with:- High update frequencies
- Large result sets
- Multiple concurrent subscriptions
Understanding Cache Invalidation
Cache invalidation occurs when a document within the limit:- Is deleted or evicted
- No longer matches the filter (WHERE clause)
- Changes position due to ORDER BY (moves outside the limit boundary)
Query Performance Examples
✅ Good Queries
These queries minimize cache invalidation by filtering and sorting on immutable fields:For queries sorted by
createdAt DESC, new documents with larger timestamps are handled efficiently without cache invalidation through internal optimizations.⚠️ Suboptimal Queries
These queries filter on mutable fields while sorting on ones that don’t change frequently:❌ Poor Queries
Avoid these patterns that filter and sort on frequently updated fields:Best Practices
- Identify Fields that do not change: Use fields like IDs, creation timestamps, or static properties for filtering and sorting.
- Minimize Usage: If you must filter on fields that change often, avoid combining them with ORDER BY.
-
Consider Query Redesign: Instead of complex stateful queries, consider:
- Removing LIMIT and handling pagination client-side
- Splitting into multiple simpler queries
- Monitor Performance: Use Ditto’s logging at WARN level to identify queries causing frequent cache invalidation.
Migration Strategies
If you’re seeing performance issues with existing queries:- Remove ORDER BY: This eliminates position-based cache invalidation
- Use Immutable Alternatives: Replace mutable field filters with immutable equivalents
- Implement Client-Side Filtering: For small datasets, fetch more data and filter locally
- Add Indexes: Ensure proper indexing for ORDER BY queries to minimize re-query costs