MinniStore is a lightweight, high-performance event store database management system written in C# (.NET). It stores immutable events in an append-only single-file database on disk and exposes a HTTP REST API for operations.
- Append-only storage: Immutable events stored in a custom binary single-file log.
-
In-Memory Indexing: Fast
$O(1)$ stream lookups and concurrency validation. - Optimistic Concurrency Control: Optimistic lock checks on write operations.
- Instrumentation: Live metrics tracking rates, totals, and server uptime.
- Specification
- Implementation Plan
Start the database server:
minni --port 25000 --db databasefile.dbAlternatively, you can build and run using just:
just runAppends one or more events to a stream.
- Method:
POST - Route:
/streams/{aggregateId} - Headers:
If-Match: (Optional) Expected version of the stream (integer encapsulated in double-quotes, e.g.,"4"). Matches the number of events in the stream prior to this append.
- Request Body:
{ "expectedVersion": 4, // Optional alternative to the If-Match header "events": [ { "data": "eyJrZXkiOiAidmFsdWUtMSJ9" // Base64-encoded string of event bytes } ] } - Success Response (
201 Created):{ "aggregateId": "order-1029", "currentVersion": 5 } - Error Responses:
409 Conflict: Concurrency conflict (expected version mismatch).400 Bad Request: Missing body, empty events array, invalid base64 data, or conflicting version specification.
Retrieves events from a specific stream.
- Method:
GET - Route:
/streams/{aggregateId} - Query Parameters:
fromVersion: (Optional, default =1) Read events starting from this sequence number (inclusive).
- Success Response (
200 OK):[ { "sequenceNumber": 1, "timestamp": 1782930292300, "data": "eyJrZXkiOiAidmFsdWUtMSJ9" // Base64-encoded string of event bytes } ] - Error Responses:
400 Bad Request:fromVersionis less than 1.
We provide helper bash scripts inside the scripts/ folder for quick testing:
Appends a JSON payload to a stream:
./scripts/post-event.sh <aggregate-id> '<json-payload>'
# Example:
./scripts/post-event.sh order-1029 '{"status": "Created", "itemsCount": 3}'Fetches and decodes the stream events into a human-readable format:
./scripts/get-events.sh <aggregate-id>
# Example:
./scripts/get-events.sh order-1029Licensed under the MIT License.
