CH.Native 1.1.1

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package CH.Native --version 1.1.1
                    
NuGet\Install-Package CH.Native -Version 1.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CH.Native" Version="1.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CH.Native" Version="1.1.1" />
                    
Directory.Packages.props
<PackageReference Include="CH.Native" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CH.Native --version 1.1.1
                    
#r "nuget: CH.Native, 1.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CH.Native@1.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CH.Native&version=1.1.1
                    
Install as a Cake Addin
#tool nuget:?package=CH.Native&version=1.1.1
                    
Install as a Cake Tool

CH.Native

A high-performance modern .NET client for ClickHouse using the native binary TCP protocol.

NuGet NuGet Downloads .NET License

Quick Start

dotnet add package CH.Native
await using var connection = new ClickHouseConnection("Host=localhost;Port=9000");
await connection.OpenAsync();

var result = await connection.ExecuteScalarAsync<int>("SELECT 1");
Console.WriteLine(result); // 1

See the Getting Started Guide for more examples, or run samples/CH.Native.Samples.QuickStart for the same flow as a runnable project.

Features

  • Native Binary Protocol - Direct TCP communication on port 9000 for optimal performance
  • Full Async/Await - All operations are async with streaming support
  • ADO.NET Provider - Standard DbConnection implementation with Dapper compatibility
  • Bulk Insert - High-performance batched inserts with typed mapping
  • Compression - LZ4 (default) and Zstd compression support
  • Resilience - Built-in retry policies, circuit breakers, and health checking
  • Load Balancing - Multi-server support with round-robin, random, or first-available strategies
  • TLS/SSL - Secure connections with certificate validation
  • Telemetry - OpenTelemetry-compatible tracing, metrics, and logging
  • Type Safety - Full support for all ClickHouse types with .NET mapping

Supported ClickHouse Types

CH.Native supports the full ClickHouse type system across read, write, and bulk-insert paths. See Data Types for the complete CLR-mapping reference.

Category ClickHouse Types .NET Mapping
Signed integers Int8, Int16, Int32, Int64, Int128, Int256 sbyte, short, int, long, Int128, BigInteger
Unsigned integers UInt8, UInt16, UInt32, UInt64, UInt128, UInt256 byte, ushort, uint, ulong, UInt128, BigInteger
Floating point Float32, Float64, BFloat16 float, double, float
Fixed-point Decimal32(S), Decimal64(S), Decimal128(S), Decimal256(S) decimal (or ClickHouseDecimal for D128/256 wide range)
Boolean Bool bool
Date / Time Date, Date32, DateTime, DateTime('Tz'), DateTime64(P), Time, Time64(P) DateOnly, DateTime, DateTimeOffset, TimeOnly
String String, FixedString(N) string, byte[]
Network / IDs UUID, IPv4, IPv6 Guid, IPAddress
Enums Enum8, Enum16 sbyte, short (or your enum via cast)
Composites Nullable(T), Array(T), Map(K,V), Tuple(...), Nested(...), LowCardinality(T) T?, T[], Dictionary<K,V>, object[], object[][], T (transparent)
Geospatial Point, Ring, LineString, Polygon, MultiLineString, MultiPolygon Point, Point[], Point[][], Point[][][]
Semi-structured JSON, Dynamic, Variant(T0, T1, ...) string / JsonDocument, ClickHouseDynamic, VariantValue<T0, T1> (boxing-free 2-arm) or ClickHouseVariant (boxed N-arm)

All types round-trip through both the read path (ExecuteReaderAsync, QueryAsync<T>) and the bulk-insert path (CreateBulkInserter<T>). Nullable(...) wraps any non-composite type. Composites compose freely (e.g. Array(Nullable(LowCardinality(String)))).

Installation

dotnet add package CH.Native

Basic Usage

Execute a Query

await using var connection = new ClickHouseConnection("Host=localhost;Port=9000");
await connection.OpenAsync();

// Scalar query
var count = await connection.ExecuteScalarAsync<long>("SELECT count() FROM users");

// DDL/DML
await connection.ExecuteNonQueryAsync("CREATE TABLE IF NOT EXISTS users (id UInt32, name String) ENGINE = Memory");

Query with Parameters

var users = await connection.QueryAsync<User>(
    "SELECT * FROM users WHERE age > @minAge",
    new { minAge = 18 }
).ToListAsync();

Typed Results

