Getting Started with InfluxDB: Setup and .NET Client Integration

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

Tags: InfluxDB Time Series Database .NET database integration Windows

Posted on Thu, 05 Nov 2026 16:51:50 +0000 by dstockto