Documents,
not rows.
MongoDB stores data the way your application thinks about it — nested objects, arrays, and hierarchies in one document. Faster to develop against, when the shape of your data actually fits.
One document = one logical entity, with everything it needs. No joins for the common read path.
Atlas
Default managed platform
7.0
Current version we ship
99.995%
Uptime across managed clusters
5–10 d
Engineer placement
The stack
Tools we ship with.
MongoDB 7.0
Database
Atlas
Managed cloud
Mongoose
ODM (Node)
Prisma
ORM (TS)
Compass
GUI
mongosh
Shell
Atlas Search
Full-text
Atlas Vector
Vector search
Atlas Charts
BI dashboards
Realm
Mobile sync
Change Streams
Realtime
Atlas Data Lake
S3 queries
Data modeling
Four patterns. Applied to every project.
MongoDB doesn't have a single correct schema. It has patterns — and knowing when to apply each is the whole skill.
Embedded documents
Order items, product reviews, user profiles — things read together, stored together.
Reference when it grows
If an array can grow unbounded, store it as a separate collection with a reference.
Indexes on access paths
Index every field you query by, and compound indexes for common filter combinations.
Sharding by tenant or time
Shard keys are forever. Pick one that matches your dominant access pattern.
Embed when
- Data is read together
- Child is bounded in size
- Child doesn't exist on its own
- One-to-few relationships
- Updates are atomic per parent
Reference when
- Array can grow unbounded
- Child is queried independently
- Child is shared by many parents
- Child needs its own indexes
- Document size approaches 16MB
Anti-patterns
Unbounded arrays
A log array that grows forever. Eventually hits 16MB, then queries slow down.
Deep nesting (5+ levels)
Hard to query, hard to index, hard to update. Flatten where possible.
Massive single documents
Approaching the 16MB limit. Split into related collections.
No indexes on query fields
Every query becomes a collection scan. The #1 cause of slow MongoDB.
$where in production
Runs JavaScript per document. Unindexable and dangerous.
Missing schema validation
Schema-flexible is not the same as schema-less. Validate at the boundary.
Deep nesting past 100 levels
Hard limit. Design to stay well under it.
Growth without shard planning
Discovering you need to shard after the fact is painful.
Aggregation framework
Complex queries, one round trip.
The aggregation pipeline is MongoDB's killer feature. Multiple stages, transformed data, no application-side joins. Real pipelines from production systems.
db.orders.aggregate([
// Filter early — uses the index
{ $match: { status: 'paid', createdAt: { $gte: ISODate('2026-01-01') } } },
// Reduce the data before grouping
{ $project: { items: 1, total: 1, 'customer.id': 1 } },
// Flatten items array
{ $unwind: '$items' },
// Group by SKU
{ $group: {
_id: '$items.sku',
revenue: { $sum: { $multiply: ['$items.qty', '$items.price'] } },
orders: { $sum: 1 },
}},
// Top 10 by revenue
{ $sort: { revenue: -1 } },
{ $limit: 10 },
]);Indexing
Index the access paths, not the schema.
Compound indexes — ESR rule
Equality, Sort, Range. Order fields in the index by this priority. Gets it right almost every time.
Multikey indexes for arrays
MongoDB automatically indexes each element of an array. Fast containment queries on tags, categories, etc.
Partial indexes
Index only the docs your queries touch. Smaller, faster, cheaper — like Postgres partials.
Text indexes
Built-in full-text search. Stemming, stop words, weights. No separate search engine for many use cases.
TTL indexes
Auto-expire documents at a time. Sessions, OTPs, event streams — no cleanup jobs needed.
Wildcard indexes
For fields whose names you don't know ahead of time. Flexible schema without losing query speed.
Honest comparison
MongoDB vs others.
Every database is a set of trade-offs. Here's when we pick MongoDB, and when we don't.
MongoDB
Best fitType
Document
Best when
Flexible schema, document-shaped reads
Signals
- Data is genuinely document-shaped
- Schema evolves fast
- Horizontal sharding without ceremony
- Read-heavy whole-document access
- Realtime + change streams
PostgreSQL
Type
Relational + JSONB
Best when
ACID, joins, complex queries
Signals
- Data is genuinely relational
- Multi-entity ACID transactions
- Complex reporting and analytics
- Financial correctness matters
- Extensions (pgvector, PostGIS)
DynamoDB
Type
Key-value + document
Best when
Massive scale, predictable access
Signals
- Access patterns are known and fixed
- Single-digit ms latency at any scale
- AWS-native infrastructure
- Serverless with zero ops
- You accept vendor lock-in
Firebase
Type
Document + realtime
Best when
Mobile/web realtime with no backend
Signals
- Real-time sync is the primary feature
- Small mobile/web apps
- You want zero backend code
- Google Cloud ecosystem
- Client SDKs are the main interface
MongoDB Atlas
The platform most teams actually use.
Atlas isn't just managed hosting — it's a suite of features built on top of MongoDB. Search, vectors, triggers, BI — all from the same data.
Atlas Search
Lucene-powered full-text search on your data. Fuzzy matching, autocomplete, synonyms, ranking.
Atlas Vector Search
Vector embeddings with HNSW indexes. RAG pipelines, semantic search, recommendations.
Atlas Data Lake
Query S3 as if it were a collection. Combine with live data in one aggregation pipeline.
Atlas Charts
BI dashboards built on your collections. Drag-and-drop, embeddable, live-updating.
Atlas Triggers
Serverless functions that fire on database events. Insert, update, delete — no polling.
Atlas Serverless
Pay-per-request instances. Scales to zero. Perfect for dev, preview, and bursty production.
Change streams
Realtime from the database itself.
Watch any collection and react to changes as they happen. Resume tokens survive restarts. Aggregation pipelines filter events before they reach your app.
Watch any collection
Subscribe to insert/update/delete events in real time. Resume tokens survive disconnects.
Pipeline on the stream
Aggregate on the change stream itself. Filter, transform, or route events before they reach your app.
Sync engines
Keep external systems in sync — search indexes, caches, analytics warehouses.
Realtime apps
Live dashboards, chat, collaboration. WebSockets on the app side, change streams on the DB side.
const stream = db.collection('orders').watch([
{ $match: { 'operationType': { $in: ['insert', 'update'] } } },
{ $match: { 'fullDocument.status': 'paid' } },
]);
stream.on('change', async (change) => {
// Push to WebSocket subscribers
await realtime.publish('orders', change.fullDocument);
// Update analytics warehouse
await warehouse.upsert(change.fullDocument);
// Save resume token for restart safety
await checkpoints.save(change._id);
});Transactions
When atomicity matters across documents.
Single-document writes are atomic. Multi-document transactions exist since 4.0 — used when correctness requires them, avoided when design can.
Single-document atomicity
Always. Every write to one document is atomic — no transaction needed. This is why we embed related data.
Multi-document transactions
Since 4.0 on replica sets, 4.2 on sharded clusters. Multi-statement, multi-collection, ACID.
The performance cost
Transactions hold locks. Slower than single-document writes. Use only where correctness requires it.
Order placement pattern
The classic use case — decrement stock, insert order, charge customer. Three writes, one transaction.
Design principle
Model so you rarely need transactions. If most writes are single-document, you rarely do.
Retry on conflict
Transient transaction errors are expected. Retry the whole transaction with exponential backoff.
Sharding
Scale-out without hand-rolling it.
Sharding spreads data across clusters. It's a scale-out decision — not a default — and the shard key is forever.
Shard keys
The field that determines distribution. High cardinality, low frequency, non-monotonic. Forever once chosen.
Ranged sharding
Contiguous ranges per shard. Great for time-series with range queries. Hot spots if keys are monotonic.
Hashed sharding
Even distribution via hash. Write throughput spreads. Range queries hit more shards.
Zone sharding
Pin ranges to specific shards. Data residency, geo-distribution, tiered storage.
Chunk migration
The balancer moves chunks between shards automatically. You watch the metrics, it does the work.
When to shard
Not until you must. A 3-node replica set handles most workloads. Sharding is a scale-out decision, not a default.
Schema validation
Schema-flexible, not schema-less.
MongoDB doesn't enforce a schema by default. That's a feature — when used deliberately. We validate at the boundary so flexibility doesn't become chaos.
$jsonSchema rules
Server-side validation using JSON Schema. Reject bad writes at the database layer.
Mongoose schemas
Application-layer schema for Node.js. Types, validation, middleware. The most common pattern.
Zod validators
Shared validation between API and database. One schema, both layers.
When to enforce
Always for user-facing data. Stable shapes, sensitive fields, anything audited.
When to stay flexible
Event logs, analytics, integrations. Schema-flexible is a feature, not a defect.
Migration strategy
Version-controlled scripts that transform documents. Idempotent, re-runnable, same discipline as SQL.
Performance
Measure. Then change one thing.
Explain plans
db.collection.find(...).explain('executionStats'). If you see COLLSCAN, you need an index.
Index covers query
If the index has every field the query needs, MongoDB never touches the document. Fastest read.
Working set in RAM
Keep the index + hot data in memory. Everything else waits for disk.
Read preferences
primary, primaryPreferred, secondary, nearest. Route reads based on consistency needs.
Write concern
w:1, w:majority, j:true. Trade durability for throughput based on what each write means.
Connection pooling
Driver-managed, sized for your app. One pool per process, sized to match workload.
Observability
You can't tune what you can't see.
db.currentOp()
Real-time view of what's running. Kill runaway queries. Spot lock waits.
db.serverStatus()
Internal metrics — memory, connections, op counters. Feed into your monitoring stack.
Performance Advisor
Atlas analyzes slow queries and recommends indexes. Usually right.
Query Profiler
Slow query log on the database or Atlas. Set threshold, get a feed of the worst.
Replica set metrics
Replication lag, oplog window, member health. Alert before lag becomes an issue.
Atlas Alerts
Proactive monitoring — connection spikes, index misses, disk usage. Wired to Slack or PagerDuty.
Time-series
Native time-series collections.
Since MongoDB 5.0, purpose-built for metrics, events, and telemetry. Column-oriented storage within buckets — 10× smaller than regular collections.
Native time-series collections
Since MongoDB 5.0. Purpose-built for metrics, events, and telemetry at scale.
Bucketing strategy
Documents grouped by time + metaField. Far smaller storage, faster queries.
Compression built in
Column-oriented compression within buckets. 10× smaller than regular collections.
TTL cleanup
Expire documents automatically. Keep 90 days of metrics, drop the rest — no cron needed.
Windows and rollups
Aggregation pipelines with $setWindowFields. Rolling averages, rates, moving windows.
vs TimescaleDB
Similar use case. Timescale if you're already on Postgres. Time-series if you're already on Mongo.
GridFS
Files beyond 16MB.
Files over 16MB
Documents cap at 16MB. GridFS chunks larger files and stores them across documents.
Two collections
fs.files for metadata, fs.chunks for data. Driver handles it transparently.
Streaming I/O
Read and write in chunks. No need to load the whole file into memory.
When to use
Small binaries that live with their metadata. Video, ML model weights, customer uploads.
When to use S3
Large media, CDN-served assets, anything where storage cost matters more than integration.
Replication
GridFS replicates with the rest of the database. No separate backup strategy needed.
Atlas Vector Search · AI features in your database
AI without a second database.
Store embeddings alongside your documents. Query by meaning with HNSW indexes. No sync pipeline, no lost transactions between two systems.
Semantic search
Embed a query, find similar documents by meaning. Ranked by cosine similarity.
RAG pipelines
Store embeddings alongside source documents. One query, retrieve context, pass to LLM.
Recommendations
Similar products, related articles, 'users who liked' — vector similarity at query time.
Hybrid search
Combine vector similarity with Atlas Search full-text ranking. Best of both.
Pre-filtering
Filter by $match before vector search. Restrict to tenant, category, or price range.
HNSW indexing
Approximate nearest neighbour. Sub-50ms queries on millions of vectors.
Security
Encrypted, authenticated, audited.
SCRAM authentication
Username/password with challenge-response. Default in modern MongoDB.
Role-based access control
Custom roles with least privilege. Read-only for analytics, write for services.
Field-level encryption
Client-side encryption of sensitive fields. The server never sees plaintext.
TLS everywhere
Encrypted in transit. Enforced by default on Atlas.
IP access lists
Allowlist of IPs or VPC peering. No open-to-the-world deployments.
Audit logging
Every auth attempt, every schema change, every admin action. Enterprise tier.
Backups & recovery
Continuous, tested, cross-region.
Continuous backups
Atlas captures the oplog continuously. Point-in-time restore to any second.
Snapshots
Scheduled full backups. Daily, weekly, monthly — retention configurable per tier.
Cross-region restore
Backups stored in a separate region. Restore into a different geography if needed.
RTO and RPO
Documented for every client. Tested quarterly with actual restore drills.
Self-managed option
mongodump / mongorestore for self-hosted. Filesystem snapshots for consistency.
Backup verification
We don't just take backups — we restore them into a test cluster and verify.
Hosting
Managed vs self-hosted.
Atlas by default. Self-hosted only when there's a specific reason: cost at scale, data residency, or specific compliance.
MongoDB Atlas
ManagedOfficial managed platform. Multi-cloud, multi-region, best-in-class tooling.
AWS DocumentDB
ManagedMongoDB-compatible. Not actually MongoDB — be careful with driver edge cases.
DigitalOcean
ManagedManaged MongoDB at fair prices. Simple, good for mid-scale.
ScaleGrid
ManagedManaged MongoDB on AWS, Azure, GCP. Solid for enterprise.
Self-hosted
Self-hostedEC2, Hetzner, or on-prem. For cost at scale, data residency, or compliance.
Realm (Mobile)
MobileAtlas Device Sync for mobile. Local-first data with cloud backup.
Anti-patterns
What we never do.
Unbounded arrays in documents
A log array that grows forever. Eventually hits 16MB, then queries slow down.
Deep nesting (5+ levels)
Hard to query, hard to index, hard to update. Flatten where possible.
Massive single documents
Approaching the 16MB limit. Split into related collections.
No indexes on query fields
Every query becomes a collection scan. The #1 cause of slow MongoDB.
$where in production
Runs JavaScript per document. Unindexable and dangerous.
Missing schema validation
Schema-flexible is not the same as schema-less. Validate at the boundary.
Ignoring the 100-level limit
Hard limit on nested depth. Design to stay well under it.
Growth without shard planning
Discovering you need to shard after the fact is painful.
Real-world use
What teams actually build.
Ecommerce
Product catalogs, orders, carts, inventory. Variable attributes per category.
Content platforms
Articles, media, comments, metadata. Flexible shape per content type.
IoT & telemetry
Device events, time-series metrics, sensor data. Native time-series collections.
Gaming
Player profiles, leaderboards, matchmaking, session state. Low-latency reads.
Realtime apps
Chat, notifications, collaboration. Change streams + WebSockets.
AI products
Embeddings with Atlas Vector Search. RAG pipelines on your own data.
Versions
What we ship today.
MongoDB 7.0
Default for all new projects
MongoDB 6.0
Existing projects — upgrade recommended
MongoDB 5.0
Time-series collections introduced
MongoDB 4.4 and older
Upgrade required
Honest advice
When to use MongoDB.
When to reach for Postgres.
Choose MongoDB when
- Your data is genuinely document-shaped
- Schema evolves fast and SQL migrations slow you down
- You need horizontal sharding without hand-rolling it
- Read-heavy patterns fetching whole documents
- Realtime features with change streams
Consider alternatives when
- Data is genuinely relational with many joins
- You need ACID across many entities in one transaction
- Complex analytical queries dominate your workload
- Financial data where every cent must reconcile
- You don't have a specific reason to leave SQL
The process
Five phases. Every MongoDB build follows them.
Discovery
Data shape, access patterns, expected scale. We model the top 20 queries before we touch collections.
Deliverables
Data model · Access patterns · Shard plan · Fixed quote
Modeling
Embed/reference decisions, index plan, schema validation rules. The shape of data determines everything.
Deliverables
Collections design · Indexes · Validators · Migration scripts
Build
Collections, indexes, validation, application integration. Change streams where realtime is needed.
Deliverables
Working integration · Test suite · Documentation · Preview deploy
Operations
Atlas setup, backups, monitoring, alerting. Failover drilled. Performance baselines measured.
Deliverables
Atlas cluster · Backup pipeline · Monitoring · Runbook
Support
Tuning, version upgrades, feature iteration, on-call. MongoDB evolves — we stay current.
Deliverables
Monthly retainer · Upgrade plan · On-call rotation · Quarterly review
Selected work
MongoDB in production.
Product catalog with variable schemas
10,000 SKUs across 20 categories, each with different attributes. One collection, dynamic schemas, Atlas Search for discovery.
Outcome
10k SKUs live
Event pipeline with change streams
Every write streams to a search index, a cache, and an analytics warehouse — with resume tokens for reliability.
Outcome
3 sinks, no lag
SaaS with per-tenant sharding
Tenants sharded across clusters by tenant ID. Zone sharding for data residency. Region-pinned compliance.
Outcome
Zone-sharded
Client feedback
What our clients
actually say.
“The move to SikaNet CBS was a bigger shift than I expected — but the right one. Before, our Susu collectors were on paper and every BOG report took us days to assemble. Now collections appear in the office before a collector even finishes their route, and the reports are just there. The team understood our business from day one.”
David Awuni
Founder, Adwumapa Microfinance
“We were cautious about moving patient records online. The on-prem approach changed that — everything stays inside the health center, nothing goes to a foreign cloud. Our clinicians now retrieve a file in seconds instead of ten minutes, and every entry has an audit trail behind it.”
Medical Director
Sekyedumase Health Center
“The patient management system they developed has streamlined our ophthalmology department. Appointment scheduling, patient records, and referral tracking are now seamless — saving us hours of administrative work every day.”
Isaac Adu
Ophthalmologist, Ghana Health Service
Let us talk
Working with MongoDB?
Whether you're building on it or evaluating whether to switch, we can help.
