Skip to content
CAI
Software that uses CAICheck a score

ThreeDotsLabs/watermill

68.9

Adequate · 21 September 2026

14.4k

lines of production code

Go

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Watermill is a Go library for building event-driven architectures, providing a unified interface for publishing and subscribing to messages across various backends like Kafka, RabbitMQ, and SQL databases. It offers a comprehensive set of components for handling complex messaging patterns, including CQRS, exactly-once delivery, delayed retries, and cross-system forwarding. The system emphasizes reliability and observability through built-in middleware for circuit breaking, throttling, and Prometheus metrics, alongside extensive examples demonstrating real-world implementations.

How it got here

2018–2019 — v1.0.0 release and middleware expansion

34 changes.

The project reached version 1.0.0 with a stable API, renaming from GooDDD to Watermill and introducing comprehensive router middleware for resilience and observability. Legacy event store and in-memory Pub/Sub implementations were removed to streamline the architecture, while new features like bulk reading and message transformation decorators were added. The period also saw the introduction of the mill CLI tool and extensive updates to examples, including CQRS refactoring and real-world integration patterns.

2020–2025 — Component expansion and example library

19 changes.

This period focused on extending the library's core capabilities by introducing new components for message routing, request/reply patterns, and delayed processing. Concurrently, the project significantly expanded its example library to demonstrate these features alongside various Pub/Sub backends and real-world architectural patterns.

Features

Add AWS SQS pub/sub example with LocalStack support

A new example demonstrating how to use Watermill with AWS SQS is now available in the \_examples/pubsubs/aws-sqs directory. The example includes a Go application that publishes and subscribes to messages using the AWS SDK for Go v2, configured to connect to a LocalStack instance for local development. A docker-compose.yml file is provided to spin up the necessary LocalStack services (SQS and SNS), and a validation script ensures the example runs correctly by checking for expected output.

_\_examples/pubsubs/aws-sns, \examples/pubsubs/aws-sqs · high confidence

Add Redis Streams pub/sub example

A new example demonstrating how to use Redis Streams for message publishing and subscribing has been added to the pub/sub examples. The entry includes a Go application that connects to a Redis instance via Docker Compose, publishing messages to 'example.topic' and processing them in a consumer group, along with validation scripts to verify the setup.

_\examples/pubsubs/redisstream · high confidence

Add SQL pub/sub example with Docker validation

The SQL pub/sub example now includes a Docker Compose setup (MySQL 8.0 and a Go 1.25 server) and a validation script to automatically verify the example runs correctly. The example code itself has been updated to use watermill-sql v4, demonstrating how to publish and subscribe to messages using MySQL as the backing store.

_\examples/pubsubs/sql · high confidence

Add Server-Sent Events example application

Introduces a new example application in the server-sent-events directory that demonstrates real-time feed updates using Server-Sent Events (SSE). The server uses Watermill with NATS Streaming for message routing, MySQL for post storage, and MongoDB for feed storage, exposing HTTP endpoints that stream live updates to Vue.js-based frontend clients.

_\examples/real-world-examples/server-sent-events/server · high confidence

Add Server-Sent Events example with polyglot persistence

Introduces a new real-world example demonstrating HTTP Server-Sent Events (SSE) for real-time updates. The example showcases a polyglot persistence pattern where writes go to MySQL (Write Model) and asynchronous event handlers update a MongoDB Read Model via NATS. It includes a Vue.js frontend using EventSource, a Go backend, and a Docker Compose setup to run the full stack locally.

_\examples/real-world-examples/server-sent-events · high confidence

Add examples for delayed message processing and requeuing

New real-world examples demonstrate how to implement delayed message delivery and automatic requeuing on failure. The delayed-messages example shows how to use the SQL delayed publisher with Redis streams to defer commands (such as sending a feedback form) after a specific duration. The delayed-requeue example illustrates using the PostgreSQL delayed requeuer middleware to automatically retry failed events with exponential backoff.

_\_examples/real-world-examples/delayed-messages, \examples/real-world-examples/delayed-requeue · high confidence

Add metrics monitoring example with Prometheus and Grafana

The basic/4-metrics example now includes a complete setup for monitoring Watermill applications. It introduces a Go application that exposes Prometheus metrics on port 8081, a docker-compose configuration to run the app alongside Prometheus and Grafana, and documentation explaining how to visualize the metrics. Users can now run this example to see how router, publisher, and subscriber statistics are collected and displayed in a Grafana dashboard.

