Thunderstrike 0.1.3

dotnet add package Thunderstrike --version 0.1.3
                    
NuGet\Install-Package Thunderstrike -Version 0.1.3
                    
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="Thunderstrike" Version="0.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Thunderstrike" Version="0.1.3" />
                    
Directory.Packages.props
<PackageReference Include="Thunderstrike" />
                    
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 Thunderstrike --version 0.1.3
                    
#r "nuget: Thunderstrike, 0.1.3"
                    
#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 Thunderstrike@0.1.3
                    
#: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=Thunderstrike&version=0.1.3
                    
Install as a Cake Addin
#tool nuget:?package=Thunderstrike&version=0.1.3
                    
Install as a Cake Tool

Thunderstrike

.NET client for the thunderstrike key-value database: a pool of pipelined TLS 1.3 connections, with blocking and Task-based APIs.

The package carries the compiled client library for each platform under runtimes/<rid>/native/; restore and publish put the right one next to your app. Nothing to compile, no other dependencies.

Install

dotnet add package Thunderstrike

Targets net8.0 and netstandard2.0. Native libraries for linux-x64, linux-arm64 (glibc 2.17 or newer) and win-x64. macOS comes in a later release.

Quick start

The server speaks TLS 1.3 only. The client needs the CA certificate that issued the server's certificate (docker/tls/ca.crt in the server's kit) and a DNS name that certificate carries (localhost unless the server was set up with other THUNDERSTRIKE_TLS_NAMES).

using System;
using System.IO;
using Thunderstrike;

using var db = new ThunderstrikeClient(new ThunderstrikeOptions
{
    Endpoints = { "127.0.0.1:7380" },
    TlsServerName = "localhost",
    TlsCaPem = File.ReadAllBytes("ca.crt"),
});

db.SetString("user:1", "ada");
Console.WriteLine(db.GetString("user:1"));   // ada
Console.WriteLine(db.GetString("nope") is null); // True: a miss is null

Give it one address. The client asks that server for the cluster layout and connects to every core (core c listens on port 7380 + c), so those ports must be reachable too. The constructor returns only once every connection, TLS included, is up, so a wrong address or a certificate that does not verify throws there rather than on first use.

TlsServerName is sent as SNI and checked against the certificate, so it is the name the certificate was issued for, not necessarily the host you dial. There is no way to turn verification off.

Operations

Keys and values are byte[]; the *String variants take and return UTF-8 text. A key is at most 65,535 bytes; an empty value is refused. Keys do not expire: a value stays until it is deleted or overwritten.

byte[] k = "k"u8.ToArray();

db.Set(k, "v"u8.ToArray());
byte[]? v = db.Get(k);                   // null on a miss
bool there = db.Exists(k);
ulong len = db.Append(k, "-more"u8.ToArray()); // appends (creates if absent); returns the new length
bool deleted = db.Delete(k);             // false if it was not there
db.Ping();

// Read into your own buffer, no allocation:
var buf = new byte[4096];
if (db.TryGetInto(k, buf, out int n)) { /* buf[..n] */ }

Batches

For more than one key, use the batch calls. They put every request on the wire before waiting for any answer, so n keys cost one round trip instead of n.

byte[][] keys = { "a"u8.ToArray(), "b"u8.ToArray(), "missing"u8.ToArray() };

db.SetMany(new[] { keys[0], keys[1] }, new[] { "1"u8.ToArray(), "2"u8.ToArray() });
db.SetMany(new Dictionary<string, string> { ["c"] = "3" }); // UTF-8 text pairs
byte[]?[] values = db.GetMany(keys);     // [ "1", "2", null ]
bool[] gone = db.DeleteMany(keys);       // [ true, true, false ]

Async

GetAsync, GetStringAsync, SetAsync and DeleteAsync hand the request to the native runtime and complete when the answer arrives, so no thread-pool thread is held while waiting. Prefer them in ASP.NET Core.

await db.SetAsync(k, "v"u8.ToArray());
byte[]? v2 = await db.GetAsync(k, cancellationToken);
bool removed = await db.DeleteAsync(k);

One ThunderstrikeClient per process is the intended shape: it is a connection pool, and every member but Dispose is thread-safe.

Errors and retries

Every failure throws ThunderstrikeException (or a subclass) with:

  • Code: the numeric status, one of the ThunderstrikeCode constants.
  • RetryClass: whether sending the request again is sound.
  • IsBusy: the server answered Busy.
  • Message: includes the specific cause when there is one (e.g. the TLS reason).
RetryClass meaning
ThunderstrikeCode.RetryAlways Busy: the server did not apply it. Retry anything after a short backoff.
ThunderstrikeCode.RetryIfIdempotent A lost connection or a timeout: the outcome is unknown. Repeat Get, Set, Exists and Ping only.
ThunderstrikeCode.RetryNever Everything else.

The client has already retried Busy answers (every operation but Delete) and dropped connections (idempotent operations) before it throws.

Subclasses: ThunderstrikeBusyException, ThunderstrikeTimeoutException, ThunderstrikeDisconnectedException, ThunderstrikeClosedException, ThunderstrikeKeyNotFoundException.

try
{
    db.Set(k, v);
}
catch (ThunderstrikeException e) when (e.RetryClass == ThunderstrikeCode.RetryAlways)
{
    // not applied; safe to try again later
}

Configuration

ThunderstrikeOptions properties, all optional except an endpoint and (against the real server) the TLS pair:

property meaning
Endpoints / AddEndpoint(...) Bootstrap addresses. One is enough.
TlsServerName, TlsCaPem TLS 1.3: the certificate's name and the CA (PEM bytes). Set both.
TlsClientCertPem, TlsClientKeyPem Client certificate (mTLS), for a server that requires one.
RequestTimeout Per-request deadline, covering retries. Default 60 s; TimeSpan.Zero disables it.
ConnectTimeout Connect and TLS handshake deadline.
ConnectionsPerEndpoint TCP connections per server core.
MaxInflight Pipeline depth per connection.
MaxRetries Retries for an idempotent request whose connection dropped.
BusyRetries, BusyBackoffMin, BusyBackoffMax, BusyRetryWindow Busy retry policy. Defaults 4, 2 ms, 200 ms, 5 s.
MaxResponseBytes Largest response the client will accept.
TcpKeepalive, TcpNoDelay Socket options.

db.GetStats() returns pool counters (connections, requests, bytes, reconnects). db.Endpoints is the number of server cores connected, db.Shards the number of shards. ThunderstrikeClient.Version is the client's version.

To load a different build of the native library, set THUNDERSTRIKE_CLIENT_LIB to its path.

License

Proprietary, free to use: see the LICENSE file in the package. You may build this library into your own applications and ship it as part of them.

Copyright (c) 2026 SHORTSQUEEZE PRIVATE LIMITED.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.3 106 10/29/2026
0.1.2 100 10/28/2026
0.1.1 101 10/28/2026