Transports Overview
Overview of available messaging transports and how to choose the right one
Available Transports
Nimbus supports multiple messaging transports, each with different characteristics and use cases:
Azure Service Bus
Enterprise-grade cloud messaging service from Microsoft Azure.
- Fully managed, highly reliable
- Advanced features (scheduled messages, dead-lettering, sessions)
- Best for production cloud deployments
- Requires Azure subscription
Redis
High-performance in-memory data store with pub/sub capabilities.
- Extremely fast, low latency
- Simple setup and operation
- Great for high-throughput scenarios
- Less durability guarantees than message queues
AMQP
AMQP 1.0 transport optimized for ActiveMQ Artemis.
- Self-hosted, full control
- Open standard AMQP 1.0 protocol
- Works with any AMQP broker
- Optimized for ActiveMQ Artemis
- Good for on-premises deployments
SQL Server
Database-backed transport using your existing SQL Server instance.
- No additional broker required
- Atomic dequeue, concurrent consumers
- Scheduled delivery and dead letters
- Great for apps already on SQL Server
PostgreSQL
Database-backed transport using your existing PostgreSQL instance.
- No additional broker required
FOR UPDATE SKIP LOCKEDfor safe concurrency- Works with Supabase, Neon, RDS, Cloud SQL
- Great for apps already on PostgreSQL
In-Process
Memory-based transport for testing and development.
- No external dependencies
- Perfect for unit and integration tests
- Fast local development
- Not suitable for production
Transport Comparison
| Feature | Azure Service Bus | Redis | AMQP | SQL Server | PostgreSQL | In-Process |
|---|---|---|---|---|---|---|
| Deployment | Cloud (Azure) | Self-hosted or Cloud | Self-hosted | Existing DB | Existing DB | N/A |
| Extra infra required | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Durability | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ |
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Setup Complexity | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Cost | Pay per use | Free (self-host) | Free (self-host) | Existing DB cost | Existing DB cost | Free |
| Message delivery | Push | Push | Push | Polling | Polling | In-memory |
| Message Size | 256KB / 1MB | 512MB | 100MB+ | VARBINARY(MAX) | BYTEA | Unlimited |
Choosing a Transport
For Production
Azure Service Bus if you:
- Run on Azure cloud
- Need enterprise-grade reliability
- Want managed infrastructure
- Require advanced features (sessions, scheduled messages, transactions)
- Have budget for cloud services
var transport = new AzureServiceBusTransportConfiguration()
.WithConnectionString(azureConnectionString)
.WithDefaultTimeout(TimeSpan.FromSeconds(30))
.WithMaxConcurrentCalls(10); Redis if you:
- Need maximum performance and low latency
- Have high message throughput requirements
- Can accept slightly lower durability guarantees
- Already use Redis in your infrastructure
- Want simple, fast pub/sub
var transport = new RedisTransportConfiguration()
.WithConnectionString("localhost:6379")
.WithDatabase(0); AMQP if you:
- Run on-premises or private cloud
- Need full control over infrastructure
- Want AMQP 1.0 standard protocol
- Have existing AMQP/Artemis infrastructure
- Want open-source solutions
var transport = new AMQPTransportConfiguration()
.WithBrokerUri("amqp://localhost:5672")
.WithCredentials("admin", "admin")
.WithConnectionPoolSize(10); SQL Server if you:
- Already have SQL Server in your stack
- Want messaging without additional infrastructure
- Need strong durability backed by your existing DB
- Are running on-premises or using Azure SQL
var transport = new SqlServerTransportConfiguration()
.WithConnectionString("Server=localhost;Database=Nimbus;Integrated Security=true;")
.WithAutoCreateSchema(); PostgreSQL if you:
- Already have PostgreSQL in your stack
- Want messaging without additional infrastructure
- Use a managed PostgreSQL service (Supabase, Neon, RDS, Cloud SQL)
- Prefer PostgreSQL’s
FOR UPDATE SKIP LOCKEDconcurrency model
var transport = new PostgresTransportConfiguration()
.WithConnectionString("Host=localhost;Database=nimbus;Username=postgres;Password=secret")
.WithAutoCreateSchema(); For Development & Testing
In-Process for:
- Unit tests
- Integration tests
- Local development
- Quick prototyping
var transport = new InProcessTransportConfiguration(); Development Strategy: Use in-process transport for development and tests, then switch to your production transport by changing configuration only. Your application code remains unchanged.
Feature Support Matrix
Core Features
| Feature | Azure Service Bus | Redis | AMQP | SQL Server | PostgreSQL | In-Process |
|---|---|---|---|---|---|---|
| Commands | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Events (Competing) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Events (Multicast) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Requests | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Multicast Requests | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Advanced Features
| Feature | Azure Service Bus | Redis | AMQP | SQL Server | PostgreSQL | In-Process |
|---|---|---|---|---|---|---|
| Scheduled Delivery | ✅ Native | ⚠️ Polling | ✅ Native | ✅ visible_after | ✅ visible_after | ✅ Full support |
| Message TTL | ✅ Native | ✅ Native | ✅ Native | ✅ expires_at | ✅ expires_at | ✅ Simulated |
| Dead Letter Queue | ✅ Native | ⚠️ Manual | ✅ Native | ✅ DB table | ✅ DB table | ⚠️ Manual |
| Large Messages | ✅ Blob store | ❌ | ✅ Blob store | ❌ | ❌ | ✅ |
| Transactions | ✅ Full support | ⚠️ Limited | ✅ Full support | ❌ | ❌ | ✅ |
| Sessions | ✅ Full support | ❌ | ✅ Full support | ❌ | ❌ | ❌ |
| Duplicate Detection | ✅ Native | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual |
| Encryption at rest | ✅ Native | ⚠️ Manual | ⚠️ Manual | ✅ TDE | ✅ Native | ❌ |
Performance Characteristics
Throughput
High Throughput (10,000+ msgs/sec):
- Redis (in-memory, minimal overhead)
- In-Process (no serialization or network)
Medium-High Throughput (1,000-10,000 msgs/sec):
- Azure Service Bus (premium tier)
- AMQP brokers (with tuning)
Medium Throughput (100-1,000 msgs/sec):
- Azure Service Bus (standard tier)
- AMQP brokers (standard config)
- SQL Server / PostgreSQL (with tuned poll interval and indexing)
Latency
Ultra-Low (sub 1ms):
- In-Process
Low (1-10ms):
- Redis
Medium (10-50ms):
- Azure Service Bus
- AMQP brokers (Artemis, etc.)
Poll-interval-dependent (configurable, default ~1s):
- SQL Server
- PostgreSQL
Latency vs. Reliability Trade-off: Faster transports (Redis, In-Process) may have lower durability guarantees. Slower transports (Azure Service Bus) provide stronger reliability guarantees.
Message Size Limits
Azure Service Bus
- Standard tier: 256 KB per message
- Premium tier: 1 MB per message
- Use large message support for bigger payloads
Redis
- Theoretical limit: 512 MB
- Practical limit: ~100 MB (performance degrades)
- Recommended: < 1 MB per message
AMQP (ActiveMQ Artemis)
- Default: 100 MB (configurable)
- Broker-dependent limits
- Large message support available
SQL Server
VARBINARY(MAX): up to 2 GB per message- Practical limit: keep messages small for performance
- No external large message store support
PostgreSQL
BYTEA: no hard limit (governed by available memory)- Practical limit: keep messages small for performance
- No external large message store support
In-Process
- No practical limit (memory-based)
- Recommended: Keep messages small for consistency with other transports
Reliability and Durability
At-Least-Once Delivery
All transports support at-least-once delivery:
- Messages are acknowledged only after successful processing
- Failed messages are retried
- Handlers must be idempotent
Exactly-Once Semantics
For exactly-once processing, you need:
Application-level deduplication:
public class IdempotentPlaceOrderHandler : IHandleCommand<PlaceOrderCommand>
{
private readonly IOrderRepository _repository;
public async Task Handle(PlaceOrderCommand command)
{
// Check if order already exists (idempotency)
if (await _repository.OrderExists(command.OrderId))
{
// Already processed, skip
return;
}
await _repository.CreateOrder(command);
}
}
Azure Service Bus: Built-in duplicate detection (with sessions) Other transports: Manual deduplication required
Message Persistence
Azure Service Bus:
- All messages persisted to storage
- Survives broker restarts
- Geo-redundant storage available
Redis:
- Messages in memory by default
- Optional persistence (RDB snapshots, AOF log)
- Risk of message loss on server crash
AMQP (ActiveMQ Artemis):
- Configurable persistence (journal-based)
- Durable subscriptions available
- Survives broker restarts with proper configuration
SQL Server:
- Full ACID durability — messages stored in database tables
- Survives application restarts and server reboots
- Inherits whatever HA/DR you’ve configured for SQL Server
PostgreSQL:
- Full ACID durability — messages stored in database tables
- Survives application restarts and server reboots
- Inherits whatever HA/DR you’ve configured for PostgreSQL
In-Process:
- No persistence
- Messages lost on application restart
- For testing only
Operational Considerations
Monitoring
Azure Service Bus:
- Azure Monitor integration
- Metrics: Queue depth, throughput, errors
- Alerts and diagnostics built-in
Redis:
- Redis INFO command
- Third-party monitoring (RedisInsight, Prometheus)
- Custom metrics via application
AMQP (ActiveMQ Artemis):
- JMX monitoring
- Web console included
- Management API available
SQL Server / PostgreSQL:
- Query
nimbus_messages/NimbusMessagesfor queue depths - Query
nimbus_dead_letters/NimbusDeadLettersfor failure counts - Standard DB monitoring tools (Azure Monitor, pgAdmin, Datadog, etc.)
In-Process:
- Custom instrumentation only
- Not intended for production monitoring
Scaling
Horizontal Scaling:
- All transports support multiple consumer instances
- Messages distributed across instances
- Add/remove instances as needed
Vertical Scaling:
- Azure Service Bus: Upgrade to premium tier
- Redis: Use Redis Cluster
- AMQP: Clustering and failover
- SQL Server / PostgreSQL: Scale up the database; reduce poll interval for lower latency
- In-Process: Add more threads (limited)
High Availability
Azure Service Bus:
- Automatic failover
- Zone redundancy available
- 99.9% SLA (standard), 99.95% (premium)
Redis:
- Redis Sentinel for automatic failover
- Redis Cluster for sharding
- Manual setup required
AMQP (ActiveMQ Artemis):
- Master-slave configuration
- Clustering support
- Manual setup and maintenance
SQL Server:
- Always On Availability Groups, failover cluster instances
- Inherits your existing SQL Server HA setup
PostgreSQL:
- Streaming replication, Patroni, pgBouncer
- Managed HA via Supabase, RDS Multi-AZ, Cloud SQL HA
In-Process:
- Single process only
- No HA capabilities
Cost Considerations
Azure Service Bus
- Pricing model: Pay per operation + monthly base fee
- Standard tier: ~$10/month + $0.05 per million operations
- Premium tier: ~$670/month (1 messaging unit) + data transfer
- Best for: Production workloads, enterprise applications
Redis
- Self-hosted: Server costs only
- Managed (Azure, AWS): ~$15-100/month depending on size
- Best for: High-volume, cost-sensitive applications
AMQP (ActiveMQ Artemis)
- Self-hosted: Server and maintenance costs
- Best for: On-premises deployments, full control requirements, open standards
SQL Server
- Self-hosted: No additional cost beyond existing SQL Server licence
- Managed (Azure SQL, RDS): Included in existing DB cost
- Best for: Teams already running SQL Server who want zero new infrastructure
PostgreSQL
- Self-hosted: No additional cost beyond existing PostgreSQL instance
- Managed (Supabase, Neon, RDS, Cloud SQL): Included in existing DB cost
- Best for: Teams already running PostgreSQL who want zero new infrastructure
In-Process
- Cost: Free
- Best for: Development and testing only
Migration Between Transports
Thanks to Nimbus’s transport abstraction, you can migrate between transports with minimal code changes:
// Before: Redis
var bus = new BusBuilder()
.Configure()
.WithTransport(new RedisTransportConfiguration()
.WithConnectionString("localhost:6379"))
.WithNames("OrderService", Environment.MachineName)
.Build();
// After: Azure Service Bus (same application code!)
var bus = new BusBuilder()
.Configure()
.WithTransport(new AzureServiceBusTransportConfiguration()
.WithConnectionString(azureConnectionString))
.WithNames("OrderService", Environment.MachineName)
.Build();
Migration Checklist:
- Test thoroughly with new transport
- Verify feature compatibility
- Update monitoring and alerting
- Plan for message migration or cutover
- Have rollback plan ready
Quick Start by Transport
Azure Service Bus
# Install package
dotnet add package Nimbus.AzureServiceBus
var transport = new AzureServiceBusTransportConfiguration()
.WithConnectionString("Endpoint=sb://...")
.WithDefaultTimeout(TimeSpan.FromSeconds(30));
Redis
# Install package
dotnet add package Nimbus.Redis
var transport = new RedisTransportConfiguration()
.WithConnectionString("localhost:6379");
AMQP
# Install package
dotnet add package Nimbus.Transports.AMQP
var transport = new AMQPTransportConfiguration()
.WithBrokerUri("amqp://localhost:5672")
.WithCredentials("admin", "admin")
.WithConnectionPoolSize(10);
SQL Server
dotnet add package Nimbus.Transports.SqlServer
var transport = new SqlServerTransportConfiguration()
.WithConnectionString("Server=localhost;Database=Nimbus;Integrated Security=true;")
.WithAutoCreateSchema();
PostgreSQL
dotnet add package Nimbus.Transports.Postgres
var transport = new PostgresTransportConfiguration()
.WithConnectionString("Host=localhost;Database=nimbus;Username=postgres;Password=secret")
.WithAutoCreateSchema();
In-Process
# Install package (included in core)
dotnet add package Nimbus
var transport = new InProcessTransportConfiguration();
Next Steps
- Choose your transport and follow the detailed setup guide
- Learn about transport abstraction principles
- Explore advanced features available across transports