Thunderstrike 0.1.3
dotnet add package Thunderstrike --version 0.1.3
NuGet\Install-Package Thunderstrike -Version 0.1.3
<PackageReference Include="Thunderstrike" Version="0.1.3" />
<PackageVersion Include="Thunderstrike" Version="0.1.3" />
<PackageReference Include="Thunderstrike" />
paket add Thunderstrike --version 0.1.3
#r "nuget: Thunderstrike, 0.1.3"
#:package Thunderstrike@0.1.3
#addin nuget:?package=Thunderstrike&version=0.1.3
#tool nuget:?package=Thunderstrike&version=0.1.3
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 theThunderstrikeCodeconstants.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.
Links
- Source and issues: https://github.com/TheManhattanProject/thunderstrike-client
- Server image: https://hub.docker.com/r/sbansal793/thunderstrike
- Clients for other languages: see the repository README.
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 | Versions 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. |
-
.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.