Skip to content
CAI
Software that uses CAICheck a score

fsprojects/pulsar-client-dotnet

54.0

Adequate · 24 September 2026

14.4k

lines of production code

F#

with C#

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a .NET client library for Apache Pulsar, providing core messaging capabilities including publishing, consuming, and reading messages across topics. It supports advanced features such as schema-validated serialization, message encryption, transactional integrity, and distributed tracing via OpenTelemetry. The library also handles secure authentication through OAuth2 and TLS, ensuring robust connectivity and reliability for distributed systems.

How it got here

2019 — Initial .NET client architecture and API release

10 changes.

This period established the foundational architecture for the Pulsar .NET client, introducing the core public API surface, internal communication infrastructure, and protocol buffer definitions. The work included restructuring the repository to support .NET 8 and .NET 10, adding OpenTelemetry and Avro support, and creating comprehensive C\# and F\# example suites to demonstrate client capabilities.

2020–2021 — Core feature expansion

5 changes.

This period focused on implementing foundational capabilities for the Pulsar client, including comprehensive schema serialization, message encryption, and transaction support. It also introduced distributed tracing via OpenTelemetry interceptors and added OAuth2 authentication to enhance security and observability.

Features

Add OAuth2 authentication support with optional scope parameter

Users can now authenticate to Pulsar using the OAuth2 client credentials flow. The new \AuthenticationOauth2\ implementation retrieves tokens from an OAuth issuer, supports loading credentials from local files or base64-encoded data URIs, and includes an optional \scope\ parameter in the token request to align with the Java client version.

src/Pulsar.Client/Auth/Oauth2 · high confidence

Initial C\# example suite with authentication, schema, and telemetry demos

The C\# examples project now includes a comprehensive set of runnable demonstrations for the Pulsar client. Users can explore basic messaging (Simple.cs), custom message properties (CustomProps.cs), and a realistic production pattern with logging and cancellation (RealWorld.cs). The suite also covers advanced capabilities: schema-validated JSON serialization (Schema.cs), transactional messaging across topics (Transaction.cs), OpenTelemetry tracing via interceptors (Telemetry.cs), TLS mutual authentication (TlsAuthentication.cs), and OAuth2 client-credentials authentication (Oauth2.cs). A new entry point (Program.cs) allows toggling these examples, and a runtime config template (runtimeconfig.template.json) optimizes GC settings for performance.

examples/CsharpExamples · high confidence

Initial release of the Pulsar .NET client API surface

This change introduces the complete public API for the Pulsar .NET client library, defining the core interfaces and configuration models for interacting with Apache Pulsar. It establishes the foundational types for producers (IProducer), consumers (IConsumer), and readers (IReader), along with their respective builders (ConsumerBuilder, ProducerBuilder) and configuration records (ConsumerConfiguration, ProducerConfiguration). The diff adds support for advanced messaging features including dead-letter processing (DeadLetterPolicy, IDeadLetterProcessor), message encryption and decryption (IMessageEncryptor, IMessageDecryptor), schema handling (ISchema), and interceptors (IConsumerInterceptor, IProducerInterceptor). It also introduces authentication mechanisms (Authentication, AuthenticationFactory, AuthenticationFactoryOAuth2) and cluster failover strategies (AutoClusterFailover, ControlledClusterFailover) to ensure robust connectivity and reliability.

src/Pulsar.Client/Api · high confidence

Introduces core client infrastructure and data models

This change adds the foundational Common module for the Pulsar .NET client, introducing essential data transfer objects and utilities. It defines the Message and MessageId types, including support for batched and chunked messages, and establishes the command serialization logic for network communication. Additionally, it provides parsing for Service URIs and Topic names, along with helper modules for logging, retries, and type-safe measurements (UMX) required for the client's internal operations.

src/Pulsar.Client/Common · high confidence

Introduces transaction support for Pulsar clients

Adds a new transaction subsystem to the Pulsar client, enabling atomic publish and acknowledge operations across topics and subscriptions. This change introduces the \TransactionCoordinatorClient\ to manage transaction lifecycle and state, a \TransactionBuilder\ for configuring and creating transactions, and the core \Transaction\ class which handles commit and abort logic, including automatic abortion on timeout and proper cleanup of cumulative ack permits.

src/Pulsar.Client/Transaction · high confidence

Introduction of comprehensive schema serialization support

The Pulsar client now includes a full suite of schema implementations in the \src/Pulsar.Client/Schema\ directory, enabling structured data handling for Pulsar topics. This update adds support for primitive types (Boolean, Byte, Int, Long, Short, Float, Double, String, Bytes, Date, Time, Timestamp), complex formats (Avro, JSON, Protobuf, Protobuf Native), and composite structures (KeyValue). It also introduces auto-consume and auto-produce schema stubs for flexible schema negotiation, along with a multi-version schema info provider to handle schema evolution and caching.

src/Pulsar.Client/Schema · high confidence

New F\# client examples and runtime configuration