_\examples/basic/4-metrics · high confidence

Added Kafka pub/sub example with Redpanda and validation

A new Kafka example has been added to the pub/sub examples directory, demonstrating a Go application using Watermill and Sarama to publish and subscribe to messages. The example is containerized via a new docker-compose.yml file that runs the Go application against a Redpanda (Kafka-compatible) service, and includes a .validate\_example.yml configuration to automatically verify the example by running the container and checking for the expected output.

_\examples/pubsubs/kafka · high confidence

Added NATS Streaming pub/sub example with Docker validation

A new example demonstrating NATS Streaming integration has been added to the pub/sub examples. It includes a Go application that publishes and subscribes to messages using the Watermill library with NATS Streaming, along with a Docker Compose configuration to run the example locally. A validation script is also provided to automatically verify the example's functionality by running the Docker containers and checking for expected output.

_\examples/pubsubs/nats-streaming · high confidence

Added SQLite pub/sub examples with ModernC and ZombieZen drivers

New example code has been added to the \\_examples/pubsubs/sqlite\ directory demonstrating Watermill pub/sub patterns using SQLite. The examples cover two distinct SQLite driver implementations: \wmsqlitemodernc\ (using \modernc.org/sqlite\) and \wmsqlitezombiezen\ (using \zombiezen.com/go/sqlite\). Each example includes a basic \main.go\ showing publisher and subscriber setup, along with a \transaction.go\ file illustrating how to publish messages within a database transaction. Validation scripts are also included to ensure the examples run correctly.

_\examples/pubsubs/sqlite · high confidence

Added a script to consolidate multiple Go modules into a single file

A new Go utility script has been added to the \dev/consolidate-gomods\ directory. This tool scans the repository for all \go.mod\ files, merges their dependency declarations into a single 'big fat' \go.mod\ output, and removes the original individual module files. This consolidation is intended to simplify the project structure for the GolangCI linter.

dev/consolidate-gomods · high confidence

Added bulk message reading with optional deduplication

The subscriber package now provides \BulkRead\ and \BulkReadWithDeduplication\ functions, allowing consumers to retrieve multiple messages from a channel in a single operation up to a specified limit or timeout. \BulkRead\ collects messages until the limit is reached, a timeout occurs, or the channel closes, while \BulkReadWithDeduplication\ additionally filters out duplicate messages based on their UUIDs before returning them.

message/subscriber · high confidence

Added development tooling for test coverage and Prometheus monitoring

Developers now have a new shell script (dev/coverage.sh) to generate Go test coverage statistics, including support for HTML reports and pushing data to Coveralls.io. Additionally, a Prometheus configuration file (dev/prometheus.yml) has been added to facilitate local development monitoring by scraping metrics from localhost:8080.

dev · high confidence

Added exactly-once delivery counter example using Watermill SQL v4

A new example demonstrating exactly-once message delivery has been added to the examples directory, featuring a Go-based server and worker. The server exposes an HTTP endpoint to publish counter increment messages, while the worker consumes these messages and updates a MySQL database. This implementation utilizes the watermill-sql/v4 package, configuring both a publisher and a subscriber with MySQL schema and offset adapters to ensure that database updates are committed atomically with message acknowledgment, preventing duplicate processing or data loss.

_\examples/real-world-examples/exactly-once-delivery-counter/worker · high confidence

Added internal text indentation utility

A new internal helper function, Indent, has been added to the tools/mill/cmd/internal package. This utility allows command-line output to be formatted with consistent line prefixes, which will be used to improve the readability of structured text responses in the CLI.

tools/mill/cmd/internal · high confidence

Added internal utilities for channel state inspection and struct naming

This change introduces new internal helper functions: \IsChannelClosed\ in \internal/channel.go\ allows safe detection of closed channels without blocking, and \StructName\ in \internal/name.go\ provides normalized struct names by leveraging the \fmt.Stringer\ interface when available. Additionally, build-tagged files (\internal/race.go\ and \internal/norace.go\) expose a \RaceEnabled\ constant to conditionally enable race detection logic based on the Go race detector build tag.

internal · high confidence

Added multiplier subscriber for increased throughput

A new multiplier subscriber decorator has been added to the internal subscriber package. This component allows users to instantiate multiple underlying subscribers concurrently to increase message processing throughput. It manages the lifecycle of these subscribers, aggregating their message streams into a single channel and handling errors during subscription and closure.

