Dekaf 1.3.0
Prefix ReservedSee the version list below for details.
dotnet add package Dekaf --version 1.3.0
NuGet\Install-Package Dekaf -Version 1.3.0
<PackageReference Include="Dekaf" Version="1.3.0" />
<PackageVersion Include="Dekaf" Version="1.3.0" />
<PackageReference Include="Dekaf" />
paket add Dekaf --version 1.3.0
#r "nuget: Dekaf, 1.3.0"
#:package Dekaf@1.3.0
#addin nuget:?package=Dekaf&version=1.3.0
#tool nuget:?package=Dekaf&version=1.3.0
Dekaf - A .NET Kafka Client
Taking the Java out of Kafka.
Dekaf is a high-performance, pure C# Apache Kafka client for .NET 10+. No JVM, no interop, no native dependencies - just clean, modern C# all the way down.
Why Dekaf?
Unlike libraries that wrap librdkafka, Dekaf is a native .NET implementation with no external dependencies:
- Pure C# - No native dependencies, no interop overhead
- Zero-allocation hot paths - Uses
Span<T>,ref struct, and object pooling for minimal GC pressure - Modern .NET - Built for .NET 10+ with nullable reference types,
IAsyncEnumerable, and all the good stuff - Native AOT compatible - Trim-safe and Native AOT ready, verified by CI smoke tests on every build
- Simple API - Intuitive fluent builders that do what you'd expect
Getting Started
dotnet add package Dekaf
Producing Messages
The simplest way to send a message:
using Dekaf;
await using var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.BuildAsync();
// Wait for acknowledgment
var metadata = await producer.ProduceAsync("my-topic", "key", "Hello, Kafka!");
Console.WriteLine($"Sent to partition {metadata.Partition} at offset {metadata.Offset}");
For high-throughput scenarios where you don't need to wait:
// Fire and forget - returns immediately
producer.Produce("my-topic", "key", "value");
// Make sure everything's delivered before shutting down
await producer.FlushAsync();
Topic-Specific Producers
When you're always producing to the same topic, use a topic producer for a cleaner API:
await using var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.BuildForTopicAsync("orders");
// No topic parameter needed
await producer.ProduceAsync("order-123", orderJson);
producer.Produce("order-456", orderJson);
You can also create multiple topic producers that share the same connection:
await using var baseProducer = Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.Build();
var orders = baseProducer.ForTopic("orders");
var events = baseProducer.ForTopic("events");
await orders.ProduceAsync("order-1", orderJson);
await events.ProduceAsync("event-1", eventJson);
Consuming Messages
using Dekaf;
await using var consumer = await Kafka.CreateConsumer<string, string>()
.WithBootstrapServers("localhost:9092")
.WithGroupId("my-consumer-group")
.SubscribeTo("my-topic")
.BuildAsync();
await foreach (var message in consumer.ConsumeAsync(cancellationToken))
{
Console.WriteLine($"Got: {message.Key} = {message.Value}");
}
Configuration Presets
Not sure which settings to use? We've got you covered with presets for common scenarios:
using Dekaf;
// Maximize throughput (batching, compression, relaxed durability)
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.ForHighThroughput()
.BuildAsync();
// Minimize latency (no batching delay, smaller batches)
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.ForLowLatency()
.BuildAsync();
// Maximum reliability (all replicas must ack, idempotent)
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.ForReliability()
.BuildAsync();
You can override individual settings after applying a preset.
Batch Production
Need to send a bunch of messages? ProduceAllAsync handles the tricky ValueTask semantics for you:
var messages = new[]
{
new ProducerMessage<string, string> { Topic = "orders", Key = "order-1", Value = orderJson1 },
new ProducerMessage<string, string> { Topic = "orders", Key = "order-2", Value = orderJson2 },
new ProducerMessage<string, string> { Topic = "orders", Key = "order-3", Value = orderJson3 },
};
var results = await producer.ProduceAllAsync(messages);
Or if all your messages go to the same topic:
var results = await producer.ProduceAllAsync("orders", new[]
{
("order-1", orderJson1),
("order-2", orderJson2),
("order-3", orderJson3),
});
Working with Headers
Headers are great for metadata like correlation IDs, trace context, or routing hints:
using Dekaf;
var headers = Headers.Create()
.Add("correlation-id", correlationId)
.Add("source", "order-service")
.AddIfNotNull("user-id", userId) // Only adds if not null
.AddIf(isRetry, "retry-count", "1"); // Only adds if condition is true
await producer.ProduceAsync("orders", orderId, orderJson, headers);
Consumer LINQ Extensions
Process consumed messages with familiar LINQ-style operations:
// Filter and limit
await foreach (var message in consumer.ConsumeAsync(ct)
.Where(m => m.Value.Contains("important"))
.Take(100))
{
await ProcessAsync(message);
}
// Batch processing - great for bulk database inserts
await foreach (var batch in consumer.ConsumeAsync(ct).Batch(100))
{
await BulkInsertAsync(batch);
await consumer.CommitAsync();
}
// Simple processing loop
await consumer.ForEachAsync(async msg =>
{
await HandleMessageAsync(msg);
}, cancellationToken);
Offset Management
Dekaf gives you control over when offsets are committed:
using Dekaf;
// Auto mode (default): Offsets committed automatically in the background
// Good for: Log processing, analytics, cases where losing a message is OK
var consumer = await Kafka.CreateConsumer<string, string>()
.WithBootstrapServers("localhost:9092")
.WithGroupId("my-group")
.WithOffsetCommitMode(OffsetCommitMode.Auto)
.BuildAsync();
// Manual mode: You control when to commit by calling CommitAsync()
// Dekaf tracks consumed offsets for you - CommitAsync() commits the latest
// consumed position for each partition. This gives you at-least-once semantics:
// if your app crashes before committing, messages will be redelivered on restart.
// Good for: Payment processing, order handling, anything where you can't lose messages
var consumer = await Kafka.CreateConsumer<string, string>()
.WithBootstrapServers("localhost:9092")
.WithGroupId("my-group")
.WithOffsetCommitMode(OffsetCommitMode.Manual)
.BuildAsync();
await foreach (var msg in consumer.ConsumeAsync(ct))
{
await ProcessAsync(msg);
await consumer.CommitAsync(); // Commits offset for all consumed messages
}
Compression
Dekaf supports all standard Kafka compression codecs. Just add the relevant package:
dotnet add package Dekaf.Compression.Lz4 # Fast, good compression
dotnet add package Dekaf.Compression.Zstd # Best compression ratio
dotnet add package Dekaf.Compression.Snappy # Balanced
Then enable it:
using Dekaf;
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("localhost:9092")
.UseLz4Compression()
.BuildAsync();
Serialization
Built-in serializers handle common types automatically:
stringbyte[]andReadOnlyMemory<byte>int,long,Guid
For JSON, add the serialization package:
dotnet add package Dekaf.Serialization.Json
using Dekaf;
var producer = await Kafka.CreateProducer<string, Order>()
.WithBootstrapServers("localhost:9092")
.WithValueSerializer(new JsonSerializer<Order>())
.BuildAsync();
await producer.ProduceAsync("orders", order.Id, order);
Security
TLS
using Dekaf;
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("kafka.example.com:9093")
.UseTls()
.BuildAsync();
SASL Authentication
using Dekaf;
// SASL/PLAIN
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("kafka.example.com:9093")
.UseTls()
.WithSaslPlain("username", "password")
.BuildAsync();
// SASL/SCRAM-SHA-512
var producer = await Kafka.CreateProducer<string, string>()
.WithBootstrapServers("kafka.example.com:9093")
.UseTls()
.WithSaslScramSha512("username", "password")
.BuildAsync();
Dependency Injection
For ASP.NET Core or other DI scenarios:
dotnet add package Dekaf.Extensions.DependencyInjection
using Dekaf.Extensions.DependencyInjection;
services.AddDekaf(dekaf =>
{
dekaf.AddProducer<string, string>(producer => producer
.WithBootstrapServers(configuration["Kafka:BootstrapServers"]!)
.WithLinger(TimeSpan.FromMilliseconds(5))
.ForReliability());
dekaf.AddConsumer<string, string>(consumer => consumer
.WithBootstrapServers(configuration["Kafka:BootstrapServers"]!)
.WithGroupId("my-service")
.WithFetchMinBytes(1024));
});
Then inject IKafkaProducer<string, string> or IKafkaConsumer<string, string> wherever you need them.
The DI callbacks use the same ProducerBuilder and ConsumerBuilder types as Kafka.CreateProducer() and Kafka.CreateConsumer(), so advanced options, SASL/TLS, retry policies, presets, interceptors, and compression extension methods are available there too.
Global Interceptors
Register cross-cutting interceptors (tracing, metrics, audit logging) that apply to all producers or consumers:
services.AddDekaf(dekaf =>
{
// Global interceptors apply to every producer/consumer
dekaf.AddGlobalProducerInterceptor(typeof(TracingInterceptor<,>));
dekaf.AddGlobalConsumerInterceptor(typeof(MetricsInterceptor<,>));
dekaf.AddProducer<string, string>(producer => producer
.WithBootstrapServers("localhost:9092")
.WithLinger(TimeSpan.FromMilliseconds(5)));
dekaf.AddConsumer<string, string>(consumer => consumer
.WithBootstrapServers("localhost:9092")
.WithGroupId("my-service")
.WithPrefetchPipelineDepth(4));
});
Global interceptors execute before per-instance interceptors, in registration order. They are constructed via ActivatorUtilities, so their dependencies are resolved from the DI container.
| 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 was computed. 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 is compatible. 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
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- System.IO.Hashing (>= 10.0.9)
- System.IO.Pipelines (>= 10.0.9)
- System.Text.Json (>= 10.0.9)
- System.Threading.Channels (>= 10.0.9)
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- System.IO.Hashing (>= 10.0.9)
NuGet packages (16)
Showing the top 5 NuGet packages that depend on Dekaf:
| Package | Downloads |
|---|---|
|
Dekaf.SchemaRegistry
Confluent Schema Registry integration for Dekaf Kafka client |
|
|
Dekaf.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection integration for Dekaf Kafka client |
|
|
Dekaf.Compression.Zstd
Zstd compression codec for Dekaf Kafka client |
|
|
Dekaf.Extensions.Hosting
Microsoft.Extensions.Hosting integration for Dekaf Kafka client |
|
|
Dekaf.SchemaRegistry.Protobuf
Protocol Buffers serialization with Schema Registry integration for Dekaf Kafka client |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.13.0 | 1,767 | 8/19/2026 |
| 1.12.0 | 1,810 | 8/15/2026 |
| 1.11.2 | 4,281 | 8/5/2026 |
| 1.11.1 | 365 | 8/5/2026 |
| 1.11.0 | 393 | 7/30/2026 |
| 1.10.0 | 370 | 7/28/2026 |
| 1.9.1 | 407 | 7/24/2026 |
| 1.9.0 | 390 | 7/22/2026 |
| 1.8.0 | 376 | 7/19/2026 |
| 1.7.0 | 8,967 | 7/18/2026 |
| 1.6.0 | 346 | 7/17/2026 |
| 1.5.1 | 350 | 7/17/2026 |
| 1.5.0 | 365 | 7/17/2026 |
| 1.4.0 | 357 | 7/15/2026 |
| 1.3.0 | 360 | 7/13/2026 |
| 1.2.0 | 3,627 | 7/7/2026 |
| 1.1.2501 | 241 | 7/6/2026 |
| 1.0.2498 | 251 | 7/6/2026 |
| 1.0.0 | 291 | 7/4/2026 |
| 0.0.1-ci.2289 | 119 | 7/4/2026 |