RedisTimeSeries 1.0 moves time-window operations into a module
RedisTimeSeries adds retention, label filtering and aggregation to timestamped numeric samples. Its first general release replaces application-maintained time-series conventions with a dedicated data type.
A sorted set can order observations by timestamp without knowing what a measurement means. The application still has to decide how to represent repeated values, discard old samples and compute time-bucket aggregates. RedisTimeSeries 1.0 gives those operations a dedicated implementation. The main change is the ownership of the time-series rules that otherwise live in application code.
The 27 June general-availability announcement introduces the module's first general release. It is a Redis module, separately loaded into the server. Its commands operate on a numeric sample model with timestamps, and its versioned command documentation describes retention, queries and compaction rules together.
I have used Redis since its release and appreciate how far its existing data structures can go. A dedicated module becomes interesting when it removes rules an application would otherwise need to keep consistent across every writer and reader. Retention and aggregation are concrete examples of that work.
A sample has an explicit representation
The 1.0 README describes each sample as a timestamp and a value, with 64 bits for each. Samples occupy fixed-capacity memory chunks. That gives the module a representation designed for numeric observations, instead of asking the application to encode a measurement into an arbitrary string member.
The command reference specifies Unix timestamps in milliseconds and double-valued samples for TS.ADD. It also accepts * to take the timestamp from the system clock. This is a choice about who supplies event time. A producer with an observation timestamp can preserve it, while another producer can ask the server to timestamp receipt.
The reference defines retention relative to the last event time. That is more specific than deleting a key after a wall-clock timeout. A retained series can continue to exist while its eligible sample history changes. The unit and reference point matter when an application describes how much history remains available.
For example, the following commands create a labelled series and add two observations. The timestamps and intervals use milliseconds throughout.
TS.CREATE temperature RETENTION 60000 LABELS sensor_id 2 area_id 32
TS.ADD temperature 1548149180000 26
TS.ADD temperature 1548149181000 28
TS.RANGE temperature 1548149180000 1548149185000 AGGREGATION avg 5000
The range query requests averages over time buckets. This example does not require the reader to interpret a string convention or implement averaging in client code. The server receives the time interval and aggregate operation explicitly.
Retention and aggregation solve different problems
Retention limits the age of samples kept in a series. Aggregation at query time changes the resolution of a result. A request for an average over a bucket does not, by itself, establish a stored long-term summary. The command reference exposes a separate mechanism for that purpose.
TS.CREATERULE connects a source series to a destination series with an aggregation type and bucket duration. The destination must already exist as a time-series key. This makes the relationship an explicit stored rule, rather than an informal convention that readers reconstruct each time.
An application can therefore give raw samples and aggregate samples different retention settings. Those choices express different historical requirements. Keeping less detailed old data reduces the number of samples retained, but it also discards information that a different aggregate might have needed. An average alone cannot answer every later question about the original observations.
The documentation also states that compaction rules add work to insertion. Its TS.ADD complexity depends on the number of rules when rules exist. That is the expected cost of maintaining derived series during writes. Query-time aggregation and maintained rollups place their work at different points in the application's workload.
I find that distinction more useful than treating every aggregate as the same optimization. A query over existing raw samples and a rule that updates another key have different storage and write consequences. The module exposes both operations, so the application can express which result needs to persist.
Labels make series discoverable
The 1.0 interface attaches field-value labels to a series. TS.QUERYINDEX finds keys matching label filters, while TS.MRANGE queries ranges across matching series. This separates a series' identity as a Redis key from the dimensions used to discover it.
That is useful when a reader knows an area or sensor attribute without knowing every exact key name. A naming convention can encode those attributes, but it does not automatically supply an index over them. The module's label operations make selection part of the same implementation that owns the series.
The command reference documents exact-value and exclusion filters, along with tests for label presence. It also describes label replacement through TS.ALTER. Changing labels is therefore a metadata operation with defined behavior, not an instruction to rename the key and infer new attributes from its text.
That division reduces a common application obligation. Without a managed index, writers must update both the series and any separate lookup structures. The module supplies a label-based query interface tied to its own data type. Labels describe the series as a whole, so per-observation variation still belongs in the choice of series or in the sample model. The application still chooses useful dimensions and cardinalities, but it no longer needs to invent the basic indexing commands.
The module remains a deployment dependency
The README describes loading redistimeseries.so into redis-server. That requirement matters because a server offering Redis's built-in commands does not necessarily offer the TS.* commands. Client protocol access alone does not establish that the module is installed or that its version supplies the documented behavior.
The dedicated type also commits the application to the module's sample semantics. A generic stream can hold multiple arbitrary fields in an entry, while this model represents a numeric measurement over time. The useful simplification comes from choosing that narrower representation and its accompanying operations.
RedisTimeSeries 1.0 makes retention, indexed discovery and maintained time-bucket summaries explicit server operations. A system using those operations can describe its raw-history window and its aggregate-history window separately. The destination series and compaction rule record how one is derived from the other, so the retained summary has a defined relationship to the samples that produced it.