Amazon DocumentDB: When MongoDB Compatibility Bites Back in Production
Amazon DocumentDB promises MongoDB compatibility but hides sharp edges.
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
- ✓Basic MongoDB query syntax
- ✓Familiarity with AWS RDS or DynamoDB
- ✓Understanding of connection pooling
Amazon DocumentDB is AWS's managed MongoDB-compatible database. Use it when you need MongoDB-like document storage but want AWS to handle backups, patching, and replication. Don't use it if you rely on MongoDB-specific features like change streams, transactions, or the aggregation pipeline beyond basic stages.
Imagine you order a 'burger' from a fast-food joint that says 'burger' on the menu. You get a patty between buns, but it's not the same as the gourmet burger place down the street. Amazon DocumentDB is that fast-food burger — it looks like MongoDB, smells like MongoDB, but when you bite into it, you notice the missing toppings. It works for most meals, but don't bring your gourmet recipe here.
Here's the truth nobody at AWS wants to shout: Amazon DocumentDB is not MongoDB. It's a separate engine that speaks MongoDB's wire protocol — mostly. I've seen teams migrate their MongoDB 3.6 workloads thinking it's a drop-in replacement, only to have their aggregation pipelines fail silently at 2 AM. The docs say 'compatible.' The reality is a compatibility matrix you need to study like a pilot's pre-flight checklist.
The problem DocumentDB solves is real: managing MongoDB yourself on EC2 is a nightmare. Backups, failover, scaling — it's a full-time job. AWS offers to handle all that, plus replication across three AZs. For many workloads, that trade-off is worth it. But you need to know exactly what you're giving up.
By the end of this, you'll know exactly when to use DocumentDB, how to configure it for production, and — more importantly — the three failure modes that will burn you if you treat it like real MongoDB. You'll walk away with a decision framework, not just syntax.
Why DocumentDB Exists: The Managed MongoDB Nightmare
Running MongoDB on EC2 is like adopting a pet elephant. It's powerful, but you're cleaning up after it constantly. Backups? You script them. Failover? You build a replica set. Patching? You schedule downtime. Amazon DocumentDB takes that elephant and puts it in a zoo — AWS feeds it, cleans its enclosure, and handles the vet visits. You just throw queries at it.
The real win is operational simplicity. DocumentDB replicates your data across three Availability Zones automatically. Storage scales from 10 GB to 64 TB without you lifting a finger. Backups are continuous to S3 with point-in-time recovery. For teams that don't have a dedicated DBA, that's gold.
But here's the catch: you're locked into AWS's implementation. If MongoDB releases a killer feature in 4.2 or 5.0, you won't get it until AWS decides to support it — if ever. DocumentDB currently targets MongoDB 3.6 and 4.0 API compatibility. That's a 5-year-old version as of 2024.
SSLHandshakeFailed. Always include ssl=true&ssl_ca_certs=rds-combined-ca-bundle.pem in your connection string.Connection Pooling: The Silent Throttle
Every DocumentDB instance has a max connection limit. For db.r5.large, it's 1000. Sounds like a lot until your microservices each open 50 connections. I've seen a single service exhaust the pool at 3 AM during a traffic spike, causing cascading failures across the entire stack.
The fix isn't just increasing the instance size — that's expensive. You need to tune your connection pool. MongoDB drivers default to 100 connections per pool. For DocumentDB, that's aggressive. Drop it to 10-20 per service instance and use connection pooling with a queue.
Also, DocumentDB doesn't support the maxPoolSize option in the same way as MongoDB. The driver will respect it, but DocumentDB's server-side limits are hard. Monitor DatabaseConnections CloudWatch metric and set alarms at 80% of the limit.
readPreference=secondaryPreferred in your connection string. This cuts writer load in half.Aggregation Pipeline: What Works and What Doesn't
DocumentDB supports a subset of MongoDB's aggregation pipeline. The basics work: $match, $group, $sort, $project, $limit, $skip. But the moment you reach for $lookup with a pipeline, $graphLookup, $facet, or $bucket, you're in unsupported territory. The engine won't error — it'll silently return empty or incomplete results.
I've debugged a production issue where a $lookup with let and pipeline variables returned zero documents. No error, no warning. The team spent two days thinking it was a data problem. The fix was to split the aggregation into two queries and join in application code.
Here's the rule: if your aggregation uses anything beyond the basic stages, test it on DocumentDB before deploying. The official compatibility docs list supported stages, but they miss edge cases. For example, $addFields works, but $set (alias) doesn't.
$lookup with pipeline or let in production on DocumentDB. It will silently fail. Always test your aggregations in a staging DocumentDB cluster before deploying.Indexing Strategy: The Write Performance Trap
DocumentDB uses a different storage engine than MongoDB. It's built on AWS's own distributed storage, not WiredTiger. That means index behavior differs. Specifically, DocumentDB's indexes are B-tree based and don't support partial indexes, sparse indexes, or TTL indexes. If you rely on TTL to auto-delete expired documents, you'll need a different approach.
More critically, every index you add slows down writes. On MongoDB, the impact is linear. On DocumentDB, it's worse because the storage layer adds latency. I've seen a 4-index collection on a db.r5.large instance handle 500 writes/sec. Adding a fifth index dropped it to 200 writes/sec. The fix: keep indexes minimal. Only index fields you query on, and use compound indexes instead of multiple single-field indexes.
Another gotcha: DocumentDB doesn't support background index creation. All index builds block writes. Schedule them during maintenance windows.
createIndex blocks all writes until the index build completes. For large collections, this can take hours. Always build indexes during low-traffic periods and monitor DatabaseConnections for dropped connections.Backup and Restore: The Hidden Costs
DocumentDB automatically backs up your cluster to S3 with point-in-time recovery within your backup retention window (1-35 days). That's great. But restoring a cluster takes time — up to several hours for multi-TB databases. And you can't restore to an existing cluster; you get a new one. That means DNS changes, connection string updates, and potential downtime.
Another hidden cost: backups consume storage I/O. During backup windows, you might see increased latency. Schedule backups during off-peak hours and monitor BackupRetentionPeriod and BackupStorageUsed metrics.
For cross-region disaster recovery, DocumentDB doesn't support cross-region snapshots natively. You have to manually copy snapshots to another region using AWS CLI or console. That's an operational burden.
When Not to Use DocumentDB: The Honest Assessment
DocumentDB is not a universal MongoDB replacement. Avoid it if:
- You need MongoDB 4.0+ features like transactions, change streams, or
$graphLookup. DocumentDB's transaction support is limited to single-document atomicity — no multi-document transactions. - Your workload is write-heavy with high throughput. DocumentDB's write performance degrades under sustained load due to its journaling mechanism. MongoDB on provisioned IOPS SSDs can outperform it.
- You rely on MongoDB-specific tools like Compass, Atlas Search, or Ops Manager. They won't work with DocumentDB.
- You need cross-region active-active replication. DocumentDB only supports single-region with read replicas in the same region.
For read-heavy, moderate-write workloads that don't need cutting-edge MongoDB features, DocumentDB is a solid choice. The operational savings often outweigh the feature gaps. But if you're building a new project and expect to need MongoDB's full feature set, just use MongoDB Atlas on AWS. It's more expensive but you get the real thing.
The Aggregation Pipeline That Went Silent
$lookup with a pipeline sub-stage to filter joined documents. DocumentDB's $lookup only supports the basic localField/foreignField syntax. The pipeline variant is silently ignored — no error, just no results.$lookup with localField and foreignField, then apply filters with $match in a separate stage. Alternatively, pull the data in application code with two queries.- Never trust 'compatible' without testing every query path.
- DocumentDB's aggregation pipeline is a subset — test your most complex aggregations in a staging environment first.
MongoError: failed to connect to serverssl=true&ssl_ca_certs=rds-combined-ca-bundle.pem. 3. Confirm the cluster is in available status via AWS Console or CLI. 4. Test connectivity using nc -zv <endpoint> 27017.db.setProfilingLevel(1, { slowms: 1000 }). 2. Check for missing indexes using explain() on the query. 3. Review ReadIOPS and WriteIOPS CloudWatch metrics — high values indicate storage bottleneck. 4. Scale up instance class or add reader instances.DatabaseConnections — if near max, reduce connection pool sizes or add instances. 2. Check WriteIOPS — if maxed out, batch writes into smaller chunks (e.g., 100 docs per batch). 3. Review JournalWriteIOPS — DocumentDB throttles when journal is full. 4. Consider increasing storage IOPS by moving to a larger instance class.nc -zv <cluster-endpoint> 27017aws docdb describe-db-clusters --db-cluster-identifier <cluster-id> --query 'DBClusters[0].Status'ssl=true&ssl_ca_certs=rds-combined-ca-bundle.pem to connection string and ensure security group allows inbound 27017| File | Command / Code | Purpose |
|---|---|---|
| ProvisionDocumentDB.devops | aws docdb create-db-cluster \ | Why DocumentDB Exists |
| ConnectionPoolConfig.devops | const uri = 'mongodb://admin:SuperS3cret!@production-cluster.cluster-xxxxx.us-ea... | Connection Pooling |
| AggregationWorkaround.devops | db.orders.aggregate([ | Aggregation Pipeline |
| IndexManagement.devops | db.collection('orders').getIndexes() | Indexing Strategy |
| BackupRestore.devops | aws docdb create-db-cluster-snapshot \ | Backup and Restore |
| DecisionMatrix.devops | const workload = { | When Not to Use DocumentDB |
Key takeaways
maxPoolSize to 10-20 per service and use reader endpoints.$lookup with pipelinelocalField/foreignField or application-level joins.Interview Questions on This Topic
How does Amazon DocumentDB handle connection pooling differently from MongoDB, and what production issues can arise?
maxPoolSize to 10-20 per service instance and use reader endpoints. Exceeding the limit causes MongoError: connection timed out and cascading failures.Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
That's AWS. Mark it forged?
3 min read · try the examples if you haven't