TSDB metrics
TSDB (time-series database) mode optimizes data streams for metrics storage. It enables sorted indices, synthetic _source, automatic deduplication, and downsampling -- significantly reducing storage for high-cardinality metrics.
- Ingesting metrics (CPU, memory, request latency, business KPIs)
- You have natural dimension fields (host, service, metric name)
- You want Elasticsearch's time-series optimizations (deduplication, downsampling)
TSDB requires at least one [Dimension] field and a [Timestamp]:
public class MetricEvent
{
[Timestamp]
[JsonPropertyName("@timestamp")]
public DateTimeOffset Timestamp { get; set; }
[Dimension]
[Keyword]
public string Host { get; set; }
[Dimension]
[Keyword]
public string MetricName { get; set; }
public double Value { get; set; }
[Keyword]
public string Unit { get; set; }
}
The combination of dimension fields and timestamp uniquely identifies a data point. Documents with the same dimensions and timestamp are deduplicated.
[ElasticsearchMappingContext]
[Entity<MetricEvent>(
Target = EntityTarget.DataStream,
DataStreamType = "metrics",
DataStreamDataset = "myapp",
DataStreamNamespace = "production",
DataStreamMode = DataStreamMode.Tsdb
)]
public static partial class MetricsContext;
var strategy = IngestStrategies.DataStream<MetricEvent>(MetricsContext.MetricEvent.Context, "90d");
var options = new IngestChannelOptions<MetricEvent>(transport, strategy, MetricsContext.MetricEvent.Context);
using var channel = new IngestChannel<MetricEvent>(options);
await channel.BootstrapElasticsearchAsync(BootstrapMethod.Failure);
For continuous metrics collection, tune the buffer for throughput:
var strategy = IngestStrategies.DataStream<MetricEvent>(MetricsContext.MetricEvent.Context, "90d");
var options = new IngestChannelOptions<MetricEvent>(transport, strategy, MetricsContext.MetricEvent.Context)
{
BufferOptions = new BufferOptions
{
InboundBufferMaxSize = 500_000,
OutboundBufferMaxSize = 5_000,
ExportMaxConcurrency = 8
}
};
using var channel = new IngestChannel<MetricEvent>(options);
await channel.BootstrapElasticsearchAsync(BootstrapMethod.Failure);
// Collect metrics on a timer
timer.Elapsed += (_, _) =>
{
channel.TryWrite(new MetricEvent
{
Timestamp = DateTimeOffset.UtcNow,
Host = Environment.MachineName,
MetricName = "cpu.usage",
Value = GetCpuUsage(),
Unit = "percent"
});
};
// At shutdown
await channel.WaitForDrainAsync(TimeSpan.FromSeconds(10), ctx);
- TSDB: TSDB mode configuration reference
- Time-series: standard data stream ingestion
- Data streams: data stream naming and bootstrap