The examples/FsharpExamples directory now includes a comprehensive set of F\# demonstration projects covering core messaging, advanced features, and security. Users can explore basic producer/consumer patterns (Simple.fs), custom message properties (CustomProps.fs), schema-based serialization with JSON (Schema.fs), and transactional messaging across topics (Transaction.fs). Additional examples demonstrate the Reader API for scanning topics (Reader.fs), robust error handling and cancellation in real-world scenarios (RealWorld.fs), and OpenTelemetry integration for distributed tracing (Telemetry.fs). Security features are illustrated through TLS authentication (TlsAuthentication.fs) and OAuth2 client credentials flow (Oauth2.fs). A runtimeconfig.template.json is also added to configure the .NET runtime for server GC and heap settings.

examples/FsharpExamples · high confidence

New message encryption and decryption implementation

The client now supports encrypting and decrypting Pulsar messages using AES-256-GCM for payload encryption and RSA-OAEP-SHA1 for wrapping the symmetric key. This change introduces a new \ICryptoKeyReader\ interface to abstract key store access, allowing users to provide custom logic for retrieving public and private keys. The \MessageEncryptor\ generates a random symmetric key for each message and encrypts it with the specified public keys, while the \MessageDecryptor\ handles decryption with caching to optimize performance when multiple messages are encrypted with the same key.

src/Pulsar.Client/Crypto · high confidence

OpenTelemetry tracing for Pulsar producer and consumer interceptors

Added OpenTelemetry integration for Pulsar messaging via new \OTelProducerInterceptor\ and \OtelConsumerInterceptor\ components. The producer interceptor now creates trace activities for message sends, injecting trace context into message properties for distributed tracing and caching activities to record success or error status upon acknowledgement. The consumer interceptor extracts upstream trace context from incoming messages, creates receive activities, and manages activity lifecycles (including cumulative acknowledgements, timeouts, and negative acknowledgements) through a background task processing a command channel, ensuring proper span closure and error tagging.

src/Pulsar.Client.Otel · high confidence

Architecture

Repository restructured with .NET 10 SDK and new support packages

