MongoDB Time Series
Some data arrives as a steady stream of measurements over time. A weather station records the temperature every minute, a smart meter reports electricity use every hour, and a delivery app logs the position of a truck every few seconds. This kind of data is called time series data. MongoDB offers special time series collections that store and search it efficiently.
The Diary Picture
A time series collection works like a diary with one line per moment. Each line holds a time stamp and a measurement, and entries from the same source sit close together on the page. MongoDB groups related measurements internally, so reading a stretch of time touches far fewer storage blocks.
Sensor A: 10:00 -> 24.1 10:01 -> 24.2 10:02 -> 24.4 ...
Sensor B: 10:00 -> 19.8 10:01 -> 19.7 10:02 -> 19.7 ...
MongoDB stores nearby readings from each sensor together (internal buckets)Parts of a Time Series Collection
| Setting | Meaning | Required |
|---|---|---|
| timeField | The field that holds the date and time of each measurement | Yes |
| metaField | The field that describes the source, such as a sensor id or city | No, but recommended |
| granularity | A hint about the gap between measurements: seconds, minutes, or hours | No |
| expireAfterSeconds | Deletes old measurements automatically after this many seconds | No |
The timeField must store a Date value. The metaField should hold data that rarely changes, such as the sensor name and location.
Create a Time Series Collection
db.createCollection("weather", {
timeseries: {
timeField: "timestamp",
metaField: "sensor",
granularity: "minutes"
}
})The collection now expects a timestamp in every document and groups readings by the sensor field.
Add Measurements
db.weather.insertMany([
{ timestamp: new Date("2026-05-01T10:00:00Z"), sensor: { id: "S1", city: "Pune" }, temp: 31.2, humidity: 40 },
{ timestamp: new Date("2026-05-01T10:01:00Z"), sensor: { id: "S1", city: "Pune" }, temp: 31.4, humidity: 41 },
{ timestamp: new Date("2026-05-01T10:00:00Z"), sensor: { id: "S2", city: "Delhi" }, temp: 36.0, humidity: 25 }
])Insert documents the same way as in any other collection. MongoDB handles the grouping behind the scenes.
Query Time Series Data
Normal queries work without any change:
db.weather.find({
"sensor.id": "S1",
timestamp: { $gte: new Date("2026-05-01T10:00:00Z"), $lt: new Date("2026-05-01T11:00:00Z") }
})Average per Hour with Aggregation
db.weather.aggregate([
{ $match: { "sensor.id": "S1" } },
{ $group: {
_id: { $dateTrunc: { date: "$timestamp", unit: "hour" } },
avgTemp: { $avg: "$temp" },
maxTemp: { $max: "$temp" }
} },
{ $sort: { _id: 1 } }
])The $dateTrunc operator rounds each time stamp down to the hour, so the group stage builds one result per hour. Charts for dashboards often use this exact shape of query.
Automatic Deletion of Old Data
Old measurements often lose value after weeks or months. Set expireAfterSeconds when creating the collection, and MongoDB removes expired data automatically:
db.createCollection("serverLogs", {
timeseries: { timeField: "ts", metaField: "host", granularity: "seconds" },
expireAfterSeconds: 2592000
})The value 2592000 equals 30 days in seconds. Measurements older than 30 days disappear without any extra job.
Add an Index
MongoDB creates an internal index on the time field and the meta field for time series collections. Add secondary indexes for fields that queries filter on often:
db.weather.createIndex({ "sensor.id": 1, timestamp: 1 })Time Series vs Regular Collection
| Feature | Time Series Collection | Regular Collection |
|---|---|---|
| Storage size | Compact, because of internal grouping | Larger for the same readings |
| Best data type | Streams of measurements | General records |
| Updates and deletes | Limited | Fully flexible |
| Automatic expiry | Built in | Needs a TTL index |
Know the Limits
- The design favors inserts and reads. Updates and deletes on individual measurements work only in limited ways, so treat readings as write-once records.
- A time series collection must be created on purpose. An existing regular collection does not convert in place.
- Version support matters. Time series collections arrived in MongoDB 5.0, and newer versions add more features.
Real-World Uses
- Temperature, humidity, and air quality sensors
- Stock price history and trading volume
- Server performance metrics such as CPU and memory use
- Website visitor counts per minute
- Vehicle tracking and fuel use
Good Practices
- Put the source description into
metaFieldand keep it stable. - Choose the granularity that matches the real gap between readings.
- Insert measurements in batches with
insertManyfor better speed. - Set an expiry rule so the collection does not grow forever.
Summary
Time series collections store measurements that arrive over time in a compact and fast form. The timeField holds the date, the metaField describes the source, and the granularity hint tunes storage. Standard queries and aggregation stages such as $dateTrunc build hourly or daily summaries, and expireAfterSeconds clears old data automatically.
