Home/Packages/HoloDb.Client

HoloDb.Client · data

Embedded or networked. Same code either way.

HoloDb.Client connects your .NET app to a HoloDb server over TCP with mandatory TLS encryption and token authentication. Run SQL queries and bulk-load data using the same API as the embedded in-process HoloDbService, so you can swap from embedded to networked by changing only how you create the handle. Columnar results stay columnar on the wire — no row buffering or JSON serialization overhead.

v1.4.0 net8.0+ TLS by default opt-in resilience
dotnet add package EvaluatedApplications.HoloDb.Client

The problem

speed vs scalability, without two APIs

Building analytics or database-driven apps means choosing between speed (embed the database in-process) and scalability (run it on its own server). Embedding locks you to one machine; networking usually means two separate APIs that behave differently. HoloDb.Client lets you have both: one code path works with either the embedded engine or a remote server.

Why HoloDb.Client

what you get

Same API, embedded or networked

Execute, ExecuteAsync, BulkLoadAsync, GetStatsAsync, PingAsync — identical surface whether you talk to in-process HoloDbService or a remote server.

Columnar over the wire

Results are typed column arrays, matching the in-process engine's QueryResult structure — no serialization tax.

Secure by default

TLS is on. Trust a self-signed server with certificate pinning (thumbprint), or skip it in dev only.

Built-in resilience

Optional exponential backoff with full jitter, a circuit breaker, and a per-operation deadline budget — opt in where you need it, transparent where you don't.

Designed for concurrency

One client per concurrent worker, or pool clients upfront with HoloDbClientPool.

How to use it

basic, resilient, pinned

using HoloDb.Client; // Connect to server var client = await HoloDbClient.ConnectAsync("db.example.com", 5433); try { var result = await client.ExecuteAsync("SELECT id, value FROM data LIMIT 10"); foreach (var row in result.Rows) Console.WriteLine($"id={row[0]}, value={row[1]}"); } finally { await client.DisposeAsync(); }

Resilient client with retry, backoff, and a circuit breaker:

var resilient = await ResilientHoloDbClient.ConnectAsync( "db.example.com", 5433, retryDelay: TimeSpan.FromMilliseconds(200), maxAttempts: 3, breakerFailureThreshold: 5 ); // Automatically retries transient transport failures var result = await resilient.ExecuteAsync("SELECT COUNT(*) FROM data");

Pinned certificate (recommended for self-hosted):

var options = new HoloDbClientOptions { AuthToken = "your-token", UseTls = true, PinnedThumbprint = "ABC123DEF456..." // SHA-1 thumbprint }; var client = await HoloDbClient.ConnectAsync("localhost", 5433, options);

Key notes

good to know

One client = one session

Requests serialize through an internal queue; concurrent callers share the same TCP connection. Use one client per worker, or pool clients with HoloDbClientPool.

No automatic reconnect

A dropped socket raises an exception; reconnect explicitly, or opt into ResilientHoloDbClient which handles this transparently.

Transient vs application errors

HoloRemoteException (SQL errors, auth failures) is never retried; ResilientHoloDbClient retries only transport-level failures.

Version history: v1.2.0 added exponential backoff, v1.3.0 added the circuit breaker, v1.4.0 (current) adds operation deadline budgets across retries. Requires: .NET 8.0+, a HoloDb server v1.4.0+ (wire-protocol compatible), network connectivity with TLS support. License: proprietary, part of Evaluated Applications.