The project has been reorganized into a new solution structure featuring the main \Pulsar.Client\ library alongside new support packages \Pulsar.Client.Proto\ (for C\# protocol buffer support) and \Pulsar.Client.Otel\ (for OpenTelemetry integration). The repository now targets .NET 8 for the main library but requires the .NET 10 SDK for building, as enforced by the new \global.json\. This change also introduces a comprehensive architecture document, updated CI workflows, and a detailed contributing guide.

(repo-wide) · high confidence

Behavioural changes

Internal client architecture refactored with new F\# modules

The internal client implementation has been significantly restructured and expanded with new F\# modules to improve reliability and feature support. Key additions include \AcknowledgmentsGroupingTracker\ for managing batch and cumulative message acknowledgments, \Backoff\ for configurable retry delays, and \BatchMessageAcker\ and \BatchMessageContainer\ for handling message batching logic. The \BinaryLookupService\ now handles topic metadata and broker lookups with retry logic, while \ChunkedMessageTracker\ manages the assembly of large chunked messages. \ClientCnx\ centralizes connection state and request handling, and \Compression\ supports ZLib, LZ4, Snappy, and Zstd codecs. \ConnectionHandler\ manages connection lifecycle and reconnection states. These changes represent a major internal overhaul of the client's core communication and message processing logic.

src/Pulsar.Client/Internal · high confidence

Updated Pulsar protocol definitions and added CRC32C and MurmurHash3 utilities

The Pulsar.Client.Proto library has been updated with new protocol buffer definitions (PulsarApi.proto) and their corresponding C\# generated code (Generated.cs), reflecting changes in the Pulsar message format such as transaction support and chunked messages. Additionally, the project now includes a new CRC32C implementation (Crc32c.cs) using .NET intrinsics for performance, a MurmurHash3 utility (MurmurHash3.cs) for partitioning, and a DynamicJsonConverter for handling JSON schema data.

src/Pulsar.Client.Proto · high confidence

Test coverage

Added Avro code generation and integration tests for Pulsar client; Internal visibility configuration for test assemblies.

Dependencies

Upgrade to .NET 10 and update core dependencies

The project has been upgraded to target .NET 10 (net10.0) for example and test projects, while the core libraries (Pulsar.Client, Pulsar.Client.Otel, Pulsar.Client.Proto) target .NET 8. This change includes updating the main client library to version 3.19.3 and the OpenTelemetry plugin to 1.1.0. Key dependency updates include Microsoft.Extensions.Logging and related packages to version 10.0.x, OpenTelemetry packages to 1.15.3, and protobuf-net to 3.2.30. The examples now reference Pulsar.Client 3.16.0, reflecting the current stable release for consumers.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 53 → 54 (+1.5)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 66 → 66 (-0.1)
  • Architecture 98 → 99 (+0.1)
  • Maturity 60 → 60 (-0.4)
  • Readiness 41 → 39 (-2.0)
  • Security 58 → 82 (+23.5)

Resolved (20)

  • BarePragmaDisable (examples/CsharpExamples/RealWorld.cs)
  • Change coupling: ClientCnx.fs ↔ ConsumerImpl.fs (src/Pulsar.Client/Internal/ClientCnx.fs)
  • Change coupling: ClientCnx.fs ↔ TransactionMetaStoreHandler.fs (src/Pulsar.Client/Internal/ClientCnx.fs)
  • Change coupling: ConsumerBuilder.fs ↔ ConsumerImpl.fs (src/Pulsar.Client/Api/ConsumerBuilder.fs)
  • Change coupling: ConsumerImpl.fs ↔ PartitionedProducerImpl.fs (src/Pulsar.Client/Internal/ConsumerImpl.fs)
  • Change coupling: DeadLetters.fs ↔ ConsumerImpl.fs (src/Pulsar.Client/Api/DeadLetters.fs)
  • Change coupling: IProducer.fs ↔ ConsumerImpl.fs (src/Pulsar.Client/Api/IProducer.fs)
  • Duplicated block (13 lines × 2) (examples/CsharpExamples/Simple.cs)
  • Duplicated block (14 lines × 2) (examples/CsharpExamples/CustomProps.cs)
  • Duplicated block (8 lines × 3) (examples/CsharpExamples/Oauth2.cs)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • Test reliability not included
  • The README links to an external examples folder (https://github.com/fsharplang-ru/pulsar-client-dotnet/tree/develop/examples) but does not mention how to build or run the examples locally. (README.md)
  • complexity unreadable for .fs — churn × complexity hotspots could not be measured
  • redundant comment (src/Pulsar.Client.Proto/DynamicJsonConverter.cs)

New (29)

  • Change coupling: IConsumer.fs ↔ IProducer.fs (src/Pulsar.Client/Api/IConsumer.fs)
  • Change-coupling hub: ClientCnx.fs → ConnectionHandler.fs, ProducerImpl.fs, TransactionMetaStoreHandler.fs (src/Pulsar.Client/Internal/ClientCnx.fs)
  • Change-coupling hub: ConsumerImpl.fs → ConsumerBuilder.fs, DeadLetters.fs, IProducer.fs, ClientCnx.fs, PartitionedProducerImpl.fs (src/Pulsar.Client/Internal/ConsumerImpl.fs)
  • Documentation: no contributor guidance (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (11 lines × 3) (examples/CsharpExamples/Oauth2.cs)
  • Duplicated block (17 lines × 2) (examples/CsharpExamples/CustomProps.cs)
  • Duplicated block (17 lines × 2) (examples/CsharpExamples/Simple.cs)
  • FileScopedPragmaDisable (examples/CsharpExamples/RealWorld.cs)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Inconsistent casing in generated Reset methods: 'connectedSince' and 'unackedMessages' use camelCase for the property name suffix, whereas other Reset methods in the same namespace (e.g., ResetMaxMessageSize, ResetNumMessages) use PascalCase (e.g., MaxMessageSize, NumMessages). This suggests a deviation from the standard PascalCase convention for property names in this codebase.
  • Inconsistent casing in property names within CommandConsumerStatsResponse: 'msgRateRedeliver' uses camelCase, while other properties like 'RequestId' use PascalCase. Additionally, the Reset methods for these camelCase properties ('ResetconnectedSince', 'ResetunackedMessages') also use camelCase suffixes, whereas standard Reset methods use PascalCase suffixes.
  • Inconsistent casing in property names within CommandSubscribe: 'keySharedMeta' uses camelCase, while 'StartMessageId' and 'InitialPosition' use PascalCase. This breaks the consistent PascalCase naming convention observed in the rest of the proto-generated types.
  • Inconsistent casing in property names: 'keySharedMeta' in CommandSubscribe uses camelCase, while 'hashRanges' in KeySharedMeta also uses camelCase. However, other properties in the codebase (e.g., 'RequestId', 'ProducerName') use PascalCase. This suggests a systemic inconsistency in the generated code where some properties are camelCase and others are PascalCase.
  • Inconsistent naming in Reset method: 'Resetauth_data' uses an underscore and camelCase for the suffix, whereas other Reset methods like 'ResetProducerName' and 'ResetProtocolVersion' use PascalCase without underscores. This indicates a deviation from the standard PascalCase naming convention for generated Reset methods.
  • …and 9 more

Changes since last survey

  • 5 commits — 2 feature/other, 3 fixes

By area

  • src/Pulsar.Client — 5 commits

Notable commits

  • fix: Fix BatchReceiveAsync never delivering a message larger than MaxNumBytes (#368)
  • fix: Fix producer sequence ordering for delayed messages and key-based batches (#367)
  • fix: Fixed flacky test and added release comment
  • change: Close the consumer at the broker when its mailbox fails (#369)
  • change: Support reader schemas and schema-bound auto-produce (#366)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

fsprojects/pulsar-client-dotnet was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 24 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 483fd76c3a48641bedb370baaf6763318ac3ef03 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.