MongoDB GridFS
A single MongoDB document can hold up to 16 megabytes. Photos, videos, audio recordings, and large PDF files often exceed that limit. GridFS is a MongoDB feature that stores large files by cutting them into small pieces and saving each piece as its own document.
The Jigsaw Puzzle Picture
Imagine a large poster that does not fit in a small drawer. Cut it into puzzle pieces, number each piece, and store the pieces in the drawer. A list card records the poster name and the number of pieces. Later, you collect the pieces in order and rebuild the poster.
Large file: movie.mp4 (50 MB)
|
v split into chunks of 255 KB
+-------+-------+-------+-------+-----+
| n = 0 | n = 1 | n = 2 | n = 3 | ... | stored in fs.chunks
+-------+-------+-------+-------+-----+
^
| described by one record in fs.files
{ filename: "movie.mp4", length: 52428800, chunkSize: 261120, uploadDate: ... }How GridFS Stores Data
GridFS uses two collections inside a database. The default bucket name is fs.
| Collection | Content |
|---|---|
| fs.files | One document for each file, with the name, size, upload date, and optional metadata |
| fs.chunks | Many documents for each file, each holding one numbered piece of the binary data |
The default chunk size is 255 kilobytes. Each chunk document links to its file through the files_id field and carries a sequence number in the field n.
When to Use GridFS
Good Fits
- Files larger than 16 megabytes, such as videos and large archives.
- Files that applications read in parts, such as streaming a section of an audio file.
- Projects that want file data and file details in the same database, with the same backup and replication rules.
Weaker Fits
- Small files under 16 megabytes. Store these directly inside a document as binary data.
- Files that change often in part. GridFS replaces a whole file instead of editing a piece of it.
- Very large media libraries that need worldwide delivery. Dedicated file storage services often suit those cases better.
Use GridFS from the Command Line
The mongofiles tool belongs to the MongoDB Database Tools and works from a normal terminal:
mongofiles --db=media put holiday.mp4
mongofiles --db=media list
mongofiles --db=media get holiday.mp4
mongofiles --db=media delete holiday.mp4putuploads a file.listshows the stored files.getdownloads a file to the current folder.deleteremoves the file and all its chunks.
Use GridFS in Node.js
The official driver includes the GridFSBucket class.
Upload a File
const { MongoClient, GridFSBucket } = require("mongodb");
const fs = require("fs");
const client = new MongoClient(process.env.MONGODB_URI);
await client.connect();
const db = client.db("media");
const bucket = new GridFSBucket(db);
fs.createReadStream("./holiday.mp4")
.pipe(bucket.openUploadStream("holiday.mp4", { metadata: { owner: "Asha", type: "video" } }))
.on("finish", function () {
console.log("Upload complete");
});A stream sends the file in small pieces, so memory use stays low even for huge files.
Download a File
bucket.openDownloadStreamByName("holiday.mp4")
.pipe(fs.createWriteStream("./copy-of-holiday.mp4"))
.on("finish", function () {
console.log("Download complete");
});Delete a File
const file = await db.collection("fs.files").findOne({ filename: "holiday.mp4" });
await bucket.delete(file._id);Search for Files
The fs.files collection works like any other collection, so normal queries find files by name, size, or metadata:
db.fs.files.find({ "metadata.owner": "Asha" })
db.fs.files.find({ length: { $gt: 10485760 } })The second query finds files larger than 10 megabytes.
Speed and Safety Tips
- Create an index on
metadata.owneror other fields that your searches use often. - Keep the default chunk size unless testing proves that a different size helps.
- Store the file name, type, and owner in the metadata field for easy searching.
- Check file types and sizes before accepting uploads from users.
- Remember that backups grow with the stored files, so plan disk space accordingly.
Summary
GridFS stores files larger than the 16 megabyte document limit by splitting them into chunks. The fs.files collection keeps the file details, and the fs.chunks collection keeps the binary pieces. The mongofiles tool and the GridFSBucket class in drivers upload, download, and delete files through streams. Choose GridFS for large or partly read files, and store small files directly in documents.
