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.
Why C# First?
Section titled “Why C# First?”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.
What’s In the Box
Section titled “What’s In the Box”Installation
Section titled “Installation”dotnet add package TerraScale.ClientThat’s it. No native dependencies, no complex setup. Works on .NET 6, 7, and 8.
Basic Usage
Section titled “Basic Usage”using TerraScale;
var client = new TerraScaleDatabase(new TerraScaleDatabaseOptions{ ApiKey = Environment.GetEnvironmentVariable("TERRASCALE_API_KEY"), DatabaseId = "my-database"});
// Write an itemawait client.PutItemAsync("user#123", "profile", new Dictionary<string, object>{ ["name"] = "Mario", ["email"] = "mariogk@terrascale.tech", ["createdAt"] = DateTime.UtcNow});
// Read it backvar result = await client.GetItemAsync("user#123", "profile");if (result.IsSuccess){ var name = result.Value.GetAttribute<string>("name"); Console.WriteLine($"Hello, {name}!");}The Repository Pattern
Section titled “The Repository Pattern”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); // MarioResult Types
Section titled “Result Types”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"};Retry Policies
Section titled “Retry Policies”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 }});Performance
Section titled “Performance”| Operation | Throughput | Memory |
|---|---|---|
| PutItem (1KB) | 15,000/sec | ~2KB/op |
| GetItem | 25,000/sec | ~1KB/op |
| Query (100 items) | 800/sec | ~50KB/op |
| Batch (25 items) | 2,000/sec | ~20KB/op |
What’s Coming
Section titled “What’s Coming”- LINQ provider - Query with
Where,Select,Take - Change tracking - Automatic dirty detection
- Interceptors - Hook into the request pipeline
- AOT support - Full Native AOT compatibility
Getting Started
Section titled “Getting Started”The SDK documentation has everything you need. But honestly, just install the package and start coding.
dotnet add package TerraScale.ClientIf you run into issues, reach out at mariogk@terrascale.tech.
Happy coding!