---
title: MongoDB Store
description: Document store using Grove ORM with mongodriver for MongoDB.
---

The MongoDB store (`store/mongo`) uses the [Grove ORM](https://github.com/xraph/grove) with `mongodriver` to persist data in MongoDB. It is the recommended store for teams that prefer document databases or need horizontal scalability.

## When to use

- **Document-oriented data** -- flexible schemas that evolve with your application.
- **Horizontal scaling** -- MongoDB sharding for large-scale deployments.
- **Cloud-native** -- MongoDB Atlas for managed deployments.
- **Teams familiar with MongoDB** -- leverage existing document database expertise.

## Configuration

```go
import (
    "github.com/xraph/grove"
    "github.com/xraph/grove/drivers/mongodriver"
    "github.com/xraph/ctrlplane/store/mongo"
)

// Open a MongoDB connection via Grove's mongodriver.
db := grove.Open(mongodriver.New(
    mongodriver.WithURI("mongodb://localhost:27017"),
    mongodriver.WithDatabase("ctrlplane"),
))

s := mongo.New(db)
if err := s.Migrate(ctx); err != nil {
    log.Fatal(err)
}
```

### With the app

```go
cp, err := app.New(
    app.WithStore(s),
)
```

## Collections

The MongoDB store uses 15 collections:

| Collection | Entity | Primary key |
|------------|--------|-------------|
| `cp_instances` | Instance | TypeID string |
| `cp_deployments` | Deployment | TypeID string |
| `cp_releases` | Release | TypeID string |
| `cp_health_checks` | HealthCheck | TypeID string |
| `cp_health_results` | HealthResult | TypeID string |
| `cp_metrics` | Metric | TypeID string |
| `cp_logs` | LogEntry | TypeID string |
| `cp_traces` | Trace | TypeID string |
| `cp_resource_snapshots` | ResourceSnapshot | TypeID string |
| `cp_domains` | Domain | TypeID string |
| `cp_routes` | Route | TypeID string |
| `cp_certificates` | Certificate | TypeID string |
| `cp_secrets` | Secret | TypeID string |
| `cp_tenants` | Tenant | TypeID string |
| `cp_audit_entries` | AuditEntry | TypeID string |

## Internals

| Aspect | Detail |
|--------|--------|
| **Driver** | Grove ORM with `mongodriver` (MongoDB) |
| **Serialization** | Intermediate BSON model structs with `bson:` tags |
| **Identity** | TypeID strings stored as `_id` field |
| **Migrate** | Creates compound and unique indexes on all collections |
| **Ping** | `db.Ping(ctx)` |
| **Close** | `db.Close()` to disconnect |

### Indexes

`Migrate()` creates compound indexes for efficient queries:

- **All collections** -- `(tenant_id, ...)` compound indexes for tenant-scoped queries.
- **Instances** -- unique `(tenant_id, slug)` index.
- **Tenants** -- unique `(slug)` index.
- **Domains** -- unique `(hostname)` index.
- **Secrets** -- unique `(tenant_id, instance_id, key)` index.
- **Time-series** -- `(tenant_id, instance_id, timestamp)` for metrics, logs, traces, and snapshots.

## Limitations

- **External dependency** -- requires a running MongoDB instance or Atlas cluster.
- **No ACID transactions** -- individual operations are atomic, but multi-document transactions require explicit sessions.
- **Index management** -- `Migrate()` must run before first use to create indexes.

## Comparison

| Feature | Memory | Badger | PostgreSQL | SQLite | MongoDB |
|---------|--------|--------|------------|--------|---------|
| Setup | None | Path only | DSN | File path | URI |
| Persistence | No | Yes | Yes | Yes | Yes |
| Multi-process | No | No | Yes | No | Yes |
| Query flexibility | Low | Low | High | Medium | High |
| Horizontal scaling | No | No | Read replicas | No | Sharding |
| Best for | Tests | Embedded KV | Production SQL | Embedded SQL | Production NoSQL |
