ClickHouse C# client
The official C# client for connecting to ClickHouse. The client source code is available in the GitHub repository. Originally developed by Oleg V. Kozlyuk.
Migration guide
- Update your
.csprojfile with the new package nameClickHouse.Driverand the latest version on NuGet. - Update all
ClickHouse.Clientreferences toClickHouse.Driverin your codebase.
Supported .NET versions
ClickHouse.Driver supports the following .NET versions:
- .NET Framework 4.6.2
- .NET Framework 4.8
- .NET Standard 2.1
- .NET 6.0
- .NET 8.0
- .NET 9.0
Installation
Install the package from NuGet:
Or using the NuGet Package Manager:
Quick start
Using Dapper:
Usage
Connection string parameters
| Parameter | Description | Default |
|---|---|---|
Host | ClickHouse server address | localhost |
Port | ClickHouse server port | 8123 or 8443 (depending on Protocol) |
Database | Initial database | default |
Username | Authentication username | default |
Password | Authentication password | (empty) |
Protocol | Connection protocol (http or https) | http |
Compression | Enables Gzip compression | true |
UseSession | Enables persistent server session | false |
SessionId | Custom session ID | Random GUID |
Timeout | HTTP timeout (seconds) | 120 |
UseServerTimezone | Use server timezone for datetime columns | true |
UseCustomDecimals | Use ClickHouseDecimal for decimals | false |
Example: Host=clickhouse;Port=8123;Username=default;Password=;Database=default
UseSession flag enables persistence of server session, allowing use of SET statements and temp tables. Session will be reset after 60 seconds of inactivity (default timeout). Session lifetime can be extended by setting session settings via ClickHouse statements.
ClickHouseConnection class normally allows for parallel operation (multiple threads can run queries concurrently). However, enabling UseSession flag will limit that to one active query per connection at any moment of time (server-side limitation).
Connection lifetime and pooling
ClickHouse.Driver uses System.Net.Http.HttpClient under the hood. HttpClient has a per-endpoint connection pool. As a consequence:
- A
ClickHouseConnectionobject does not have 1:1 mapping to TCP connections - multiple database sessions will be multiplexed through several (2 by default) TCP connections per server. - Connections can stay alive after
ClickHouseConnectionobject was disposed. - This behavior can be tweaked by passing a bespoke
HttpClientwith customHttpClientHandler.
For DI environments, there is a bespoke constructor ClickHouseConnection(string connectionString, IHttpClientFactory httpClientFactory, string httpClientName = "") which allows to generalize HTTP client settings.
Recommendations:
- A
ClickHouseConnectionrepresents a "session" with the server. It performs feature discovery by querying server version (so there is a minor overhead on opening), but generally it is safe to create and destroy such objects multiple times. - Recommended lifetime for a connection is one connection object per large "transaction" spanning multiple queries. There is a minor overhead on connection startup, so it's not recommended to create a connection object for each query.
- If an application operates on large volumes of transactions and requires to create/destroy
ClickHouseConnectionobjects often, it is recommended to useIHttpClientFactoryor a static instance ofHttpClientto manage connections.
Creating a table
Create a table using standard SQL syntax:
Inserting data
Insert data using parameterized queries:
Bulk insert
Using ClickHouseBulkCopy requires:
- Target connection (
ClickHouseConnectioninstance) - Target table name (
DestinationTableNameproperty) - Data source (
IDataReaderorIEnumerable<object[]>)
- For optimal performance, ClickHouseBulkCopy uses the Task Parallel Library (TPL) to process batches of data, with up to 4 parallel insertion tasks (this can be tuned).
- Column names can be optionally provided via
ColumnNamesproperty if source data has fewer columns than target table. - Configurable parameters:
Columns,BatchSize,MaxDegreeOfParallelism. - Before copying, a
SELECT * FROM <table> LIMIT 0query is performed to get information about target table structure. Types of provided objects must reasonably match the target table. - Sessions are not compatible with parallel insertion. Connection passed to
ClickHouseBulkCopymust have sessions disabled, orMaxDegreeOfParallelismmust be set to1.
Performing SELECT queries
Execute SELECT queries and process results:
Raw streaming
Nested columns support
ClickHouse nested types (Nested(...)) can be read and written using array semantics.
AggregateFunction columns
Columns of type AggregateFunction(...) cannot be queried or inserted directly.
To insert:
To select:
SQL parameters
To pass parameters in query, ClickHouse parameter formatting must be used, in following form:
Examples:
- SQL 'bind' parameters are passed as HTTP URI query parameters, so using too many of them may result in a "URL too long" exception.
- To insert large volume of records, consider using Bulk Insert functionality.
Supported data types
ClickHouse.Driver supports the following ClickHouse data types with their corresponding .NET type mappings:
Boolean types
Bool→bool
Numeric types
Signed Integers:
Int8→sbyteInt16→shortInt32→intInt64→longInt128→BigIntegerInt256→BigInteger
Unsigned Integers:
UInt8→byteUInt16→ushortUInt32→uintUInt64→ulongUInt128→BigIntegerUInt256→BigInteger
Floating Point:
Float32→floatFloat64→double
Decimal:
Decimal→decimalDecimal32→decimalDecimal64→decimalDecimal128→decimalDecimal256→BigDecimal
String types
String→stringFixedString→string
Date and time types
Date→DateTimeDate32→DateTimeDateTime→DateTimeDateTime32→DateTimeDateTime64→DateTime
Network types
IPv4→IPAddressIPv6→IPAddress
Geographic types
Point→TupleRing→Array of PointsPolygon→Array of Rings
Complex types
Array(T)→Array of any typeTuple(T1, T2, ...)→Tuple of any typesNullable(T)→Nullable version of any typeMap(K, V)→Dictionary<K, V>
DateTime handling
ClickHouse.Driver tries to correctly handle timezones and DateTime.Kind property. Specifically:
DateTimevalues are returned as UTC. User can then convert them themselves or useToLocalTime()method onDateTimeinstance.- When inserting,
DateTimevalues are handled in following way:UTCDateTimes are inserted 'as is', because ClickHouse stores them in UTC internally.LocalDateTimes are converted to UTC according to user's local timezone settings.UnspecifiedDateTimes are considered to be in target column's timezone, and hence are converted to UTC according to that timezone.
- For columns without timezone specified, client timezone is used by default (legacy behavior).
UseServerTimezoneflag in connection string can be used to use server timezone instead.
Logging and diagnostics
The ClickHouse .NET client integrates with the Microsoft.Extensions.Logging abstractions to offer lightweight, opt-in logging. When enabled, the driver emits structured messages for connection lifecycle events, command execution, transport operations, and bulk copy uploads. Logging is entirely optional—applications that do not configure a logger continue to run without additional overhead.
Quick start
Using ClickHouseConnection
Using appsettings.json
You can configure logging levels using standard .NET configuration:
Using in-memory configuration
You can also configure logging verbosity by category in code:
Categories and emitters
The driver uses dedicated categories so that you can fine-tune log levels per component:
| Category | Source | Highlights |
|---|---|---|
ClickHouse.Driver.Connection | ClickHouseConnection | Connection lifecycle, HTTP client factory selection, connection opening/closing, session management. |
ClickHouse.Driver.Command | ClickHouseCommand | Query execution start/completion, timing, query IDs, server statistics, and error details. |
ClickHouse.Driver.Transport | ClickHouseConnection | Low-level HTTP streaming requests, compression flags, response status codes, and transport failures. |
ClickHouse.Driver.BulkCopy | ClickHouseBulkCopy | Metadata loading, batch operations, row counts, and upload completions. |
Example: Diagnosing connection issues
This will log:
- HTTP client factory selection (default pool vs single connection)
- HTTP handler configuration (SocketsHttpHandler or HttpClientHandler)
- Connection pool settings (MaxConnectionsPerServer, PooledConnectionLifetime, etc.)
- Timeout settings (ConnectTimeout, Expect100ContinueTimeout, etc.)
- SSL/TLS configuration
- Connection open/close events
- Session ID tracking
Debug mode: network tracing and diagnostics
To help with diagnosing networking issues, the driver library includes a helper that enables low-level tracing of .NET networking internals. To enable it you must pass a LoggerFactory with the level set to Trace, and set EnableDebugMode to true (or manually enable it via the ClickHouse.Driver.Diagnostic.TraceHelper class). Warning: this will generate extremely verbose logs, and impact performance. It is not recommended to enable debug mode in production.
ORM & Dapper support
ClickHouse.Driver supports Dapper (with limitations).
Working example:
Not supported: