BackendNode.jsMulterCloudinaryFile UploadExpress

File Upload with Multer and Cloudinary in Node.js

Implement secure file uploads in Node.js using Multer for handling multipart form data and Cloudinary for cloud image storage.

Abdur Razzak

Abdur Razzak

Full-Stack Web Developer

March 16, 2025 10 min read

The File Upload Architecture

File uploads in production should never store files on your application server — server storage is ephemeral in containerized environments and does not scale horizontally. The correct architecture: receive the file in Node.js with Multer (in memory or temp disk), upload it to a cloud storage service like Cloudinary or AWS S3, and store only the returned URL in your database. Your application server stays stateless.

Setting Up Multer

Install multer and configure it with your storage engine. For Cloudinary uploads, use multer's memory storage (multer.memoryStorage()) — this stores the file buffer in memory rather than writing to disk. Configure file size limits with limits: { fileSize: 5 * 1024 * 1024 } for a 5MB limit. Use fileFilter to whitelist allowed MIME types and reject non-image files before they reach your route handler.

Uploading to Cloudinary

Install cloudinary and configure it with your API key, secret, and cloud name from environment variables. Use a promisified upload stream to upload the file buffer from Multer's memory storage: cloudinary.uploader.upload_stream({folder: 'uploads'}, callback). The callback receives the Cloudinary response with the secure_url, public_id, width, height, and format of the uploaded file.

Cloudinary Image Transformations

Cloudinary can transform images on the fly via URL parameters — no server-side processing needed. Append /w_300,h_300,c_fill/ to an image URL to resize and crop it to 300x300. Use /f_auto,q_auto/ to automatically serve WebP/AVIF format with optimal quality settings. These transformations are cached at Cloudinary's CDN, so subsequent requests are served instantly without re-processing.

Deleting Files from Cloudinary

When a user replaces or deletes an image, delete the old file from Cloudinary using cloudinary.uploader.destroy(publicId) to avoid orphaned files consuming storage. Store the Cloudinary public_id alongside the URL in your database for this purpose. For bulk operations or cleanup, use Cloudinary's admin API to list and delete assets by folder or tag.

Security Best Practices for File Uploads

Never trust the client-provided MIME type — validate file types by checking the file's magic bytes (file signature) rather than the Content-Type header. Scan uploaded images with a library like sharp to process and re-encode them, which strips any malicious payloads embedded in image files. Rate limit your upload endpoint to prevent abuse. Require authentication before accepting any file upload.

Share this article

All posts
#Node.js#Multer#Cloudinary#File Upload#Express
Abdur Razzak — Full Stack Web Developer

Let's Connect

Follow My Developer Journey