Skip to content

Announcing the TerraScale C# SDK: First-Class .NET Support

Today we’re releasing the official TerraScale C# SDK. It’s been in beta for three months and I’m genuinely proud of how it turned out.

When we started building SDKs, we had to pick a language to start with. JavaScript would have been the obvious choice - it’s everywhere. But we looked at our early users and noticed something interesting: a disproportionate number were .NET shops.

The Venn diagram of “developers who want a DynamoDB-like experience” and “developers building with C#” has a lot of overlap. Many developers are migrating from Azure Cosmos DB or building high-performance backends where C# shines.

So C# it was.

Terminal window
dotnet add package TerraScale.Client

That’s it. No native dependencies, no complex setup. Works on .NET 6, 7, and 8.

using TerraScale;
var client = new TerraScaleDatabase(new TerraScaleDatabaseOptions
{
ApiKey = Environment.GetEnvironmentVariable("TERRASCALE_API_KEY"),
DatabaseId = "my-database"
});
// Write an item
await client.PutItemAsync("user#123", "profile", new Dictionary<string, object>
{
["name"] = "Mario",
["email"] = "mariogk@terrascale.tech",
["createdAt"] = DateTime.UtcNow
});
// Read it back
var result = await client.GetItemAsync("user#123", "profile");
if (result.IsSuccess)
{
var name = result.Value.GetAttribute<string>("name");
Console.WriteLine($"Hello, {name}!");
}

Raw dictionaries are fine for prototyping, but production code deserves better:

public record User : EntityBase
{
public required string Name { get; init; }
public required string Email { get; init; }
public DateTime? LastLoginAt { get; init; }
}
var users = client.GetRepository<User>("users");
var user = new User
{
Id = "user-123",
Name = "Mario",
Email = "mariogk@terrascale.tech"
};
await users.CreateAsync(user);
var retrieved = await users.GetByIdAsync("user-123");
Console.WriteLine(retrieved.Value.Name); // Mario

Every SDK operation returns a Result<T> type. No exceptions for expected failures:

var result = await client.GetItemAsync("user#123", "profile");
var message = result switch
{
{ IsSuccess: true } => $"Found: {result.Value.PartitionKey}",
{ IsFailed: true } => $"Error: {result.Errors.First().Message}",
_ => "Unknown state"
};

Transient failures are handled automatically:

var client = new TerraScaleDatabase(new TerraScaleDatabaseOptions
{
ApiKey = "...",
DatabaseId = "...",
Retry = new RetryPolicyOptions
{
MaxRetries = 3,
BaseDelay = TimeSpan.FromMilliseconds(100),
MaxDelay = TimeSpan.FromSeconds(5),
UseJitter = true
}
});
OperationThroughputMemory
PutItem (1KB)15,000/sec~2KB/op
GetItem25,000/sec~1KB/op
Query (100 items)800/sec~50KB/op
Batch (25 items)2,000/sec~20KB/op
  • LINQ provider - Query with Where, Select, Take
  • Change tracking - Automatic dirty detection
  • Interceptors - Hook into the request pipeline
  • AOT support - Full Native AOT compatibility

The SDK documentation has everything you need. But honestly, just install the package and start coding.

Terminal window
dotnet add package TerraScale.Client

If you run into issues, reach out at mariogk@terrascale.tech.

Happy coding!