Bird
Raised Fist0
Expressframework~8 mins

Single file upload in Express - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: Single file upload
MEDIUM IMPACT
This affects the page load speed and interaction responsiveness when uploading files through a web form.
Uploading a single file from a client to the server
Express
app.post('/upload', (req, res) => {
  const file = req.files.file;
  // Asynchronously save file
  fs.writeFile(`./uploads/${file.name}`, file.data, (err) => {
    if (err) return res.status(500).send('Upload failed');
    res.send('File uploaded');
  });
});
Asynchronous file saving allows Node.js to handle other requests while saving, improving responsiveness.
📈 Performance GainNon-blocking file save reduces INP and improves server throughput.
Uploading a single file from a client to the server
Express
app.post('/upload', (req, res) => {
  const file = req.files.file;
  // Synchronously save file
  fs.writeFileSync(`./uploads/${file.name}`, file.data);
  res.send('File uploaded');
});
Using synchronous file system operations blocks the Node.js event loop, delaying other requests and slowing response time.
📉 Performance CostBlocks event loop during file save, increasing INP and causing slower server response.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Synchronous file saveMinimal (file input only)00[X] Bad
Asynchronous file saveMinimal (file input only)00[OK] Good
Rendering Pipeline
When a file is uploaded, the browser sends the file data to the server, which processes and saves it. The server's handling affects how quickly it can respond to the client, impacting interaction responsiveness.
Network Transfer
Server Processing
Response Rendering
⚠️ BottleneckServer Processing when using synchronous file operations
Core Web Vital Affected
INP
This affects the page load speed and interaction responsiveness when uploading files through a web form.
Optimization Tips
1Always use asynchronous file handling to avoid blocking the Node.js event loop.
2Keep file upload handling lightweight to improve interaction responsiveness (INP).
3Monitor server response times in DevTools Network tab to detect blocking operations.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance problem with synchronous file saving in Express during file upload?
AIt causes the browser to reflow the page multiple times.
BIt increases the size of the uploaded file.
CIt blocks the Node.js event loop, delaying other requests.
DIt reduces the network bandwidth available.
DevTools: Network
How to check: Open DevTools, go to Network tab, upload a file, and observe the request timing and response time.
What to look for: Look for long server response times indicating blocking operations during upload.

Practice

(1/5)
1. What does upload.single('file') do in an Express app using multer?
easy
A. Uploads multiple files with the form field name 'file'.
B. Validates the file type without uploading.
C. Uploads a single file but does not save it.
D. Handles uploading a single file with the form field name 'file'.

Solution

  1. Step 1: Understand multer's single file upload

    The method upload.single('file') tells multer to accept one file with the field name 'file' from the form.
  2. Step 2: Confirm behavior of single file upload

    This middleware processes the file and attaches its info to req.file, enabling access in the route handler.
  3. Final Answer:

    Handles uploading a single file with the form field name 'file'. -> Option D
  4. Quick Check:

    upload.single('file') = single file upload [OK]
Hint: Remember single() is for one file with given field name [OK]
Common Mistakes:
  • Confusing single() with array() for multiple files
  • Thinking it uploads files without saving
  • Assuming it validates file type automatically
2. Which of the following is the correct syntax to set up multer for single file upload with field name 'avatar'?
easy
A. app.post('/upload', multer.single('avatar'), (req, res) => { ... })
B. app.post('/upload', upload.single('avatar'), (req, res) => { ... })
C. app.post('/upload', multer.upload.single('avatar'), (req, res) => { ... })
D. app.post('/upload', upload.single.avatar(), (req, res) => { ... })

Solution

  1. Step 1: Recognize multer setup pattern

    You first create an upload instance with multer, e.g., const upload = multer({ dest: 'uploads/' }). Then use upload.single('avatar') in route.
  2. Step 2: Identify correct usage in route

    The correct syntax is app.post('/upload', upload.single('avatar'), (req, res) => { ... }). app.post('/upload', upload.single('avatar'), (req, res) => { ... }) matches this.
  3. Final Answer:

    app.post('/upload', upload.single('avatar'), (req, res) => { ... }) -> Option B
  4. Quick Check:

    upload.single('fieldName') = correct syntax [OK]