internal/subscriber · high confidence

Added realtime feed producer example using Watermill Kafka v3

The basic realtime feed producer example has been updated to use the watermill-kafka v3 package. The example demonstrates publishing synthetic post events to a Kafka topic using multiple concurrent workers, correlation ID middleware, and graceful shutdown handling via signal interrupts.

_\examples/basic/2-realtime-feed/producer · high confidence

Automated dependency and Go version update tool for examples

A new internal utility script has been added to automatically update Go versions and dependencies across all example projects. The tool fetches the latest Go version, updates the Go version in Docker Compose files, upgrades the Watermill library to the latest release, and updates all other Go module dependencies, ensuring the examples remain consistent and up-to-date.

dev/update-examples-deps · high confidence

Delayed message support and PostgreSQL poison-queue management tool

Users can now delay message delivery using a new \components/delay\ package, which provides a publisher wrapper to inject delay metadata (via context or default generators) and helper functions to set delay times on messages. Additionally, a new CLI tool \tools/pq\ has been added to manage delayed messages on PostgreSQL poison queues, allowing users to inspect, requeue, or acknowledge messages directly from the database.

components/delay, tools/pq · high confidence

GoChannel Pub/Sub implementation with FanOut support and context preservation

The in-process GoChannel Pub/Sub now supports preserving request context across message boundaries via the new PreserveContext configuration option, ensuring that context values attached to published messages are available to subscribers. Additionally, a new FanOut component has been introduced, allowing a single external subscription to be distributed to multiple internal workers within the same process. The implementation also includes improved resource management, automatically cleaning up subscriber data and locks when topics no longer have active subscribers, and moves internal synchronization utilities to a public pubsub/sync package.

pubsub/gochannel · high confidence

Introduce Prometheus metrics collection for publishers, subscribers, and handlers

The metrics component now provides built-in instrumentation for Watermill message routing, exposing standard Prometheus metrics for publish latency, handler execution time, and subscriber message reception. Users can easily integrate this by using the PrometheusMetricsBuilder to decorate publishers and subscribers or by applying the router middleware, with support for custom histogram buckets and additional dynamic labels. The component also includes a convenience HTTP server helper to expose these metrics at a /metrics endpoint for scraping.

components/metrics · high confidence

Introduce message transformation decorators and router context propagation

The message package now includes \MessageTransformSubscriberDecorator\ and \MessageTransformPublisherDecorator\, allowing users to apply custom transformations to messages as they pass through subscribers and publishers. Additionally, the router now injects contextual information—such as handler name, subscriber/publisher names, and topics—into the message context, accessible via new helper functions like \HandlerNameFromCtx\ and \SubscribeTopicFromCtx\, enabling better tracing and debugging of message flows.

message · high confidence

Introduce mill CLI for AMQP, Kafka, and Google Cloud Pub/Sub

The mill command-line tool is introduced to allow users to consume and produce messages via the AMQP, Kafka, and Google Cloud Pub/Sub providers. This update adds specific subcommands for each provider (e.g., \mill amqp consume\, \mill kafka produce\, \mill googlecloud subscription ls\) that utilize the watermill-io \io.Writer\ and \io.Reader\ interfaces to read from or write to standard input and output, respectively. Users can now manage subscriptions directly for Google Cloud Pub/Sub and configure connection details such as URIs, topics, and consumer groups through CLI flags.

tools/mill/cmd · high confidence

Introduce mill CLI tool for Watermill pub/sub operations

Added the 'mill' CLI tool, a command-line interface for the Watermill library that enables users to produce and consume messages across supported pub/sub systems including Kafka, Google Cloud Pub/Sub, and RabbitMQ. The tool supports standard consume and produce modes via stdin/stdout, and includes specific management commands for Google Cloud Pub/Sub, such as listing, adding, and removing subscriptions. A default configuration file (.default-config.yml) is provided to help users set up connection parameters for these providers.

tools/mill · high confidence

New CQRS example demonstrating ordered event processing with Kafka

Added a new example application (\_examples/basic/6-cqrs-ordered-events) that implements a CQRS email subscription system using Watermill and Kafka. This example specifically demonstrates how to maintain event ordering using event groups and Kafka partitioning keys, ensuring that subscription state changes (subscribe, unsubscribe, update) are processed in the correct sequence. It includes a subscriber read model and an activity timeline read model, along with the necessary Protobuf definitions and Docker Compose configuration to run the service.

