관리 메뉴

오늘도 더 나은 코드를 작성하였습니까?

개발자가 알아야 하는 숫자1 - Latency Numbers 본문

카테고리 없음

개발자가 알아야 하는 숫자1 - Latency Numbers

hik14 2026. 5. 18. 16:10

작업 1993 (Norvig) 2009 (Jeff Dean) 2012 (SSD 시대) 2024 (NVMe 시대)
L1 캐시 참조 10 ns 0.5 ns 0.5 ns 0.5 ns
분기 예측 실패 5 ns 5 ns 3 ns
L2 캐시 참조 7 ns 7 ns 4 ns
Mutex lock/unlock 100 ns 25 ns 25 ns 17 ns
메인 메모리 참조 200 ns 100 ns 100 ns 80 ns
메모리 1MB 순차 읽기 5,000,000 ns
(5,000 μs)
250,000 ns
(250 μs)
250,000 ns
(250 μs)
100,000 ns
(100 μs)
1KB Zip 압축 3,000 ns (3 μs) 3,000 ns (3 μs) 2,000 ns (2 μs)
1Gbps로 1KB 전송 10,000 ns (10 μs) 10,000 ns (10 μs) 1,000 ns (1 μs, 10Gbps)
SSD 랜덤 읽기 (SATA) 없음 없음 150,000 ns
(150 μs)
100,000 ns
(100 μs)
SSD 랜덤 읽기 (NVMe) 없음 없음 없음 20,000 ns
(20 μs)
SSD 1MB 순차 읽기 없음 없음 1,000,000 ns
(1,000 μs)
50,000 ns
(50 μs, NVMe)
같은 DtatCenter내 RTT 500,000 ns
(500 μs)
500,000 ns
(500 μs)
500,000 ns
(500 μs)
HDD seek 10,000,000 ns
(10,000 μs)
10,000,000 ns
(10,000 μs)
10,000,000 ns
(10,000 μs)
10,000,000 ns
(10,000 μs)
HDD 1MB 순차 읽기 30,000,000 ns
(30,000 μs)
20,000,000 ns
(20,000 μs)
20,000,000 ns
(20,000 μs)
20,000,000 ns
(20,000 μs)
한국 ↔ 미국 RTT 200,000,000 ns
(200,000 μs)
150,000,000 ns
(150,000 μs)
150,000,000 ns
(150,000 μs)
150,000,000 ns
(150,000 μs)

 

중요하게 봐야할 것들

- 관통하는 통찰물리 한계 기반 숫자는 변하지 않는다 (빛의 속도, HDD 회전)

- 기술 기반 숫자만 격변한다 (SSD 등장으로 디스크 500 빨라짐)

- 병목은 사라지지 않고 옮겨간다 (디스크에서 네트워크와 메모리로)

- 정확한 수치보다 자릿수(order of magnitude) 감각이 중요하다

- 표는 항상 만든 시점의 스냅샷시간이 지나면 검증이 필요하다'

자릿수 감각 정리 및 무엇이 중요할까?

계층 단위 비유
L1 캐시 sub-ns 손에 들고 있음
메인 메모리 100 ns 책상 위
NVMe SSD 10~100 μs 같은 방 책장
SATA SSD 100 μs ~ 1 ms 옆방
HDD 10 ms 도서관 가서 찾기
같은 DataCenter 네트워크 500 μs 옆 사무실 전화
대륙 간 RTT 150 ms 해외로 편지

 

메모리 → NVMe SSD는 약 1,000배 차이입니다. 옛날엔 메모리 → HDD가 10만 배였으니, 격차가 100배 줄어든 것.

"RAM이 곧 디스크"라는 말이 어느 정도 농담이 아닌 시대.

 

Android 개발 관점에서 보면, Room에 로컬캐싱하는 이유.

모바일 NVMe(UFS 3.0~4.0)도 랜덤 읽기가 수십μs 수준이라, 네트워크 한 번 다녀오는 것(수십 ms)보다 1000배 빠르다.

*"Room은 디바이스 내부 SQLite를 호출하니까 수 ms 수준(전형적으로 1~10ms, 단순 쿼리는 그보다 빠름)에 끝납니다."

 

이게 "로컬 캐싱이 압도적으로 유리한" 물리적 근거입니다.

