Skill 99 · Timestream Influxdb
Subchapter 99.8
references/schema-design-guide.mdMarkdown4 KBView on GitHub
User asks about tag vs field decisions, cardinality management, table/measurement design, retention policies, or InfluxDB 3 best practices for data modeling.
Schema design differs significantly between V2 and V3. Confirm the engine before advising.
Line protocol (both engines):
measurement,tag1=val1,tag2=val2 field1=1.0,field2="text" timestampTags = indexed, low-cardinality metadata (device_id, region, sensor_type) Fields = values not indexed by default (temperature, cpu_usage, response_time) Timestamp = nanosecond precision, always present
Ask: “Will I filter or GROUP BY this column frequently?”
Cardinality rule: The product of all unique tag value combinations = series cardinality.
Table and column limits:
maxTables default: 4,000 per database. Recommended: keep under ~500 for optimal query performance.maxColumnsPerTable default: 200. Each unique tag key or field key counts as a column.Table design:
cpu, memory, http_requests)Partition templates:
--partition-template tag:region,tag:host,time:%Y-%m-%dDeduplication and uniqueness:
Field indexing (V3):
Fields are NOT indexed by default
For fields used in WHERE clauses, create a field index:
CREATE INDEX idx_status ON http_requests (status);Retention:
| Anti-Pattern | Problem | Fix |
|---|---|---|
Encoding data in tag values (e.g., sensor_123_temp) | Explodes cardinality | Split into sensor_id=123 tag + temp field |
| Using high-cardinality values as tags (UUIDs, timestamps) | V2: crashes. V3: bloated indexes | Move to fields; use field indexes if needed |
| Single mega-table for all data | Poor query performance, hard to manage | Split by measurement domain |
| Missing timestamp precision | Accidental deduplication | Use nanosecond precision for high-frequency data |
| Storing constants as fields | Wastes storage on every point | Move to tags (indexed once per series) |
For typical HTTP request log schemas, use these as default tags (low-to-moderate cardinality, commonly filtered/grouped):
method (~10 values: GET, POST, etc.)status_code (~20 values: 200, 404, 500, etc.)endpoint (the request path — typically <500 unique paths in a well-normalized API; commonly filtered/grouped in error queries)Note on endpoint cardinality: if the application logs raw paths with embedded IDs (e.g., /users/123 instead of /users/:id), normalize the path before ingestion. The default classification is tag.
response_time_ms, bytes_sent (numeric measurements)user_agent, request_id (unbounded cardinality — never tags)IoT sensor data:
sensors,device_id=d001,location=factory-a,type=temperature value=23.5 1714000000000000000
sensors,device_id=d001,location=factory-a,type=humidity value=45.2 1714000000000000000Application metrics:
http_requests,method=GET,endpoint=/api/users,status=200 response_time=45.2,bytes=1024 1714000000000000000Infrastructure monitoring:
cpu,host=web-01,region=us-east-1 usage_user=23.5,usage_system=5.2,usage_idle=71.3 1714000000000000000