_\examples/basic/6-cqrs-ordered-events · high confidence

New CQRS example using Protobuf and AMQP v3

Added a new example demonstrating a CQRS application that uses Protocol Buffers for message serialization and the AMQP v3 publisher/subscriber for transport. The example includes a Docker Compose setup with Go 1.25 and RabbitMQ 3.7, a Makefile for generating Protobuf code, and validation scripts to ensure the application runs correctly.

_\examples/basic/5-cqrs-protobuf · high confidence

New FanIn component for multiplexing messages from multiple topics

A new FanIn component is introduced to multiplex messages from one or more source topics onto a single target topic. It manages an internal message router that subscribes to the configured source topics and publishes all received messages to the specified target topic, allowing users to consolidate message streams into a single downstream channel.

components/fanin · high confidence

New Forwarder component for cross-PubSub message routing

A new Forwarder component has been added to enable routing messages between different Pub/Sub implementations (e.g., from MySQL to Google Pub/Sub). The component consists of a \Publisher\ that wraps outgoing messages in a JSON envelope containing the destination topic, and a \Forwarder\ service that consumes these enveloped messages and publishes them to the specified destination. The implementation supports custom marshalers for serialization, configurable handler names to allow multiple forwarders on a single router, and an option to acknowledge messages that fail to unwrap.

components/forwarder · high confidence

New Requeuer component for delayed message retry

A new Requeuer component has been added to the library, allowing users to automatically requeue messages to a different topic after a configurable delay. This is useful for handling transient failures by waiting before retrying, with built-in support for tracking retry counts in message metadata. The component integrates with the existing message router and subscriber/publisher interfaces.

components/requeuer · high confidence

New Server-Sent Events example with htmx and Watermill

This location introduces a complete example application demonstrating live website updates using Go, Server-Sent Events (SSE), and htmx. The example features a web interface built with the templ template engine and Bootstrap, allowing users to view posts and interact with reactions. It implements an event-driven architecture using the Watermill library and Google Cloud Pub/Sub (with a local emulator for development) to handle events like post views and reaction updates. The application runs via Docker Compose, including services for the Go server, PostgreSQL, and the Pub/Sub emulator, and includes a validation script to ensure the example starts correctly.

_\examples/real-world-examples/server-sent-events-htmx · high confidence

New basic router example with middleware and validation

Added a new example in \_examples/basic/3-router demonstrating a Watermill router setup that includes router-level middleware (CorrelationID, Retry, Recoverer) and handler-level middleware, along with a validation script (.validate\_example.yml) to ensure the example runs correctly and produces expected output.

_\examples/basic/3-router · high confidence

New exactly-once delivery counter example

Added a new example demonstrating exactly-once message delivery using MySQL and the watermill-sql Pub/Sub implementation. The example includes a server and worker that update a database counter within the same transaction as message consumption, ensuring consistency even during failures. It also provides a validation script and Docker Compose configuration to run and test the scenario.

_\examples/real-world-examples/exactly-once-delivery-counter · high confidence

New example demonstrating transactional event publishing with the Forwarder component

Added a new example in \_examples/real-world-examples/transactional-events-forwarder that illustrates how to persist application state and publish messages within a single database transaction using the Forwarder component. The example compares three approaches—publishing before persisting, persisting before publishing, and using a transactional forwarder—and highlights the risks of inconsistency in the first two methods. It includes a Docker Compose setup with MySQL and a Google Cloud Pub/Sub emulator, along with validation scripts to ensure the example runs correctly and produces the expected output.

_\examples/real-world-examples/transactional-events-forwarder · high confidence

New example for synchronizing MySQL and PostgreSQL databases

Added a new example demonstrating how to synchronize data between MySQL and PostgreSQL using Watermill's SQL Pub/Sub. The example includes a Go application that subscribes to changes in a MySQL database and publishes them to a PostgreSQL database, along with Docker Compose configuration to run the services and a validation script to verify the synchronization.

_\examples/real-world-examples/synchronizing-databases · high confidence

New example validation tool for automated verification

A new Go-based validation tool has been added to the \dev/validate-examples\ directory to automatically verify that example applications behave as expected. The tool scans example directories for \.validate\example\.yml\ configuration files, executes the specified validation commands, and checks the output against expected patterns or strings within a configurable timeout. This enables automated regression testing for the examples by ensuring their runtime output matches the documented behavior.

