콘텐츠로 이동

API 응답속도 개선 체크리스트 — 느린 API 빠르게 만들기

“API가 느리다”는 민원을 받았을 때 어디서부터 확인해야 할지 막막하다면, 이 체크리스트를 순서대로 따라가세요.

1. DB 쿼리 (원인의 80%)
2. 외부 API 호출
3. 캐시 부재
4. 불필요한 데이터 처리
5. 인프라 리소스

□ N+1 쿼리가 없는가?
→ APM에서 DB Span이 수십~수백 개이면 N+1 의심
→ ORM의 eager loading / JOIN으로 해결
□ 느린 쿼리에 인덱스가 있는가?
→ EXPLAIN ANALYZE로 Seq Scan 확인
→ WHERE, JOIN, ORDER BY 컬럼에 인덱스 추가
□ 필요한 컬럼만 SELECT하는가?
→ SELECT * 대신 SELECT id, name, email
→ 응답 데이터 크기 감소
□ 페이지네이션을 사용하는가?
→ 전체 데이터를 한 번에 로드하지 않기
-- 나쁜 예: 전체 로드
SELECT * FROM orders WHERE user_id = 123;
-- 좋은 예: 페이지네이션 + 필요한 컬럼만
SELECT id, total, status, created_at
FROM orders
WHERE user_id = 123
ORDER BY created_at DESC
LIMIT 20 OFFSET 0;
□ 자주 조회되고 잘 변하지 않는 데이터에 캐시 적용됐는가?
→ 상품 목록, 카테고리, 설정 데이터 등
□ DB 결과를 Redis에 캐시하는가?
□ TTL이 설정돼 있는가? (만료 없는 캐시 금지)
□ 캐시 히트율을 모니터링하는가?
# Redis 캐시 적용 예시
def get_product(product_id: int):
cache_key = f"product:{product_id}"
# 캐시 확인
cached = redis.get(cache_key)
if cached:
return json.loads(cached) # 캐시 히트
# DB 조회
product = db.query(Product).get(product_id)
# 캐시 저장 (1시간 TTL)
redis.setex(cache_key, 3600, json.dumps(product.to_dict()))
return product
□ 응답에 불필요한 동기 작업이 포함돼 있는가?
→ 이메일 발송, 알림, 로그 기록은 비동기로 분리
□ 독립적인 외부 API 호출을 병렬로 실행하는가?
# 나쁜 예: 순차 호출 (합산 지연)
user = await get_user(user_id) # 50ms
orders = await get_orders(user_id) # 80ms
recommendations = await get_recs(user_id) # 120ms
# 총 250ms
# 좋은 예: 병렬 호출
user, orders, recommendations = await asyncio.gather(
get_user(user_id),
get_orders(user_id),
get_recs(user_id),
)
# 총 ~120ms (가장 느린 것 기준)
□ 응답에 불필요한 필드가 포함돼 있는가?
→ 클라이언트가 사용하지 않는 필드 제거
□ 응답 압축(gzip/br)이 활성화돼 있는가?
□ JSON 직렬화 성능이 병목은 아닌가?
# FastAPI gzip 미들웨어
from fastapi.middleware.gzip import GZipMiddleware
app.add_middleware(GZipMiddleware, minimum_size=1000)
# Nginx gzip 설정
gzip on;
gzip_types application/json text/plain;
gzip_min_length 1000;
□ HTTP/2가 활성화돼 있는가?
→ 멀티플렉싱으로 동시 요청 처리 향상
□ Keep-Alive가 설정돼 있는가?
→ 매 요청마다 TCP 연결을 새로 맺지 않도록
□ CDN을 사용하는가?
→ 정적 파일, 이미지는 CDN으로 분리
□ 서버 리소스(CPU, 메모리)가 포화 상태인가?
□ DB 커넥션 풀이 고갈되진 않는가?
□ 같은 리전에 배포됐는가? (DB-서버 간 레이턴시 확인)

최적화 전후를 반드시 측정해서 효과를 검증하세요.

Terminal window
# k6로 before/after 측정
k6 run --out json=before.json test.js
# 최적화 적용
k6 run --out json=after.json test.js
# p95 비교
python scripts/compare_baseline.py
visitor count

이 가이드를 내 서비스에 직접 적용해 보세요.

TestForge 무료 스캔 시작 →