title: Node JS Slow upload with Multer
body: <p>I'm working on a project with an instance (my test server) with Docker.</p>
  
  <p>I have actually a client (front of upload app) and an api with Node JS and multer storage and Google Cloud Storage.</p>
  
  <p>My Database is a ReplicaSet of 3 containers MongoDB (1 primary and 2 secondary).</p>
  
  <p>The problem is during the upload, the process is very long (POST 17sec).</p>
  
  <p>My strategy is to store the informations of the file (png, pdf, jpeg...) in my mongoDB Database, and store the file on a filesystem mounted to my api container.
  If the file is an image, then we resize it to a thumbmail and store it in the filesystem, update the document path in mongodb, upload to Google Cloud Storage the file (original size) and delete it to the local.</p>
  
  <p>But all of this process with my code is very long.</p>
  
  <pre><code>// Enable Storage
  const gcs = gcloud.storage({
      projectId: 'myprojectid',
      keyFilename: 'mykeyfilename',
  });
  
  // environments Variables
  let clientUrl;
  let smtpTransport;
  let bucket;
  
  
   bucket = gcs.bucket('mybucket');
  
   module.exports = {
  
      async create(req, res) {
          const upload = multer({
              storage: multer.diskStorage({
                  destination: (req, file, callback) =&gt; {
                      const client = JSON.parse(req.body.client);
                      const companyName = client.company_name;
                      const type = file.mimetype.split('/')[1];
                      const path = `./uploads/${companyName}/${type}`;
                      fs.mkdirsSync(path);
                      callback(null, path);
                  },
                  filename: (req, file, callback) =&gt; {
                      // originalname is the uploaded file's name with extn
                      callback(null, `${Date.now()}_${file.originalname}`);
                  },
              }),
              limits: {
                  fileSize: 500000000, // 500mb max
              },
          }).array('document');
  
          try {
              await upload(req, res, async () =&gt; {
                  let addedBy;
                  const docs = [];
  
                  const userTypeJwt = extractTypeUserJwt(req);
  
                  if (userTypeJwt === 'admins') {
                      addedBy = 'admin';
                  } else {
                      addedBy = 'client';
                  }
  
                  const client = JSON.parse(req.body.client);
  
                  req.files.forEach(async (file) =&gt; {
                      try {
                          const doc = await Document.create({
                              filename: file.originalname,
                              client: {
                                  client_id: client._id,
                                  company_name: client.company_name,
                                  firstname: client.firstname,
                                  lastname: client.lastname,
                                  email: client.email,
                              },
                              added_by: addedBy,
                              mimetype: file.mimetype,
                              path: file.path,
                              size: file.size,
                          });
                          docs.push(doc);
  
                          /**
                           * Resizing de l'image originel
                           *
                           * Puis update path du document dans la base de donnée
                           */
                          const resizedPath = await imgProc(file, client.company_name);
                          await doc.update({
                              path: resizedPath,
                          });
  
                          /**
                           * Vérification image ?
                           *
                           * Si oui, upload de l'image originel sur le google cloud storage
                           *
                           * Suppression du fichier origine sur le local
                           */
                          if (file.mimetype.split('/')[0] === 'image') {
                              await bucket.upload(file.path);
                              console.log('File uploaded to Google cloud Storage');
                              await fs.unlink(file.path);
                              console.log('File deleted from local');
                          }
                      } catch (err) {
                          console.log(err);
                      }
                  });
  
                  if (addedBy === 'client') {
                      const mailOptions = {
                          to: config.contact_email,
                          from: config.contact_email,
                          subject: `${client.company_name} a uploadé dans son Espace`,
                          template: 'client_upload',
                          context: {
                              company_name: client.company_name,
                              docs,
                          },
                      };
  
                      try {
                          await smtpTransport.use('compile', mailerhbs({
                              viewPath: 'templates/emails',
                              extName: '.hbs',
                          }));
                          await smtpTransport.sendMail(mailOptions);
                          console.log('Send mail to mysmail@mail.com...');
                      } catch (err) {
                          console.log(err);
                      }
                  }
  
                  res.json({ success: true, message: 'Document(s) successfuly uploaded.' });
              });
          } catch (err) {
              console.log(err);
          }
      },
  </code></pre>