dev/validate-examples · high confidence

New examples for persistent event logs and transactional events

Added two new real-world examples demonstrating how to use the SQL Pub/Sub components with Watermill. The 'Persistent Event Log' example shows how to use an SQL publisher to store events from Google Cloud Pub/Sub into MySQL for auditability. The 'Transactional Events' example demonstrates how to publish domain events to Kafka while persisting them to MySQL in the same database transaction, ensuring consistency between the aggregate state and the event stream.

_\examples/real-world-examples/transactional-events · high confidence

New interactive Consumer Groups example with Redis Streams and CQRS

Adds a new interactive example demonstrating how to use Consumer Groups to route events to specific handlers in a distributed system. The example includes a web UI, an API service, and separate newsletter and CRM services, all communicating via Redis Streams. It illustrates various patterns, including basic event handling, scaling services with replicas, and using the CQRS component to manage event processors and consumer groups for fine-grained message routing.

_\examples/real-world-examples/consumer-groups · high confidence

New realtime feed consumer example with advanced middleware

Added a new consumer example for the realtime feed that demonstrates using the watermill-kafka v3 library. The example implements a feed generator handler using AddConsumerHandler and includes a comprehensive middleware chain: Recoverer, Throttle (10 msg/sec), PoisonQueue, Retry (1 attempt), CorrelationID, and random failure/panic simulators. It processes posts\_published messages to update a feed and publishes count updates to posts\_count.

_\examples/basic/2-realtime-feed/consumer · high confidence

New router middleware components for resilience, reliability, and observability

This update introduces a comprehensive suite of new middleware components for the message router, enabling robust message processing patterns. Key additions include CircuitBreaker for preventing cascading failures, Deduplicator for ensuring exactly-once processing semantics, and PoisonQueue to salvage unprocessable messages for later analysis. Operational reliability is enhanced with Retry (featuring exponential backoff and an OnRetriesExhausted hook), Throttle for rate limiting, and Timeout for context-based deadline enforcement. Additional utilities include CorrelationID for distributed tracing, InstantAck for high-throughput scenarios, DelayOnError for exponential backoff retries, IgnoreErrors for filtering specific error types, Recoverer for panic handling, and Duplicator for idempotency testing.

message/router/middleware · high confidence

New webhook integration examples for sending and receiving messages

Added two new real-world examples demonstrating bidirectional webhook patterns using Watermill. The 'sending-webhooks' example shows how to consume Kafka messages and dispatch HTTP POST requests to a webhook server, routing events to different endpoints based on metadata. The 'receiving-webhooks' example demonstrates an HTTP subscriber that accepts incoming webhook POSTs and publishes them to a Kafka topic. Both examples are fully containerized with Docker Compose, using Redpanda as the Kafka broker and Go 1.25 for the application services.

_\examples/real-world-examples/sending-webhooks · high confidence

Request/Reply pattern support for commands

The \components/requestreply\ package now provides a request/reply pattern implementation for commands, allowing callers to send a command and wait for a structured result or error from the handler. This includes \SendWithReply\ and \SendWithReplies\ functions to initiate requests, \NewCommandHandler\ and \NewCommandHandlerWithResult\ to register handlers that can return results, and a \PubSubBackend\ that uses Pub/Sub to transport commands and replies. The backend supports configuration for reply timeouts, error handling (including \AckCommandErrors\ and \ReplyPublishErrorHandler\), and custom message modification.

components/requestreply · high confidence

RetryPublisher decorator for message publishing

The internal publisher package now includes a RetryPublisher that wraps an existing message publisher to automatically retry failed message sends. This decorator uses an exponential backoff strategy, starting with a configurable initial wait time and doubling the delay for each subsequent attempt, up to a specified maximum number of retries. If all retry attempts fail, it returns a composite error detailing the specific failure reason for each message, ensuring that successful messages are not resent during retries.

internal/publisher · high confidence

Removals

Removal of SQL and PubSub event store implementations

The SQL-based event store (sql.go), its database schema (sql\_schemq.sql), and the PubSub-based event store (pubsub.go) have been removed from the domain/eventstore package. This eliminates the previous implementations that persisted events to a SQL database or published them via a PubSub mechanism, effectively stripping out these storage and messaging backends from the event store layer.

domain/eventstore · high confidence

Removal of legacy in-memory Pub/Sub implementation

