InMemory Options for Development and Testing

Overview

Brighter V10 provides a comprehensive suite of in-memory implementations for key components, making it easy to develop and test applications without external dependencies. These in-memory options replace databases, message brokers, and schedulers with simple, lightweight alternatives that run entirely in process.

Key Benefits:

  • Zero dependencies: No databases, message brokers, or external services required

  • Fast execution: Perfect for unit and integration tests

  • Simple configuration: Minimal setup, get started immediately

  • Consistent APIs: Same interfaces as production components

  • Deterministic behavior: Predictable, repeatable test execution

Important: InMemory options are designed for development and testing. While robust, they are generally not recommended for production due to lack of persistence, distribution, and durability guarantees.

Available InMemory Components

Brighter V10 provides InMemory implementations for the following components:

Component
Purpose
Production Ready?

Message publishing and consumption

Limited use cases

Transactional messaging

Limited use cases

Message deduplication

Limited use cases

Delayed message scheduling

Limited use cases

Message archiving

No

Claim Check pattern

No

InMemory Transport

The InMemory Transport provides lightweight message publishing and consumption without requiring a message broker like RabbitMQ, Kafka, or AWS SQS. It consists of three replacements:

  • InternalBus An in memory collection of topics, and queues of messages to those topics. It implements IAmABus and can be used from the InMemoryMessageProducer and InMemoryMessageConsumer to exchange a message.

  • InMemoryMessageProducer An implementation of IAmAMessageProducerSync, IAmAMessageProducerAsync and IAmABulkMessageProducerAsync that produces message to topics on the InternalBus.

  • InMemoryMessageConsumer An implementation of IAmAMessageConsumerSync and IAmAMessageConsumerAsync that consumes messages from topics on the InternalBus.

When to Use

Perfect for:

  • Unit testing command and event handlers

  • Integration testing without external dependencies

  • Local development and debugging

  • Demos and proof-of-concepts

Production Use Cases (limited):

  • Single-process applications with no distribution requirements

  • Internal message passing within a monolith

  • Scenarios where message loss is acceptable

Configuration

Internal Bus:

Producer Configuration:

Consumer Configuration:

Complete Example

Limitations

  • No persistence: Messages are lost if the process crashes

  • Single process: Cannot distribute across multiple instances

  • No backpressure: Unlimited queue growth (memory bound)

  • No dead letter queues: Failed messages are discarded

  • No message TTL: Messages never expire

InMemory Outbox

The InMemory Outbox provides transactional messaging support without requiring a database. Note that if you do not specify a persistent Outbox, we will use the InMemoryOutbox, by default. Any use of the CommandProcessor's Post method uses the default InMemoryOutbox and not the persistent Outbox, as it does not take a transaction provider as an argument.

Flush of Expired Messages

The InMemory Outbox will flush expired messages. You can configure the time limit for a message, after which it will be flushed:

  • EntryTimeToLive Defaults to 5 minutes. Governs how long a message can remain in the Outbox.

  • ExpirationScanInterval Defaults to 10 mins. Governs how often a scan for expired messages runs.

Compaction of the InMemoryOutbox

The InMemoryOutbox's capacity is constrained. You can configure the limit to the number of messages the Outbox contains. If you are using the InMemoryOutbox in production scenarios, you should pay attention to this limit. Once the limit is hit, the Outbox will compact, removing older messages first. You can set a compaction percentage, which governs how many messages will be purged from the InMemoryOutbox when we compact.

  • EntryLimit Defaults to 2048. Governs how many messages the InMemoryOutbox can hold.

  • CompactionPercentage When we hit a capacity limit, what percentage of messages should we purge.

When to Use

Perfect for:

  • Testing transactional messaging patterns

  • Unit testing the Outbox pattern

  • Development without database dependencies

Production Use Cases (limited):

  • Single-process applications

  • Non-critical message publishing - the InMemoryOutbox is used in place of a persistent Outbox

  • Scenarios where message loss on restart is acceptable

Configuration

Example of Post

Limitations

  • No persistence: Messages lost on application restart

  • No transactions: Cannot participate in database transactions

  • Single process: State not shared across instances

  • Memory bound: All outstanding messages held in memory

InMemory Inbox

The InMemory Inbox provides message deduplication without requiring a database.

When to Use

Perfect for:

  • Unit testing duplicate message handling

  • Development without database dependencies

Production Use Cases (limited):

  • Single-process applications

  • Short-lived message deduplication windows

  • Non-critical deduplication scenarios

Configuration

Example Usage

Limitations

  • No persistence: Deduplication state lost on restart

  • Single process: Cannot deduplicate across instances

  • Memory bound: All seen message IDs held in memory

  • No cleanup: Old entries remain until process restart

InMemory Scheduler

The InMemory Scheduler provides delayed message execution without requiring Quartz, Hangfire, or cloud schedulers.

When to Use

See the complete InMemory Scheduler documentation for detailed information.

Perfect for:

  • Unit and integration tests

  • Local development

  • Demos and proof-of-concepts

Production Use Cases (very limited):

  • Non-critical scheduled work

  • Short delays (minutes, not hours/days)

  • Acceptable to lose scheduled work on restart

Configuration

Example Usage

For complete documentation, see InMemory Scheduler.

InMemory Archive

The InMemory Archive stores dispatched messages in memory for diagnostics and replay.

When to Use

Perfect for:

  • Testing message archiving

  • Development and debugging

  • Inspecting sent messages in tests

Not recommended for production due to unbounded memory growth.

Configuration

Example Usage

Complete Testing Example

Here's a complete example showing how to use multiple InMemory components together:

Environment-Specific Configuration

Use InMemory components for development/testing, production components elsewhere:

Comparison with Production Components

Feature
InMemory
Production (DB/Broker)

Persistence

None

Database/Disk

Distribution

Single process

Multi-instance

Durability

None

ACID guarantees

Performance

Very fast

Network/IO bound

Setup

Zero config

Requires infrastructure

Testing

Ideal

Complex setup

Production

Limited

Recommended

Migration to Production

When moving to production, replace InMemory components:

InMemory Component
Production Alternative

InMemory Transport

RabbitMQ, Kafka, AWS SQS, Azure Service Bus

InMemory Outbox

MS SQL, PostgreSQL, MySQL, DynamoDB, MongoDB

InMemory Inbox

MS SQL, PostgreSQL, MySQL, DynamoDB, MongoDB

InMemory Scheduler

Quartz, Hangfire, AWS Scheduler, Azure Service Bus Scheduler

InMemory Archive

Database-backed archive provider

No code changes required - just swap the registration in your DI container!

Summary

Brighter V10 provides comprehensive InMemory options for all major components:

Best For:

  • Unit and integration testing

  • Local development

  • Demos and POCs

  • CI/CD pipelines (fast, no external dependencies)

Not Recommended For:

  • Production systems requiring durability

  • Distributed/multi-instance applications

  • Long-running scheduled work

Use InMemory options to accelerate development and testing, then migrate to production components for deployed applications with durability and distribution requirements.

Last updated

Was this helpful?