Using Redis Sorted Sets for Recent User Search History
How should a system record a user’s recent search history in a way that is fast, ordered by recency, de-duplicated, and naturally bounded—without turning a lightweight behavior signal into a database concern? Recent searches show up everywhere: search bars, dashboards, internal tools. The data is useful, but only temporarily. It does not require strong consistency or long-term persistence, yet it is written frequently and read often.
The key insight is to treat recent search history as ephemeral user behavior, not core business data. Once framed this way, persisting every search into a relational table becomes unnecessarily heavy: high write volume, custom ordering logic, and periodic cleanup jobs just to keep the data small. The problem is not storage—it is recency and uniqueness.
Redis Sorted Sets (ZSET) provide a natural fit for this use case. Each user maps to a single key where the member represents a stable search identifier and the score represents the timestamp of the search. When a user searches again, inserting the same member simply refreshes its score, automatically moving it to the most recent position. Older entries are trimmed by rank, keeping the set bounded to a fixed size. This keeps both writes and reads simple: writes are O(log N) and idempotent, reads return already-ordered results, and the data structure enforces recency and de-duplication automatically.
The strength of this approach is not performance alone—it is semantic alignment. A sorted set naturally models what “recent searches” actually are: a small, ordered window of user intent where only the latest occurrence matters. By delegating ordering, uniqueness, and size limits to the data structure itself, application code stays minimal and predictable. There is no need for background cleanup, manual sorting, or duplicate handling logic. Equally important, this design supports graceful degradation. If Redis is temporarily unavailable, the core search functionality remains unaffected; only the convenience of recent history is lost. That trade-off matches the value of the feature.