The legacy in-memory Pub/Sub implementation (gochannel) and its associated core interfaces, message structures, and tests have been removed from the pubsub package. This cleanup eliminates the internal go-channel based broker, the generic Message and PubSub interface definitions, and the corresponding unit tests, effectively removing this specific infrastructure component from the codebase.

pubsub · high confidence

Removal of the enterprise-aggregate-with-events example

The entire \enterprise-aggregate-with-events\ example application has been removed from the repository. This deletion eliminates the previous implementation of an event-sourced shop domain (including cart, order, and delivery aggregates) and its associated infrastructure, such as the in-memory repository and stub delivery services. Users relying on this specific example for guidance on event sourcing patterns will no longer have access to this codebase.

_\examples/enterprise-aggregate-with-events · high confidence

Behavioural changes

AMQP example now uses Watermill v3 and Docker for local validation

The AMQP pub/sub example has been updated to use the watermill-amqp/v3 library, requiring users to interact with the v3 API surface. To simplify local testing, the example now includes a docker-compose.yml file that spins up a RabbitMQ 3.7 container and a Go 1.25 server, along with a .validate\_example.yml configuration that automates the validation process by running the Docker services and checking for the expected output.

_\examples/pubsubs/amqp · high confidence

CQRS component refactored with new public API and handler groups

The CQRS component has been restructured to replace the legacy \Facade\ with a modular public API consisting of \CommandBus\, \EventBus\, \CommandProcessor\, and \EventProcessor\. This change introduces \CommandBusConfig\ and \EventBusConfig\ for flexible configuration, including \OnSend\ and \OnPublish\ hooks for message modification, and adds support for \EventHandler\ groups via \EventGroupProcessor\ to allow multiple handlers for the same event type. The new API also enforces stricter validation, context propagation, and thread-safe handler execution, while the old \Facade\ and related constructors are marked as deprecated.

components/cqrs · high confidence

NATS Jetstream example now uses JetStream with auto-provisioning

The NATS Jetstream example has been updated to enable JetStream functionality by setting \JetStream.Disabled\ to false and enabling \AutoProvision\. This allows the example to automatically create the necessary JetStream streams and consumers on the NATS server, simplifying setup for users who want to test persistent messaging features without manual configuration.

_\examples/pubsubs/nats-jetstream · high confidence

Removal of legacy domain event and event bus infrastructure

The legacy domain event structures and associated infrastructure have been removed from the codebase. Specifically, the \Event\ struct, \EventPayload\ interface, and the \NewEvent\ constructor in \domain/event.go\ are deleted, along with the \EventProducer\ and its test in \domain/eventsbus.go\ and \domain/eventsbus\_test.go\. Additionally, the \Eventstore\ interface defined in \domain/eventstore.go\ has been removed. This cleanup eliminates the previous implementation of event recording, storage, and conversion to message payloads, aligning with the broader refactoring to separate message and event concepts.

domain · high confidence

Updated 'Your First App' example to use Watermill Kafka v3 and Redpanda

The 'Your First App' example has been updated to use the watermill-kafka v3 library, changing the import path from v2 to v3 in main.go. The Docker Compose configuration now uses the Redpanda container image (redpandadata/redpanda:v26.1.7) instead of the previous Kafka/Zookeeper setup, and the Go base image is updated to golang:1.26. The example code itself has been modernized to use the v3 API, including explicit configuration of the Kafka publisher and subscriber with a consumer group, and utilizes the 'mill' CLI tool for topic inspection in the documentation.

_\examples/basic/1-your-first-app · high confidence

Watermill v1.0.0: Stable API and Logging Enhancements

Watermill reaches v1.0.0 with a stable public API, introducing a new \SlogLoggerAdapter\ for Go's standard \log/slog\ package alongside the existing \StdLoggerAdapter\. This release also adds utility functions for generating UUIDs, ShortUUIDs, and ULIDs, and includes a \CaptureLoggerAdapter\ to facilitate testing. The project has been renamed from 'GooDDD' to 'Watermill', and the core \LoggerAdapter\ interface now requires a \With\ method for field injection. Additionally, the \message.PubSub\ interface and related constructors have been removed, and the \Router.Run\ method now requires a context.

(repo-wide) · high confidence

Test coverage

Added comprehensive test suite and benchmarking utilities for Pub/Sub implementations

