InfluxDB is a purpose-built time series database optimized for high-throughput write operations and time-range queries. This guide covers the essential setup process on Windows and demonstrates how to integrate InfluxDB with .NET applications using the official client library.
Prerequisites
- Windows 10 or later
- InfluxDB 1.8.x (binary distribution)
- Visual Studio 2022
- .NET 6.0 SDK or higher
1. Installation and Configuration
Download
Obtain the Windows binary from the official InfluxData repository:
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.8.10-windows-amd64.zip -UseBasicParsing -OutFile influxdb-1.8.10-windows-amd64.zip
Extract the archive to your preferred location, such as C:\Program Files\InfluxData\InfluxDB.
Configuration
The primary configuration file is influxdb.conf in the installation directory. Key settings include:
- HTTP Binding: Configure the HTTP API endpoint
[http]
enabled = true
bind-address = ":8086"
auth-enabled = true
log-enabled = true
- Network Binding: Alow remote connections
# bind-address = "127.0.0.1:8088"
bind-address = ":8088"
Startup
Launch InfluxDB from the command line:
InfluxDB\influxd.exe -config InfluxDB\influxdb.conf
For ease of use, create a batch file in the InfluxDB directory:
@ECHO OFF
SET HOME=%~dp0
"%~dp0\influxd.exe" -config "%~dp0\influxdb.conf"
CLI Client Connection
Remote connections require authentication:
@ECHO OFF
"%~dp0\influx.exe" -host 192.168.1.100 -port 8086
pause
Authentication credentials can be configured via the CLI after connection:
auth
admin
admin_password
2. .NET Client Integration
Package Installation
Install the official InfluxDB client library via NuGet:
Install-Package InfluxDB.Client
Client Wrapper Implementation
The following wrapper provides asynchronous database operations:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api;
using InfluxDB.Client.Writes;
using InfluxDB.Client.Domain;
namespace Sensors.Timeseries
{
public class TsdbConnector
{
private readonly InfluxDBClient _client;
private string _bucketName;
private readonly string _org;
public TsdbConnector(string serverUrl, string token, string organization)
{
_org = organization;
_client = InfluxDBClientFactory.Create(serverUrl, token);
}
public async Task InitializeAsync(string bucket)
{
_bucketName = bucket;
await _client.GetBucketsApi().CreateBucketAsync(bucket, _org);
}
public async Task WriteRecordsAsync<TRecord>(string measurement, IEnumerable<TRecord> records)
where TRecord : class
{
try
{
var writer = _client.GetWriteApiAsync();
await writer.WriteRecordsAsync(records, WritePrecision.Ns, measurement, _bucketName, _org);
}
catch (Exception ex)
{
Console.WriteLine($"Write failed: {ex.Message}");
}
}
public async Task<long> CountRecordsAsync(string measurement, string filter)
{
var query = $"SELECT count(*) FROM {measurement} {filter}";
var result = await _client.GetQueryApi().QueryAsync(query, _org);
if (result?.Results.Count > 0)
{
var firstResult = result.Results[0];
if (firstResult.Series?.Count > 0)
{
return Convert.ToInt64(firstResult.Series[0].Values[0][1]);
}
}
return 0;
}
public async Task<List<TRecord>> QueryRecordsAsync<TRecord>(string query)
where TRecord : class
{
try
{
var result = await _client.GetQueryApi().QueryAsync<TRecord>(query, _org);
return result ?? new List<TRecord>();
}
catch (Exception ex)
{
Console.WriteLine($"Query failed: {ex.Message}");
return new List<TRecord>();
}
}
public void Dispose()
{
_client?.Dispose();
}
}
}
Data Model Definition
Define measurement classes using client attributes:
using System;
using InfluxDB.Client;
using InfluxDB.Client.Attributes;
namespace Sensors.Timeseries.Models
{
[Measurement("sensor_readings")]
public class SensorRecord
{
[Column("timestamp", IsTimestamp = true)]
public DateTime Timestamp { get; set; }
[Column("sensor_id")]
[Tag]
public string SensorId { get; set; }
[Column("reading_type")]
public int ReadingType { get; set; }
[Column("value")]
public double Value { get; set; }
[Column("recorded_at")]
public DateTime RecordedAt { get; set; }
}
}
Service Layer
Implement data access methods:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sensors.Timeseries
{
public class SensorDataService
{
private readonly TsdbConnector _tsdb;
private const string DefaultBucket = "sensor_data";
public SensorDataService(string endpoint, string authToken, string organization)
{
_tsdb = new TsdbConnector(endpoint, authToken, organization);
}
public async Task SetupAsync()
{
await _tsdb.InitializeAsync(DefaultBucket);
}
public async Task StoreReadingAsync(SensorRecord reading)
{
await _tsdb.WriteRecordsAsync("sensor_readings", new[] { reading });
}
public async Task<long> GetReadingCountAsync(string sensorIdentifier)
{
var filter = $"WHERE sensor_id = '{sensorIdentifier}'";
return await _tsdb.CountRecordsAsync("sensor_readings", filter);
}
public async Task<List<SensorRecord>> GetPaginatedReadingsAsync(
string sensorIdentifier, int pageSize, int pageOffset)
{
var query = $"SELECT * FROM sensor_readings " +
$"WHERE sensor_id = '{sensorIdentifier}' " +
$"ORDER BY time DESC " +
$"LIMIT {pageSize} OFFSET {pageOffset}";
return await _tsdb.QueryRecordsAsync<SensorRecord>(query);
}
public async Task<List<SensorRecord>> GetReadingsByTimeRangeAsync(
string sensorIdentifier, DateTime from, DateTime to)
{
var startStr = from.ToString("yyyy-MM-ddTHH:mm:ssZ");
var endStr = to.ToString("yyyy-MM-ddTHH:mm:ssZ");
var query = $"SELECT * FROM sensor_readings " +
$"WHERE sensor_id = '{sensorIdentifier}' " +
$"AND time >= {startStr} " +
$"AND time <= {endStr}";
return await _tsdb.QueryRecordsAsync<SensorRecord>(query);
}
}
}
3. Important Notes
When defining InfluxDB entity classes, adhere to these type constraints:
- Timestamp field marked with
[Column(IsTimestamp = true)]is mandatory—this field serves as the primary key for each measurement - Fields decorated with
[Tag]are indexed and restricted too string values only - Regular fields using
[Column]store numeric or boolean values and support aggregation queries
4. CLI Reference Commands
Common InfluxQL operations:
auth
admin
admin_password
show users
show databases
use database_name
show measurements
show field keys from measurement_name
show tag keys from measurement_name
precision rfc3339
SELECT * FROM measurement_name WHERE tag_name = 'tag_value' ORDER BY time DESC LIMIT 100 OFFSET 100