InfluxDB’s default limit of 1 million series can be a surprisingly effective bottleneck for even moderately high-cardinality workloads, forcing you to optimize your data model before you even hit what you think is your scale limit.
Let’s see what high cardinality looks like in practice. Imagine you’re monitoring a large fleet of IoT devices, each sending metrics with a unique device ID.
# Example data points
# device_id=device_0001, metric_name=temperature, value=25.5
# device_id=device_0001, metric_name=humidity, value=60.1
# device_id=device_0002, metric_name=temperature, value=24.9
# device_id=device_0002, metric_name=humidity, value=59.5
Each unique combination of device_id and metric_name creates a series. If you have 100,000 devices and each sends 10 different metrics, you’re already at 1,000,000 series. Add a few more tags, and you’ll quickly exceed the default.
The core problem InfluxDB solves here is efficiently storing and querying time-series data, particularly when dealing with a vast number of distinct data sources or measurement types (high cardinality). It achieves this through a specialized Time-Structured Merge Tree (TSM) storage engine. When you write data, it’s initially held in memory (a WAL - Write Ahead Log) and then batched into segments written to disk as TSM files. Indexes are built to allow rapid retrieval of series and points within a time range. The series limit is a safeguard against runaway cardinality that could lead to excessive memory usage for indexes and slow down write and query performance.
The primary lever you control is the max-series-per-measurement configuration option. This setting dictates the maximum number of unique series allowed within a single measurement.
Configuration:
You’ll need to edit your InfluxDB configuration file, typically located at /etc/influxdb/influxdb.conf.
-
Locate the
[cluster]section. If you’re running a single-node instance, this might be under[meta]or[data], depending on your InfluxDB version. For newer versions (v2.x and later), it’s often under[data]. -
Find or add
max-series-per-measurement. Uncomment it if it exists and is commented out, or add it if it’s not present.# /etc/influxdb/influxdb.conf [data] # Default is 1000000 max-series-per-measurement = 10000000 -
Restart InfluxDB.
sudo systemctl restart influxdb
This setting is applied per measurement. So, if you have a measurement cpu_usage and set max-series-per-measurement = 10000000, you can have up to 10 million unique series within that cpu_usage measurement. If you have another measurement, network_traffic, it also gets its own limit of 10 million series.
The mental model here is that InfluxDB is tracking every unique tag set for every field within a measurement as a distinct series. When you query, it uses these indexes to quickly find the relevant series and then the time-based data within them. Exceeding the limit means InfluxDB stops accepting new series for that measurement, preventing the index from growing uncontrollably.
When increasing this limit, it’s crucial to understand the trade-offs. A higher limit means InfluxDB will consume more memory to store and manage its series indexes. If you have truly astronomical cardinality (hundreds of millions or billions of series), you might hit memory limits on your server or experience degraded write performance as the system struggles to keep indexes in memory. Always monitor your system’s memory usage after making such changes. If you’re consistently hitting the series limit, it’s often a strong indicator that your data model needs re-evaluation to reduce cardinality, perhaps by aggregating data or using different tagging strategies.
The next hurdle you’ll likely encounter with high-cardinality data, after adjusting series limits, is query performance. Queries that scan across a vast number of series, even with appropriate time ranges, can become prohibitively slow.