CascadeFlow is a real-time telemetry and visualization platform for NServiceBus-based distributed systems. It captures message flows across microservices, aggregates them into correlated flows, and provides a web-based UI for observing system behavior.
- Message Flow Tracking: Automatically captures incoming and outgoing messages from NServiceBus endpoints, correlating them into end-to-end flows
- System Topology Discovery: Builds a live topology map showing how your services communicate
- Impact Analysis: Analyzes message propagation to identify high-impact endpoints and message types
- Real-time Dashboard: Displays metrics including message throughput, slowest handlers, and failure rates
- Zero-config Integration: Drop-in NServiceBus plugin that requires minimal configuration
┌────────────────────────┐ ┌────────────────────────┐
│ NServiceBus │ │ NServiceBus │
│ Endpoint A │ │ Endpoint B │
│ + Cascade.NServiceBus | │ + Cascade.NServiceBus |
└─────────┬──────────────┘ └──────┬─────────────────┘
│ HTTP POST │ HTTP POST
│ /api/telemetry │ /api/telemetry
▼ ▼
┌─────────────────────────────────┐
│ Cascade.Collector │
│ (ASP.NET Core + SQL Server) │
└─────────────┬───────────────────┘
│ SignalR
▼
┌─────────────────────────────────┐
│ Cascade.Web │
│ (React + TypeScript) │
└─────────────────────────────────┘
The easiest way to run the Cascade Collector is with Docker Compose:
docker compose upThis starts both the Collector and SQL Server. The collector will be available at http://localhost:5100.
To run just the collector (if you have your own SQL Server):
docker build -t cascade-collector .
docker run -p 5100:8080 -e ConnectionStrings__CascadeDb="Server=host.docker.internal;Database=CascadeCollector;..." cascade-collectorPrerequisites:
- .NET 10.0 SDK
- SQL Server (LocalDB or SQL Server Express)
- Node.js 18+
# Start the collector API (database migrations run automatically)
dotnet run --project src/Cascade.CollectorThe collector will be available at http://localhost:5100.
cd src/Cascade.Web
npm install
npm run devThe web UI will be available at http://localhost:5173.
Choose the package that matches your environment:
| Package | Target Framework | NServiceBus Version |
|---|---|---|
CascadeFlow.NServiceBus |
.NET 10+ | 9.x |
CascadeFlow.NServiceBus.Framework |
.NET Framework 4.7.2+ | 8.x |
# For .NET 10+ with NServiceBus 9.x
dotnet add package CascadeFlow.NServiceBus
# For .NET Framework 4.7.2+ with NServiceBus 8.x
dotnet add package CascadeFlow.NServiceBus.FrameworkThat's it! The package automatically registers telemetry behaviors via INeedInitialization. No code changes required.
var endpointConfiguration = new EndpointConfiguration("MyEndpoint");
endpointConfiguration.UseCascade(options =>
{
options.CollectorUrl = "http://localhost:5100";
});Or use environment variables for zero-code configuration:
CASCADE_COLLECTOR_URL: URL of the Cascade collectorCASCADE_ENDPOINT_NAME: Override the endpoint name (defaults to NServiceBus endpoint name)
| Project | Description |
|---|---|
Cascade.Core |
Shared domain models and enums |
Cascade.Collector |
ASP.NET Core API and SignalR hub for receiving and serving telemetry |
Cascade.NServiceBus |
NServiceBus 9.x plugin for .NET 10+ |
Cascade.NServiceBus.Framework |
NServiceBus 8.x plugin for .NET Framework 4.7.2+ |
Cascade.Web |
React-based visualization dashboard |
Cascade.Sample.* |
Sample microservices demonstrating integration |
The Collector supports optional API key authentication to secure the telemetry ingestion endpoint.
Set the environment variable on the Collector:
Cascade__RequireApiKey=true- Open the Cascade web UI and navigate to Settings
- Click Create Key and provide a name (and optional endpoint restriction)
- Copy the generated key - it's only shown once
Set the API key via environment variable (recommended):
CASCADE_API_KEY=csk_your-api-key-hereOr configure explicitly:
endpointConfiguration.UseCascade(options =>
{
options.ApiKey = "csk_your-api-key-here";
});services:
collector:
image: ghcr.io/erik-mostert/cascade-collector:main
environment:
- Cascade__RequireApiKey=true
ports:
- "5100:8080"
my-service:
environment:
- CASCADE_COLLECTOR_URL=http://collector:8080
- CASCADE_API_KEY=csk_your-api-key-hereThe API key management endpoints (/api/keys) can be protected with an admin key. This prevents unauthorized users from creating, revoking, or deleting API keys.
Set the environment variable on the Collector:
Cascade__AdminKey=your-secret-admin-keyWhen configured:
- The Settings page in the web UI will prompt for the admin key
- All
/api/keysendpoints require theX-Admin-Keyheader - The admin key is stored in session storage and sent with API key management requests
| Configuration | Behavior |
|---|---|
| No admin key set | API key management is unrestricted (development mode) |
| Admin key set | Requires X-Admin-Key header with matching value |
services:
collector:
image: ghcr.io/erik-mostert/cascade-collector:main
environment:
- Cascade__RequireApiKey=true
- Cascade__AdminKey=your-secret-admin-key
ports:
- "5100:8080"By default, the Collector allows requests from any origin (suitable for private network deployments). To restrict CORS to specific origins:
# Single origin
Cors__AllowedOrigins__0=https://myapp.example.com
# Multiple origins
Cors__AllowedOrigins__0=https://myapp.example.com
Cors__AllowedOrigins__1=https://admin.example.comRate limiting is disabled by default. Enable it to protect the API from abuse.
RateLimiting__Enabled=true| Tier | Endpoints | Default Limit | Partition |
|---|---|---|---|
| Telemetry | /api/telemetry |
10,000 req/min | Per API Key |
| Analytics | /api/dashboard/*, /api/impact/* |
500 req/min | Per IP |
| Standard | /api/flows/*, /api/topology |
2,000 req/min | Per IP |
| Management | /api/keys/*, /api/topology/reset |
50 req/min | Per IP |
RateLimiting__Telemetry__PermitLimit=20000
RateLimiting__Analytics__PermitLimit=1000
RateLimiting__Standard__PermitLimit=5000
RateLimiting__Management__PermitLimit=100services:
collector:
image: ghcr.io/erik-mostert/cascade-collector:main
environment:
- RateLimiting__Enabled=true
- RateLimiting__Telemetry__PermitLimit=50000
ports:
- "5100:8080"The NServiceBus integration is designed to never impact your services:
- Telemetry dispatch is asynchronous and non-blocking
- If the collector is unavailable, telemetry is silently dropped
- No exceptions propagate to message handlers
- Bounded buffer prevents memory buildup