Node.js 멀티파트 파일 업로드 처리 시 메모리 누수 해결

문제 상황

재택근무 전환 이후 사내 파일 공유 시스템의 트래픽이 급증했다. 특히 500MB 이상의 대용량 파일 업로드 시 서버 메모리 사용률이 80%를 넘어가며 다른 요청까지 지연되는 현상이 발생했다.

기존 코드는 multermemoryStorage를 사용하고 있었다.

const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

app.post('/upload', upload.single('file'), (req, res) => {
  // req.file.buffer에 전체 파일이 로드됨
  s3.upload({
    Bucket: 'my-bucket',
    Key: req.file.originalname,
    Body: req.file.buffer
  }, (err, data) => {
    if (err) return res.status(500).send(err);
    res.json({ url: data.Location });
  });
});

해결 과정

  1. diskStorage로 전환: 메모리 대신 임시 디스크에 저장하도록 변경했다.
const storage = multer.diskStorage({
  destination: '/tmp/uploads',
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`);
  }
});
  1. 스트림 방식 업로드: S3 업로드 시 파일을 통째로 읽지 않고 스트림으로 전달했다.
const fs = require('fs');

app.post('/upload', upload.single('file'), (req, res) => {
  const fileStream = fs.createReadStream(req.file.path);
  
  s3.upload({
    Bucket: 'my-bucket',
    Key: req.file.originalname,
    Body: fileStream
  }, (err, data) => {
    fs.unlinkSync(req.file.path); // 임시 파일 삭제
    if (err) return res.status(500).send(err);
    res.json({ url: data.Location });
  });
});

결과

동일한 500MB 파일 업로드 시 메모리 사용량이 기존 대비 70% 감소했다. 동시 업로드 처리량도 3배 증가했다.

임시 파일 정리를 위한 cron job도 추가로 설정해두었다. 디스크 용량 모니터링은 CloudWatch로 진행 중이다.

Node.js 멀티파트 파일 업로드 처리 시 메모리 누수 해결