Skip to content

Choosing an Event Store

WARNING

We created this page with the help of the GenAI tool.

We're currently double-checking it to ensure the information is 100% correct and free of hallucinations.

Emmett supports multiple event store backends. This guide helps you select the right one for your project.

Quick Decision Guide

If you...Choose
Are just starting outIn-Memory or SQLite
Want production-ready with familiar techPostgreSQL
Already use MongoDBMongoDB
Want native Event Sourcing featuresEventStoreDB
Need embedded/serverlessSQLite

Comparison Matrix

FeaturePostgreSQLEventStoreDBMongoDBSQLiteIn-Memory
Production ReadyYesYesYesLimitedNo
Persistent StorageYesYesYesYesNo
Built-in ProjectionsInline + AsyncAsync onlyInline + AsyncInline + AsyncInline
Multi-tenancyPartitionsStreamsCollectionsSeparate DBsN/A
TransactionsFull ACIDStream-levelDocument-levelFull ACIDN/A
Horizontal ScalingYesYes (cluster)YesNoNo
Learning CurveLow (SQL)MediumLowLowNone
InfrastructurePostgreSQLEventStoreDBMongoDBFile/MemoryNone

PostgreSQL

Best for: Most production applications, teams with SQL experience.

PostgreSQL is the recommended choice for most applications. It's battle-tested, widely deployed, and your team likely already knows it.

Strengths

  • Familiar technology - SQL knowledge transfers directly
  • Rich ecosystem - Excellent tooling, monitoring, hosting options
  • ACID transactions - Inline projections in same transaction as events
  • Multi-tenancy - Native table partitioning for tenant isolation
  • Pongo integration - Document-style projections with JSONB

When to Choose

  • You want a proven, reliable solution
  • Your team knows PostgreSQL
  • You need strong transactional guarantees
  • You want inline projections with guaranteed consistency

Installation

bash
npm install @event-driven-io/emmett-postgresql

Quick Setup

typescript
import { getPostgreSQLEventStore } from '@event-driven-io/emmett-postgresql';

const eventStore = getPostgreSQLEventStore(
  'postgresql://user:password@localhost:5432/mydb',
);

Documentation: PostgreSQL Event Store


EventStoreDB

Best for: Teams wanting native Event Sourcing capabilities.

EventStoreDB is purpose-built for Event Sourcing. It offers features specifically designed for event-driven systems.

Strengths

  • Purpose-built - Designed specifically for Event Sourcing
  • Stream subscriptions - Native catch-up and persistent subscriptions
  • Projections - Server-side JavaScript projections
  • Clustering - Built-in high availability

When to Choose

  • You want a dedicated Event Sourcing database
  • You need advanced subscription features
  • You're building a complex event-driven system
  • You want server-side projection capabilities

Installation

bash
npm install @event-driven-io/emmett-esdb

Quick Setup

typescript
import { getEventStoreDBEventStore } from '@event-driven-io/emmett-esdb';
import { EventStoreDBClient } from '@eventstore/db-client';

const client = EventStoreDBClient.connectionString(
  'esdb://localhost:2113?tls=false',
);
const eventStore = getEventStoreDBEventStore(client);

Documentation: EventStoreDB Event Store


MongoDB

Best for: Teams already using MongoDB who want Event Sourcing.

MongoDB provides a document-oriented approach to event storage with flexible querying capabilities.

Strengths

  • Document model - Natural fit for event data
  • Flexible schemas - Easy to evolve event structures
  • Familiar for MongoDB users - Same query patterns
  • Storage strategies - Multiple approaches for different needs

When to Choose

  • Your team already uses MongoDB
  • You want document-oriented storage
  • You need flexible event schemas
  • You prefer MongoDB's query capabilities

Installation

bash
npm install @event-driven-io/emmett-mongodb

Quick Setup

typescript
import { getMongoDBEventStore } from '@event-driven-io/emmett-mongodb';

const eventStore = getMongoDBEventStore({
  connectionString: 'mongodb://localhost:27017',
  database: 'events',
});

Documentation: MongoDB Event Store


SQLite

Best for: Development, testing, embedded applications, edge computing.

SQLite provides a lightweight, file-based or in-memory event store perfect for development and specific production scenarios.

Strengths

  • Zero configuration - No server to manage
  • File or in-memory - Flexible storage options
  • Fast for development - Instant startup
  • Portable - Single file database
  • Edge computing - Runs anywhere

When to Choose

  • Local development and testing
  • Embedded applications
  • Edge/serverless deployments
  • Prototyping before choosing production database
  • Desktop applications

Limitations

  • Not suitable for high-concurrency production workloads
  • Single-writer limitation
  • No horizontal scaling

Installation

bash
npm install @event-driven-io/emmett-sqlite

Quick Setup

typescript
import { getSQLiteEventStore } from '@event-driven-io/emmett-sqlite';

// File-based
const eventStore = getSQLiteEventStore('./events.db');

// In-memory
const eventStore = getSQLiteEventStore(':memory:');

Documentation: SQLite Event Store


In-Memory

Best for: Unit testing and prototyping.

The in-memory event store is included in the core Emmett package. It's perfect for testing and learning.

Strengths

  • No dependencies - Included in core package
  • Instant - No setup, no persistence
  • Perfect for tests - Fast, isolated, deterministic
  • Learning - Understand patterns without infrastructure

When to Choose

  • Unit and integration testing
  • Learning Emmett
  • Prototyping business logic
  • Demonstration code

Limitations

  • Data lost on restart
  • Not for production

Quick Setup

typescript
import { getInMemoryEventStore } from '@event-driven-io/emmett';

const eventStore = getInMemoryEventStore();

Migration Between Stores

Emmett's consistent EventStore interface makes migration straightforward:

typescript
// Development
const eventStore = getInMemoryEventStore();

// Testing with real database
const eventStore = getSQLiteEventStore(':memory:');

// Production
const eventStore = getPostgreSQLEventStore(connectionString);

Your business logic, command handlers, and projections remain unchanged.

Decision Flowchart

Start

  ├─ Is this for testing/learning?
  │   └─ Yes → In-Memory or SQLite

  ├─ Do you need production persistence?
  │   │
  │   ├─ Already using PostgreSQL?
  │   │   └─ Yes → PostgreSQL
  │   │
  │   ├─ Already using MongoDB?
  │   │   └─ Yes → MongoDB
  │   │
  │   ├─ Want native ES features?
  │   │   └─ Yes → EventStoreDB
  │   │
  │   └─ Not sure?
  │       └─ PostgreSQL (safest choice)

  └─ Need embedded/edge deployment?
      └─ Yes → SQLite

See Also