Hint: Use upload instance, then call single('fieldName') [OK]
Common Mistakes:
  • Calling multer.single() directly without creating upload
  • Using dot notation like single.avatar()
  • Using multer.upload which does not exist
3. Given this Express route using multer:
const upload = multer({ dest: 'uploads/' });
app.post('/profile', upload.single('photo'), (req, res) => {
  res.send(req.file.originalname);
});
What will the server respond with after uploading a file named 'mypic.png'?
medium
A. Undefined
B. The saved filename in 'uploads/' folder
C. 'mypic.png'
D. An error message

Solution

  1. Step 1: Understand req.file properties

    When multer saves a file, req.file contains info including originalname which is the name of the file on the user's computer.
  2. Step 2: Check what is sent in response

    The route sends req.file.originalname, so the response will be the original filename, 'mypic.png'.
  3. Final Answer:

    'mypic.png' -> Option C
  4. Quick Check:

    req.file.originalname = original filename [OK]
Hint: req.file.originalname holds the uploaded file's original name [OK]
Common Mistakes:
  • Confusing originalname with filename (saved name)
  • Expecting req.file to be undefined
  • Assuming response sends saved file path
4. What is wrong with this Express route for single file upload?
const upload = multer({ dest: 'uploads/' });
app.post('/upload', (req, res) => {
  upload.single('file');
  res.send('File uploaded');
});
medium
A. upload.single('file') is not called as middleware, so file is not processed.
B. The destination folder 'uploads/' is missing.
C. The route should use upload.array() for single file.
D. res.send() must be called before upload.single().

Solution

  1. Step 1: Check how multer middleware is used

    The method upload.single('file') must be passed as middleware in the route definition, not just called inside the handler.
  2. Step 2: Identify the mistake in route setup

    Here, upload.single('file') is called but not used as middleware, so multer never processes the file.
  3. Final Answer:

    upload.single('file') is not called as middleware, so file is not processed. -> Option A
  4. Quick Check:

    Use upload.single() as middleware in route [OK]
Hint: Pass upload.single() as middleware, not call inside handler [OK]
Common Mistakes:
  • Calling upload.single() inside route handler instead of middleware
  • Confusing upload.single() with upload.array()
  • Ignoring multer setup before route
5. You want to customize the filename of uploaded files to include the current timestamp before the original name. Which multer storage option correctly achieves this?
hard
A. const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { cb(null, Date.now() + '-' + file.originalname); } });
B. const storage = multer.diskStorage({ destination: (req, file) => 'uploads/', filename: (req, file, cb) => { cb(null, file.originalname); } });
C. const storage = multer.diskStorage({ destination: 'uploads/', filename: (file, cb) => { cb(null, Date.now() + '-' + file.originalname); } });
D. const storage = multer.diskStorage({ destination: 'uploads/', filename: (req, file) => { cb(null, Date.now() + '-' + file.originalname); } });

Solution

  1. Step 1: Understand multer.diskStorage parameters

    The destination can be a string or a function with signature (req, file, cb). The filename must be a function with (req, file, cb).
  2. Step 2: Check each option for correct function signatures

    const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { cb(null, Date.now() + '-' + file.originalname); } }); correctly uses functions for both destination and filename, and sets filename to timestamp + original name.
  3. Final Answer:

    const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { cb(null, Date.now() + '-' + file.originalname); } }); -> Option A
  4. Quick Check:

    Use functions with (req, file, cb) for storage options [OK]
Hint: Use functions with (req, file, cb) to customize storage [OK]
Common Mistakes:
  • Passing destination as string but filename as function missing req
  • Wrong function parameters in filename or destination
  • Not adding timestamp in filename callback