public class User
{
    public uint Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

await foreach (var user in connection.QueryAsync<User>("SELECT * FROM users"))
{
    Console.WriteLine($"{user.Id}: {user.Name}");
}

Bulk Insert

var users = new List<User> { /* ... */ };

await using var inserter = connection.CreateBulkInserter<User>("users");
await inserter.InitAsync();
await inserter.AddRangeAsync(users);
await inserter.CompleteAsync();

ADO.NET / Dapper

await using var connection = new ClickHouseDbConnection("Host=localhost;Port=9000");
await connection.OpenAsync();

// Dapper
var users = await connection.QueryAsync<User>("SELECT * FROM users");

Documentation

Guide Description
Quick Start Get up and running in minutes
Configuration Connection strings, settings, TLS, multi-server
Authentication Password, JWT, SSH key, mTLS, role activation
Connection Pooling ClickHouseDataSource, sizing, observability
Dependency Injection AddClickHouse, keyed services, providers, health checks
Data Types ClickHouse to .NET type mapping reference
Resilience Retry policies, circuit breakers, load balancing
Bulk Insert High-performance data loading
ADO.NET & Dapper Standard provider and ORM integration
LINQ Provider connection.Table<T>(), operators, modifiers
Telemetry Tracing, metrics, and logging

Samples

End-to-end runnable console projects under samples/. Each picks a flavour by CLI arg, creates a temp table, runs the demo, and drops the table.

Project What it covers
QuickStart Runnable mirror of docs/quickstart.md — open a connection, scalar query, bulk insert, typed read. Start here.
Queries Every read path: scalar, reader, raw rows, typed, LINQ, ADO.NET, Dapper, pooled, resilient, progress, log analytics
Insert Every write path: single, collection, async stream, one-shot bulk, long-lived, dynamic, pooled, cross-database, plain SQL
Hosting ASP.NET host wiring: AddClickHouse, keyed DataSources, all four auth methods (password / JWT / SSH / mTLS) against a docker overlay, credential providers, per-request role activation, health checks, bulk insert

Performance

Three-way comparison against ClickHouse.Driver (HTTP) and Octonica (native TCP).

Query Latency

Benchmark CH.Native ClickHouse.Driver Octonica
SELECT 1 586 μs 978 μs 878 μs
COUNT(*) 1M rows 992 μs 1,408 μs 1,041 μs
SELECT 100 rows 660 μs 1,183 μs 710 μs

Large Result Sets

Benchmark CH.Native CH.Native (Lazy) ClickHouse.Driver Octonica
Stream 1M rows 100 ms 58 ms 263 ms 77 ms
Materialize 1M rows 234 ms 319 ms 442 ms 202 ms

Bulk Insert

Benchmark CH.Native ClickHouse.Driver Octonica
1M rows 97 ms 205 ms 1,489 ms

Memory Efficiency (1M rows)

Benchmark CH.Native CH.Native (Lazy) ClickHouse.Driver Octonica
Streaming 121 MB 25 MB 191 MB 78 MB
Bulk insert 0.4 MB 95 MB 27 MB

Enable lazy string materialization via connection string (StringMaterialization=Lazy) or builder (.WithStringMaterialization(StringMaterialization.Lazy)). Lazy mode defers UTF-8 string decoding until values are accessed, reducing memory by ~68% for streaming reads. Best for ExecuteReaderAsync / QueryAsync workloads; typed queries (QueryAsync<T>) always use eager decoding.

Apple M5, .NET 10.0, ClickHouse 25.3 — run benchmarks with dotnet run --project benchmarks/CH.Native.Benchmarks -c Release

Requirements

  • .NET 8.0, 9.0, or 10.0
  • ClickHouse server with native protocol enabled (port 9000)

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on CH.Native:

Package Downloads
CH.Native.DependencyInjection

Microsoft.Extensions.DependencyInjection integration for CH.Native. Registers ClickHouseDataSource as a singleton, supports keyed multi-database setups, IConfiguration binding, rotating-credential providers (JWT, SSH key, mTLS cert), and ASP.NET health checks.

CH.Native.Dapper

Dapper integration for CH.Native. Registers type handlers for array-typed parameters (int[], string[], long[], Guid[], etc.) so `new { ids = arr }` binds as a ClickHouse Array(T) on the wire instead of being expanded into a Tuple by Dapper's default list-expansion behaviour.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.2-prerelease.33 55 5/30/2026
1.1.2-prerelease.32 57 5/30/2026
1.1.2-prerelease.31 65 5/20/2026
1.1.2-prerelease.30 60 5/18/2026
1.1.2-prerelease.29 65 5/17/2026
1.1.2-prerelease.28 60 5/17/2026
1.1.2-prerelease.27 56 5/17/2026
1.1.2-prerelease.26 56 5/15/2026
1.1.1 141 5/9/2026
1.1.1-prerelease.25 69 5/9/2026
1.1.1-prerelease.24 81 5/8/2026
1.1.1-prerelease.23 63 5/7/2026
1.1.0 134 5/6/2026
1.1.0-prerelease.22 62 5/6/2026
1.0.1-prerelease.21 62 5/6/2026
1.0.1-prerelease.20 57 5/6/2026
1.0.1-prerelease.19 57 5/5/2026
1.0.1-prerelease.18 66 5/4/2026
1.0.1-prerelease.17 59 5/2/2026
1.0.1-prerelease.15 64 4/26/2026
Loading failed