Configuration Reference
All configuration in Emit is validated at startup via IValidateOptions<T>. Misconfiguration surfaces as a startup error, not a runtime surprise.
Outbox options
Section titled “Outbox options”Applies to both MongoDB and EF Core when UseOutbox() is called on the persistence provider. These options control the background worker that delivers outbox entries to the broker. All producers route through the outbox by default when outbox infrastructure is configured; use topic.Producer(p => p.UseDirect()) to opt out.
| Option | Default | Range | Description |
|---|---|---|---|
PollingInterval | 5s | min 1s | Idle wait between poll cycles. When a full batch is fetched and fully delivered, the next poll starts immediately to drain the backlog without waiting. |
BatchSize | 100 | 1-10000 | Max entries fetched per cycle, ordered by sequence (FIFO). |
MaxConcurrentGroups | 32 | min 1 | Max entry groups delivered in parallel within a cycle. Groups are delivered concurrently up to this limit; entries within a group stay sequential. |
Kafka client options
Section titled “Kafka client options”ConfigureClient maps directly to Confluent.Kafka's ClientConfig. All standard Confluent.Kafka client properties are available. Common ones:
| Option | Description |
|---|---|
BootstrapServers | (required) Comma-separated broker addresses |
ClientId | Client identifier reported to the broker |
SecurityProtocol | Plaintext, Ssl, SaslPlaintext, or SaslSsl |
SaslMechanism | Plain, ScramSha256, ScramSha512, or Gssapi |
SaslUsername / SaslPassword | SASL credentials |
SslCaLocation | Path to the CA certificate file |
Producer routing options
Section titled “Producer routing options”| Method | Description |
|---|---|
UseDirect() | Forces the producer to send directly to the broker, bypassing the outbox. Only meaningful when outbox infrastructure is configured. |
Kafka producer options
Section titled “Kafka producer options”ConfigureProducer maps to Confluent.Kafka's ProducerConfig. Common options:
| Option | Default | Description |
|---|---|---|
Acks | Leader | Acknowledgement level: None, Leader, or All |
EnableIdempotence | false | Prevents duplicate messages on retry |
CompressionType | None | Gzip, Snappy, Lz4, or Zstd |
Linger | 0 | Batching delay before sending |
Consumer and handler options
Section titled “Consumer and handler options”| Attribute | Description |
|---|---|
[Transactional] | Applied to a consumer or mediator handler class. The pipeline wraps the handler invocation in a unit of work; the transaction commits on success and rolls back on failure. |
Kafka consumer group options
Section titled “Kafka consumer group options”Emit-specific options:
| Option | Default | Description |
|---|---|---|
WorkerCount | 1 | Number of parallel workers |
WorkerDistribution | ByKeyHash | ByKeyHash or RoundRobin |
BufferSize | 32 | Per-worker channel capacity |
CommitInterval | 5s | Offset commit frequency |
WorkerStopTimeout | 30s | Graceful shutdown wait for in-flight messages |
Confluent consumer options (also settable on the group):
| Option | Description |
|---|---|
AutoOffsetReset | Where to start when no committed offset exists: Earliest or Latest |
SessionTimeout | Broker marks the consumer dead after this period without a heartbeat |
HeartbeatInterval | How often the consumer sends heartbeats to the broker |
MaxPollInterval | Maximum time between poll calls before the broker considers the consumer dead |
IsolationLevel | ReadUncommitted or ReadCommitted (for transactional producers) |
QueuedMaxMessagesKbytes | Maximum KB of pre-fetched messages in the local consumer queue |
QueuedMinMessages | Minimum number of messages per topic+partition librdkafka tries to maintain in the local queue |
Additional properties
Section titled “Additional properties”All options classes (KafkaClientOptions, KafkaConsumerOptions, KafkaProducerOptions) expose an AdditionalProperties dictionary for librdkafka settings not yet surfaced as typed properties. Typed properties always take precedence over entries in this dictionary. Invalid keys cause an InvalidOperationException at client build time.
kafka.ClientConfig(client =>{ client.AdditionalProperties = new Dictionary<string, string> { ["socket.nagle.disable"] = "true" };});Schema Registry options
Section titled “Schema Registry options”ConfigureSchemaRegistry maps to Confluent.Kafka's SchemaRegistryConfig. Common options:
| Option | Description |
|---|---|
Url | (required) Schema Registry URL |
BasicAuthUserInfo | Credentials in user:password format |
RequestTimeout | Per-request timeout |
MaxCachedSchemas | In-memory schema cache size |
Circuit breaker options
Section titled “Circuit breaker options”Circuit breaker configuration is covered in detail on the error policies page. The short form:
group.CircuitBreaker(cb =>{ cb.FailureThreshold(5); cb.SamplingWindow(TimeSpan.FromSeconds(60)); cb.PauseDuration(TimeSpan.FromSeconds(30)); cb.TripOn<HttpRequestException>(); // optional; default trips on any exception});Dead letter options
Section titled “Dead letter options”Dead letter configuration is covered on the error policies page. The short form:
kafka.DeadLetter("orders.dlt");
// With provisioning options:kafka.DeadLetter("orders.dlt", dlq =>{ dlq.Provisioning(options => { options.Retention = TimeSpan.FromDays(30); });});The DLQ topic participates in topic verification and auto-provisioning like any other topic.
Auto-provisioning options
Section titled “Auto-provisioning options”Call kafka.AutoProvision() to enable automatic topic creation at startup. Per-topic creation options are configured via topic.Provisioning(...). See Kafka Setup: Auto-provisioning for usage examples.
| Option | Default | Description |
|---|---|---|
NumPartitions | broker default | Number of partitions |
ReplicationFactor | broker default | Number of replicas |
Retention | 7 days | How long messages are retained (null = infinite) |
RetentionBytes | no limit | Maximum partition size before old segments are discarded |
CleanupPolicy | Delete | Delete, Compact, or DeleteAndCompact |
DeleteRetention | 1 day | Tombstone retention for compacted topics |
CompressionType | Producer | Producer, Uncompressed, Gzip, Snappy, Lz4, or Zstd |
MinCleanableDirtyRatio | 0.5 | Minimum dirty-to-total ratio before compaction |
MinCompactionLag | 0 | Minimum time before compaction |
MaxCompactionLag | none | Maximum time before compaction |
Leader election options
Section titled “Leader election options”Controls how Emit elects a leader across instances. Tuning is rarely needed except in high-latency networks or when the default lease duration is too aggressive for your failover requirements.
| Option | Default | Description |
|---|---|---|
HeartbeatInterval | 15s | How often each node attempts to renew leadership |
LeaseDuration | 60s | How long a lease lasts; another node takes over if not renewed in time |
QueryTimeout | 5s | Max time for a heartbeat database query; the node drops leadership on timeout |
NodeRegistrationTtl | 90s | How long before a silent node is considered dead and removed |
InstanceId | MachineName | Human-readable node identifier visible in leader records |
emit.ConfigureLeaderElection(le =>{ le.HeartbeatInterval = TimeSpan.FromSeconds(10); le.LeaseDuration = TimeSpan.FromSeconds(45); le.InstanceId = Environment.GetEnvironmentVariable("POD_NAME");});Daemon coordination options
Section titled “Daemon coordination options”Controls how the outbox daemon is assigned to leader nodes.
| Option | Default | Description |
|---|---|---|
AcknowledgeTimeout | 30s | How long a node has to acknowledge a daemon assignment before the leader reassigns it |
DrainTimeout | 30s | How long a node has to stop a revoked daemon before the leader force-reassigns it |
emit.ConfigureDaemons(d =>{ d.AcknowledgeTimeout = TimeSpan.FromSeconds(15); d.DrainTimeout = TimeSpan.FromSeconds(20);});Lock cleanup options
Section titled “Lock cleanup options”Applies to the EF Core persistence provider only. Controls how often expired distributed lock rows are purged from the database.
| Option | Default | Range | Description |
|---|---|---|---|
CleanupInterval | 5 minutes | min 1 minute | How often the cleanup worker runs |
Tracing options
Section titled “Tracing options”| Option | Default | Description |
|---|---|---|
Enabled | true | Master switch for all Emit trace activity |
CreateRootActivities | true | Creates a root span when no parent trace context is present |
PropagateBaggage | true | Forwards W3C baggage across message boundaries |
MaxBaggageSizeBytes | 8192 | Maximum baggage payload size in bytes (range: 1024-65536) |
OpenTelemetry instrumentation options
Section titled “OpenTelemetry instrumentation options”| Option | Default | Description |
|---|---|---|
EnableEmitMeter | true | Core pipeline instruments |
EnableOutboxMeter | true | Outbox worker instruments |
EnableLockMeter | true | Distributed lock instruments |
EnableMediatorMeter | true | Mediator instruments |
EnableKafkaMeter | true | Kafka consumer/producer instruments |
EnableKafkaBrokerMeter | true | Broker-level Kafka instruments |
Call options.EnrichWithTag("key", "value") to add a global dimension to all instruments.
Middleware lifetimes
Section titled “Middleware lifetimes”group.Use<MyMiddleware>(MiddlewareLifetime.Singleton); // default: one shared instancegroup.Use<MyMiddleware>(MiddlewareLifetime.Scoped); // one instance per messageSee Custom Middleware for registration details and lifetime semantics.
Validation on startup
Section titled “Validation on startup”All options classes implement IValidateOptions<T> and are registered with ValidateOnStart(). If a required field is missing or a value falls outside its allowed range, the application throws at startup with a descriptive error pointing to the misconfigured option. You will not discover bad configuration at 2am when a message finally exercises that code path.