작업 시간 의미 1초 기준 환산 체감
메인 메모리 접근 100 ns 가장 빠른 "데이터 가져오기"의 기준점. 모든 비교의 출발점. 1초 손가락 한 번 튕기기
NVMe SSD 랜덤 읽기 20,000 ns
(20μs)
로컬 저장소의 현실. 모바일 UFS도 비슷한 수준. 3분 20초 라면 끓이기
같은 DC 내 RTT 500,000 ns
(500μs)
마이크로서비스, Redis, DB 같은 백엔드 통신의 기준선. 1시간 23분 영화 한 편
한 프레임 (60fps) 16,666,666 ns
(16.6ms)
UI가 안 끊기게 만들 시간 예산. 1일 22시간 주말
모바일 ↔ 서버 RTT 50,000,000 ns
(50ms)
앱 → 서버 호출의 현실. 무선이 추가되는 순간 자릿수가 바뀜. 5일 19시간 휴가 일주일
대륙 간 RTT 150,000,000 ns
(150ms)
글로벌 서비스 설계의 물리적 한계. 17일 8시간 보름 넘게

실무에서 이게 왜 중요한가

1. 마이크로서비스 호출 한 번 = 메모리 접근 5,000번

- 서비스 A가 서비스 B를 HTTP로 호출하면, 같은 DC 안이라도 최소 500μs는 깔립니다. 메모리에서 읽는 것보다 5,000배-6000배 느리다.

- "필요 없는 마이크로서비스 분리는 성능 재앙"

 

2. N+1 쿼리 문제 (서버, 로컬DB)

첫번째, 1번의 쿼리 100개의 게시글 가져오기

두번째, 100번의 쿼리 100개의 게시글의 각 작성자 가져오기.

// 1번째 쿼리: 게시글 100개 가져오기
val posts = postDao.getAllPosts() // SELECT * FROM Post LIMIT 100

// 그 다음 작성자 정보를 가져온다
posts.forEach { post ->
    // 2번째, 3번째, ..., 101번째 쿼리: 매번 작성자 조회
    val author = userDao.getUserById(post.userId) // SELECT * FROM User WHERE id = ?
    println("${post.title} by ${author.name}")
}

 

JOIN 쿼리가 조금 무거운 작업이라도 한 번이면 끝날 일.

 

서버(백앤드)

환경: 앱 서버 ↔ DB 서버가 같은 데이터센터에 있고, 둘 사이는 내부망 네트워크로 통신.

기준 시간: DB 쿼리 1번 ≈ 0.5 ms (DataCenter 내 RTT 500μs + 쿼리 처리 약간)

방식 총 쿼리 수 시간 체감
N+1번 쿼리 1 + 100 = 101번 약 50 ms 느리다고 인식 시작
JOIN 1번 1번 약 0.7 ms 즉각적

약 70배 더 걸림.

안드로이드 로컬 (Room)

환경: 앱 안에서 SQLite를 직접 호출. 네트워크 없음, 디바이스 내부 파일 접근만.

기준 시간: Room 단순 쿼리 1번 ≈ 50~100 μs (네트워크 없음, 디스크 접근 + 소프트웨어 스택)

방식 총 쿼리 수 시간 체감
N+1 1 + 100 = 101번 약 5-10 ms 위험 (프레임의 절반 이상)
JOIN(@Relation) 1번 1번 0.3 ms 여유 있음

약 20~30배 더 걸림.

 

 

3. 캐싱 판단의 기준선

 

"이 데이터를 Redis에 캐싱할 가치가 있나?"의 답이 여기서 나옵니다. Redis도 결국 네트워크(같은 DC RTT)호출이라 500μs 소요된다 그래서 **단순 메모리 캐시(앱 프로세스 내 HashMap)**가 Redis보다 압도적으로 빠릅니다. 다만 여러 서버가 공유해야 한다면 Redis로 가야한다

 

4. 모바일 앱(android native)에서는?

 

Android에서 서버 API 한 번 호출하면 보통 50ms 이상 깔립니다. (무선 구간 + 인터넷 구간 + 서버 처리가 다 포함)

반면 Room은 디바이스 내부 SQLite를 호출하니까 수 ms 수준(전형적으로 1~10ms, 단순 쿼리는 그보다 빠름)에 끝납니다. 무선도, 인터넷도, 서버 부하도 없이 그냥 UFS에서 파일 읽고 객체로 매핑하면 끝이니까요. 같은 데이터를 가져오는 데 자릿수가 한 단계 다른 비용이 들어갑니다. 이게 Single Source of Truth 패턴(네트워크는 백그라운드에서 Room에 동기화, UI는 Room만 본다)이 모던 안드로이드 아키텍처의 표준이 된 정량적 근거입니다.