This article explains how to collect MongoDB size statistics for all collections and indexes across all databases. The output is sorted by largest collections first and can be saved to a file for review.
This is useful when investigating disk usage growth, storage exhaustion, or identifying which databases and collections are consuming the most space.
The script does the following:
- Loops through all databases
- Retrieves stats for every collection
- Captures collection size, storage size, index size, and total size
- Sorts the results from largest to smallest by total size
- Prints the output in a readable format
Logical uncompressed size of the documents in the collection
Physical space allocated for document storage
Total size of all indexes for the collection
Combined size of collection storage and indexes
Because Swimlane uses WiredTiger, collection data is compressed. As a result, storageSize may be smaller than size.
- Connect to the Mongo shell from the Mongo pod.
kubectl -n $NS exec -i mongo-0 -- mongosh --quiet \
-u Admin \
-p "$(kubectl -n $NS get secret mongo-admin -n default -o jsonpath='{.data.password}' | base64 -d)" \
--authenticationDatabase admin \
--tls \
--tlsAllowInvalidHostnames \
--tlsAllowInvalidCertificates \
admin
- Run the following script:
function getReadableFileSizeString(fileSizeInBytes) {
var i = -1;
var byteUnits = [' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
do {
fileSizeInBytes = fileSizeInBytes / 1024;
i++;
} while (fileSizeInBytes > 1024);
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
}
var dbs = db.getMongo().getDBNames();
var results = [];
dbs.forEach(function(dbName) {
var currentDB = db.getMongo().getDB(dbName);
currentDB.getCollectionNames().forEach(function(collName) {
try {
var s = currentDB.getCollection(collName).stats();
results.push({
ns: s.ns,
count: s.count || 0,
size: s.size || 0,
storageSize: s.storageSize || 0,
totalIndexSize: s.totalIndexSize || 0,
totalSize: (s.storageSize || 0) + (s.totalIndexSize || 0)
});
} catch (e) {
print("Skipping " + dbName + "." + collName + ": " + e);
}
});
});
results.sort(function(a, b) {
return b.totalSize - a.totalSize;
});
results.forEach(function(r) {
print(
r.ns +
" | count=" + r.count +
" | size=" + getReadableFileSizeString(r.size) +
" | storageSize=" + getReadableFileSizeString(r.storageSize) +
" | totalIndexSize=" + getReadableFileSizeString(r.totalIndexSize) +
" | totalSize=" + getReadableFileSizeString(r.totalSize)
);
});
app.records | count=250000 | size=5.2 GB | storageSize=2.8 GB | totalIndexSize=1.4 GB | totalSize=4.2 GB
app.attachments | count=18000 | size=3.6 GB | storageSize=2.1 GB | totalIndexSize=512.0 MB | totalSize=2.6 GB
If you want to save the output to a file, run the command below from the shell instead of entering mongosh interactively:
OUTPUT_FILE="mongo_collection_index_sizes_$(date +%Y%m%d_%H%M%S).txt"
kubectl -n $NS exec -i mongo-0 -- mongosh --quiet \
-u Admin \
-p "$(kubectl -n $NS get secret mongo-admin -n default -o jsonpath='{.data.password}' | base64 -d)" \
--authenticationDatabase admin \
--tls \
--tlsAllowInvalidHostnames \
--tlsAllowInvalidCertificates \
admin <<'EOF' > "$OUTPUT_FILE"
function getReadableFileSizeString(fileSizeInBytes) {
var i = -1;
var byteUnits = [' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
do {
fileSizeInBytes = fileSizeInBytes / 1024;
i++;
} while (fileSizeInBytes > 1024);
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
}
var dbs = db.getMongo().getDBNames();
var results = [];
dbs.forEach(function(dbName) {
var currentDB = db.getMongo().getDB(dbName);
currentDB.getCollectionNames().forEach(function(collName) {
try {
var s = currentDB.getCollection(collName).stats();
results.push({
ns: s.ns,
count: s.count || 0,
size: s.size || 0,
storageSize: s.storageSize || 0,
totalIndexSize: s.totalIndexSize || 0,
totalSize: (s.storageSize || 0) + (s.totalIndexSize || 0)
});
} catch (e) {
print("Skipping " + dbName + "." + collName + ": " + e);
}
});
});
results.sort(function(a, b) {
return b.totalSize - a.totalSize;
});
results.forEach(function(r) {
print(
r.ns +
" | count=" + r.count +
" | size=" + getReadableFileSizeString(r.size) +
" | storageSize=" + getReadableFileSizeString(r.storageSize) +
" | totalIndexSize=" + getReadableFileSizeString(r.totalIndexSize) +
" | totalSize=" + getReadableFileSizeString(r.totalSize)
);
});
EOF
echo "Output saved to $OUTPUT_FILE"
How to interpret the results
Use totalSize as the best quick view of how much space a collection and its indexes are consuming together.
Large size with smaller storageSize
This usually indicates document compression.
This suggests indexes are contributing significantly to disk usage.
Large storageSize with relatively small count
This may indicate larger document payloads or previously allocated space.
- MongoDB disk usage is growing unexpectedly
- The Mongo volume or mount point is nearing full capacity
- You need to identify the largest collections across the environment
- You want to compare document growth versus index growth
Additional recommendation
If disk usage is the main concern, collect this output along with:
This helps correlate MongoDB collection growth with underlying disk and partition usage.