사용자가 이미지를 올릴 때마다 썸네일을 만들어야 합니다. 이 일로 서버 한 대를 24시간 켜두자니, 정작 일하는 시간은 하루 몇 분뿐 — 나머지는 돈만 먹는 유휴입니다. 반대로 가끔 트래픽이 몰리면 그 한 대로는 부족합니다. "가끔, 갑자기, 짧게" 실행되는 일에 상시 서버는 낭비입니다. 서버리스는 "올라올 때만 실행하고, 동시에 많이 오면 알아서 늘리는" 방식으로 이 틈을 메웁니다.
- 1서버리스가 '서버를 관리하지 않는다'는 의미를 정확히 안다
- 2이벤트 기반 실행과 자동 동시성 확장을 설명할 수 있다
- 3콜드스타트가 무엇이고 언제 문제인지 안다
- 4실행 시간 기반 과금의 손익분기를 판단할 수 있다
- 5서버리스가 맞는 작업과 안 맞는 작업을 구분할 수 있다
이벤트가 올 때만 깨어난다
서버리스 = 서버를 '내가' 관리하지 않는다
서버리스(FaaS)는 서버가 없는 게 아니라, 서버의 프로비저닝·패치·스케일링을 제공자가 가려서 내가 신경 쓸 필요가 없는 모델입니다. PaaS(IaaS·PaaS·SaaS와 리전·AZ)에서 한 발 더 나아가, 이벤트 단위로 실행됩니다.
함수는 트리거(HTTP 요청, 파일 업로드, 큐 메시지, 스케줄)가 올 때 실행되고, 동시 요청 수에 맞춰 인스턴스가 자동으로 늘어납니다. 호출이 없으면 도는 게 없어 비용이 거의 0입니다.

콜드스타트 — 깨어나는 데 드는 시간
한동안 호출이 없으면 실행 환경이 회수됩니다. 그 뒤 첫 호출은 환경을 새로 초기화(런타임·코드 로드, 연결 준비)하느라 평소보다 느립니다 — 이것이 콜드스타트입니다.
배치·웹훅처럼 지연이 덜 중요한 곳은 문제없지만, 사용자 대면 API의 첫 응답이 느리면 체감이 나쁩니다. 완화책: 프로비저닝된 동시성(미리 워밍 유지), 가벼운 런타임, 패키지 크기 축소, VPC 연결 최소화.
과금 — 안 쓰면 0, 항상 바쁘면 비쌀 수도
서버리스는 실행 횟수 + 실행 시간(메모리×시간) 에 비례해 과금합니다. 간헐적 작업은 거의 공짜입니다. 하지만 초당 수천 건이 끊임없이 도는 무거운 워크로드라면 상시 인스턴스보다 비쌀 수 있습니다. 판단 기준은 단순합니다: "가끔 튀는가(서버리스), 항상 바쁜가(인스턴스/컨테이너)".
과금과 성능을 좌우하는 메모리·타임아웃을 확인합니다. 메모리를 올리면 CPU도 함께 올라 더 빨리 끝나 비용이 오히려 줄기도 합니다.
aws lambda get-function-configuration --function-name make-thumbnail \
--query "{Mem:MemorySize,Timeout:Timeout,Runtime:Runtime}"
{ "Mem": 512, "Timeout": 30, "Runtime": "python3.12" }
aws lambda get-function-configuration실행 로그에서 에러와 초기화 지연(Init Duration=콜드스타트)을 봅니다.
aws logs filter-log-events --log-group-name /aws/lambda/make-thumbnail \
--filter-pattern "REPORT" --limit 3 --query "events[].message" --output text
REPORT Duration: 842 ms Init Duration: 410 ms Memory Used: 180 MB ← 콜드스타트
REPORT Duration: 120 ms Memory Used: 178 MB ← 웜
aws logs filter-log-events- REPORT의 Init Duration이 자주 보이면 — 콜드스타트 빈발. 사용자 대면이면 프로비저닝된 동시성·런타임 경량화 검토
- Memory Used가 할당 MemorySize에 한참 못 미치면 — 과할당. 줄여 비용↓ (단 CPU도 함께 줄어 느려질 수 있어 측정 후 조정)
- Timeout에 임박하거나 타임아웃 에러 — 작업이 길어 함수에 부적합할 수 있음. 컨테이너/배치로 분리 검토
- 호출량×평균 Duration 추세 — 상시 고부하로 수렴하면 서버리스 비용이 인스턴스를 넘는 지점인지 재평가
상황: 함수 동시 실행이 폭증하면 각 인스턴스가 DB 커넥션을 열어 DB 커넥션이 고갈됨.
원인: 서버리스는 동시성에 맞춰 함수 인스턴스가 수백~수천 개로 늘 수 있습니다. 각자 DB 커넥션을 직접 열면 관리형 데이터베이스(RDS)의 최대 커넥션을 순식간에 초과합니다. 전통적 커넥션 풀 가정이 깨집니다.
진단: DB의 활성 커넥션 수와 함수 동시 실행 수를 비교 → 함수당 커넥션 사용 패턴 확인.
해결: 함수와 DB 사이에 커넥션 풀 프록시(예: RDS Proxy)를 둬 커넥션을 공유·재사용. 함수 동시성에 상한(reserved concurrency)을 둬 폭주를 막음. 가능하면 함수는 짧게 붙고 빨리 떼게 설계. 커넥션 풀의 원리는 Database 트랙과 이어집니다.
서버리스는 "운영 부담 최소화 + 트래픽 변동 대응"이 필요한 곳에서 강력하지만, 만능이 아닙니다. 면접에서 "왜 서버리스를 썼나/안 썼나"를 트레이드오프로 설명할 수 있어야 합니다 — 콜드스타트, 실행시간 제한, 상시 고부하 시 비용, DB 커넥션 폭주 같은 현실적 제약을 아는지가 핵심입니다.
실무 패턴: 전체를 서버리스로 짓기보다, 간헐적·이벤트성 부분만 서버리스로 떼어내고(이미지 처리, 알림, 정기 배치) 핵심 상시 API는 컨테이너로 두는 혼합이 흔합니다. 이벤트 기반 아키텍처(동기 vs 비동기)와 잘 맞습니다.
다음 모듈에서는 서버리스로는 무거운 상시 워크로드를 담는 또 다른 방식 — 매니지드 컨테이너 서비스(ECS·EKS·Fargate) 를 다룹니다.