OpenAI API 스트리밍 응답 처리 시 메모리 누수 해결

문제 상황

챗봇 서비스에서 OpenAI API의 스트리밍 응답을 사용 중이었는데, 서버 메모리 사용량이 지속적으로 증가하는 현상이 발생했다. 하루에 약 2GB 정도씩 늘어나 주기적으로 재시작이 필요한 상황이었다.

원인 분석

코드를 점검한 결과 스트림 처리 과정에서 reader를 제대로 해제하지 않고 있었다.

// 문제가 있던 코드
const stream = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: messages,
  stream: true,
});

const reader = stream.toReadableStream().getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  // 처리 로직
}

에러 발생 시 reader가 해제되지 않아 메모리에 계속 남아있었다.

해결 방법

try-finally 블록으로 reader를 명시적으로 해제하도록 수정했다.

const stream = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: messages,
  stream: true,
});

const reader = stream.toReadableStream().getReader();
try {
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    // 처리 로직
  }
} finally {
  reader.releaseLock();
}

결과

배포 후 3일간 모니터링한 결과 메모리 사용량이 안정적으로 유지되었다. 평균 메모리 사용량도 기존 대비 30% 정도 감소했다.

스트림 처리 시 리소스 해제는 필수다. 특히 프로덕션 환경에서는 작은 누수도 시간이 지나면 큰 문제가 된다.