The \pubsub/tests\ package now includes a universal test suite (\TestPubSub\) that validates Pub/Sub implementations against various features such as consumer groups, exactly-once delivery, guaranteed order, and context preservation. It also provides helper functions for assertions (\test\_asserts.go\) and a benchmarking utility (\bench\_pubsub.go\) to measure subscriber performance, along with stress test configurations (\test\_pubsub\_stress.go\).

pubsub/tests · 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

Score

  • CAI 66 → 69 (+3.0)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 92 → 98 (+6.0)
  • Architecture 100 → 97 (-2.9)
  • Maturity 72 → 74 (+2.1)
  • Readiness 47 → 53 (+6.0)
  • Security 84 → 79 (-4.2)
  • Event-Driven 100 → 100 (+0.0)
  • Event Sourcing 100 → 100 (+0.0)

Resolved (39)

  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (tools/mill/go.mod)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (10 lines × 2) (_examples/real-world-examples/persistent-event-log/main.go)
  • Duplicated block (10 lines × 2) (dev/update-examples-deps/main.go)
  • Duplicated block (11 lines × 2) (_examples/real-world-examples/consumer-groups/crm-service/main.go)
  • Duplicated block (12 lines × 2) (components/cqrs/event_processor.go)
  • Duplicated block (13 lines × 2) (_examples/real-world-examples/delayed-messages/main.go)
  • Duplicated block (13 lines × 2) (components/cqrs/command_processor.go)
  • Duplicated block (14 lines × 2) (components/cqrs/command_processor.go)
  • Duplicated block (14 lines × 3) (_examples/real-world-examples/consumer-groups/newsletter-service/main.go)
  • Duplicated block (15 lines × 2) (_examples/real-world-examples/exactly-once-delivery-counter/server/main.go)
  • Duplicated block (15 lines × 3) (_examples/pubsubs/sql/main.go)
  • Duplicated block (16 lines × 2) (_examples/pubsubs/nats-core/main.go)
  • Duplicated block (16 lines × 2) (_examples/real-world-examples/delayed-messages/main.go)
  • Duplicated block (16 lines × 4) (_examples/real-world-examples/consumer-groups/crm-service/main.go)
  • Duplicated block (17 lines × 7) (_examples/real-world-examples/consumer-groups/newsletter-service/main.go)
  • Duplicated block (18 lines × 2) (_examples/real-world-examples/consumer-groups/crm-service/main.go)
  • Duplicated block (9 lines × 2) (_examples/pubsubs/nats-core/main.go)
  • Duplicated block (9 lines × 2) (_examples/real-world-examples/server-sent-events/server/http.go)
  • …and 19 more

New (183)

  • Critical CVE: [GHSA redacted] (tools/mill/go.mod)
  • Critical CVE: [GHSA redacted] (tools/mill/go.mod)
  • Deprecated module: cloud.google.com/go/pubsub
  • Deprecated module: github.com/golang/protobuf
  • Deprecated module: go.mongodb.org/mongo-driver
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (docs/content/support.md)
  • Documentation: no usage examples (README.md)
  • Documentation: written for insiders
  • Duplicated block (10 lines × 2) (dev/update-examples-deps/main.go)
  • Duplicated block (10 lines × 3) (components/cqrs/command_processor.go)
  • Duplicated block (10 lines × 3) (components/cqrs/command_processor.go)
  • Duplicated block (11 lines × 2) (_examples/pubsubs/aws-sns/main.go)
  • Duplicated block (11 lines × 2) (_examples/pubsubs/sql/main.go)
  • Duplicated block (11 lines × 2) (_examples/real-world-examples/persistent-event-log/main.go)
  • Duplicated block (11 lines × 2) (components/cqrs/event_processor.go)
  • Duplicated block (11 lines × 6) (_examples/pubsubs/amqp/main.go)
  • Duplicated block (12 lines × 2) (components/cqrs/command_bus.go)
  • Duplicated block (15 lines × 2) (_examples/real-world-examples/delayed-messages/main.go)
  • Duplicated block (15 lines × 2) (components/cqrs/command_processor.go)
  • …and 163 more

Changes since last survey

  • 2 commits — 2 feature/other, 0 fixes

By area

  • _examples/pubsubs — 1 commit
  • components/forwarder — 1 commit

Notable commits

  • change: Update nats docs (#694)
  • change: improve figure (#695)

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

Survey your own repository

ThreeDotsLabs/watermill 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 21 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 080d4b4e7fe6105ab880d1becd5cf91af0235d8c — 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-fa71c66cabd8.