버퍼(Buffer), 스트림(Stream), 스로틀(Throttle)의 목적과 처리 방식을 실무 예시와 함께 정리
버퍼·스트림·스로틀의 장단점과 사용처를 표와 예시로 정리
실전 코드·아키텍처에서의 적용 팁 포함
* 결론~
| 구분 | 버퍼(Buffer) | 스트림(Stream) | 스로틀(Throttle) |
| 목적 | 속도 차이 완충 | 연속 데이터 처리 | 처리 빈도 제한 |
| 핵심 역할 | 임시 저장 | 순차 처리 | 요청 제어 |
| 데이터 저장 | O (임시 저장) | △ (필요 최소한) | X |
| 처리 방식 | 쌓아두고 처리 | 들어오는 즉시 처리 | 일정 시간당 처리 제한 |
| 주 사용처 | 네트워크, I/O, 메시지 큐 | 대용량 데이터, 실시간 처리 | 이벤트, API, UI 제어 |
| 장점 | 안정성, 유실 방지 | 메모리 효율, 실시간성 | 시스템 보호 |
| 단점 | 메모리 초과 위험 | 역압(backpressure) 필요 | 데이터 손실 가능 |
| 대표 예시 | Kafka, TCP Buffer | Node Stream, 파일 다운로드 | Scroll Throttle, Rate Limit |
목차
- 버퍼의 개념
- 버퍼의 동작 방식
- 환경 별 버퍼의 저장 위치
- 버퍼에 데이터 유입 시 실제 흐름(네트워크 예시)
- 프론트엔드에서의 버퍼 처리
버퍼
개념
- 정의 : 데이터를 일시적으로 저장해 두는 공간
- 목적 : 처리 속도 차이 완충
- 위치 : 메인 스레드의 메모리 / Worker 내부 메모리
- 사용 이유 : 실시간 데이터 폭주 대응
- 입력은 빠른데 처리가 느린 경우
- 네트워크 / I/O 지연이 발생하는 경우
- 데이터 손실 없이 안정적으로 처리해야 하는 경우
버퍼의 본질 “ 어디에 저장 되는가”
- 추상적인 메모리가 아니라 항상 실제 메모리 공간에 존재함
- 환경에 따라 위치와 주체가 달라질 뿐
- 공통 원칙
- 버퍼 = RAM 상의 메모리 영역
- 디스크가 아니라 메모리
- 누가 관리하느냐에 따라 구분
동작 방식
- 데이터가 들어오면 즉시 버퍼에 저장
- 소비자는 자신의 처리 속도에 맞춰 버퍼에서 데이터를 꺼냄
- 버퍼가 가득 차면
- 대기
- 오래된 데이터 삭제
- 에러 발생
- 예시
- 네트워크 패킷 버퍼
- 파일 I/O 버퍼
- kafka의 파티션 로그
- 영상 스트리밍의 미리 로딩 영역
환경 별 버퍼 저장 위치
OS 레벨 버퍼
- 운영체제가 관리
- 네트워크 수신 버퍼(TCP Receive Buffer)
- 파일 읽기/쓰기 버퍼
- 커널 영역 메모리
- 특징
- 애플리케이션은 직접 접근 불가
- 시스템 콜을 통해서만 사용
- 매우 빠르지만 크기 제한 존재
런타임 레벨 버퍼
- JAVA / Node.js 등
- 언어 런타임이 관리
- Java: byte[], ByteBuffer
- Node.js: Buffer, ReadableStream internal buffer
- 특징
- 힙 메모리 또는 네이티브 메모리
- 개발자가 제어 가능
- GC 또는 런타임 정책 영향 받음
애플리케이션 레벨 버퍼
- 개발자가 직접 구현
- 배열
- 큐
- Ring Buffer
- 상태 저장소(Redux, Zustand 등)
- 특징
- 가장 많이 쓰임
- 로직에 맞게 자유롭게 설계 가능
- 메모리 관리 책임도 개발자에게 있음
데이터 유입 시 실제 흐름 (네트워크 기준)
- [네트워크] ↓ [OS 네트워크 버퍼] ↓ [런타임 버퍼] ↓ [애플리케이션 버퍼] ↓ [비즈니스 로직 처리]
- OS 버퍼를 거친다!
프론트 엔드에서의 버퍼 처리
구분 내용
| 저장 위치 | JS Heap (브라우저 메모리) |
| 구현 방식 | 배열, 큐, 링버퍼 |
| 주 사용처 | WebSocket, 이벤트, 스트림 처리 |
| 초과 정책 | 삭제, 덮어쓰기, 대기 |
| 주의점 | 메모리 누수, 렌더 성능 |
배열
const buffer: Message[] = [];
socket.onmessage = (event) => {
buffer.push(JSON.parse(event.data));
};
- 가장 단순한 버퍼
- 메모리 : 브라우저 JS Heap
- 문제점 : 무한 증가 위험
제한 크기 버퍼 (고정 버퍼)
const MAX_BUFFER_SIZE = 1000;
const buffer: Message[] = [];
function pushBuffer(data: Message) {
if (buffer.length >= MAX_BUFFER_SIZE) {
buffer.shift(); // 오래된 데이터 제거
}
buffer.push(data);
}
- 정책
- 최신 데이터 우선
- 실시간 UI에 자주 사용
큐 기반 버퍼 (처리용)
const queue: Message[] = [];
let isProcessing = false;
function enqueue(data: Message) {
queue.push(data);
process();
}
async function process() {
if (isProcessing) return;
isProcessing = true;
while (queue.length > 0) {
const item = queue.shift()!;
await handle(item);
}
isProcessing = false;
}
- 특징
- 생산자/소비자 모델
- 서버 데이터 처리, 배치 처리에 적합
WebSocket + 버퍼 + 렌더링 분리
const socketBuffer: Tick[] = [];
let rafId: number;
socket.onmessage = e => {
socketBuffer.push(JSON.parse(e.data));
};
function render() {
const data = socketBuffer.splice(0, socketBuffer.length);
updateChart(data);
rafId = requestAnimationFrame(render);
}
render();
- 장점
- 수신과 렌더 분리
- 프레임 드랍 방지
브라우저 내부 스트림 버퍼
- Fetch Stream
- 브라우저가 내부적으로 버퍼 관리
- 개발자는 흐름만 소비
- const response = await fetch(url); const reader = response.body!.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; process(value); // 내부 버퍼에서 chunk 단위 제공 }
상태관리 도구도 버퍼일까
- Redux 느 RTK Query 모두 서버 응답 결과를 메모리에 캐시함
- 시간 기준으로 보면 버퍼 + 캐시 의 혼합
- 버퍼는 일시적으로 사용하고 캐시는 재 사용 목적으로 사용하는 것
'개발지식' 카테고리의 다른 글
| [개발지식] 온라인 통신 - SSE Server-sent Events_온라인 통신을 위한 “서버 → 클라이언트 스트림” (0) | 2026.01.21 |
|---|---|
| [개발지식] 온라인 통신 - 웹소켓 - 온라인 통신을 위한 “양방향 채널” (0) | 2026.01.21 |
| [개발지식] 온라인 통신 - 웹 통신(HTTP 기반)과 온라인 통신(실시간 통신)의 비교 (0) | 2026.01.21 |
| [개발지식] 메시지 Message - 서로 다른 컨텍스트 끼리 데이터 주고 받는 프로토콜 (0) | 2026.01.21 |
| [개발지식] 웹 워커 web Worker 와 서비스 워커 service Worker - 프론트엔드 대용량 데이터 처리 방식 (0) | 2026.01.21 |