[실전 서버리스 20] Workers의 한계, CPU 5분·서브리퀘스트·번들 크기

서버리스가 좋다고 계속 이야기했지만, 한계도 분명히 있다. 이 한계를 모르고 개발하다 벽에 부딪히면 당황한다. 반대로 미리 알면 그 안에서 설계하거나, 한계를 넘는 방법을 준비할 수 있다. 이번 편은 워커스의 주요 한계들, CPU 시간과 서브리퀘스트, 번들 크기 같은 제약을 정리한다.


한계를 아는 건 도구를 제대로 쓰는 첫걸음이다. 무엇이 되고 무엇이 안 되는지의 경계를 알아야 그 안에서 자유롭게 설계할 수 있다.

1. CPU 시간 한계

가장 중요한 한계가 CPU 시간이다. 워커가 한 요청을 처리하며 쓸 수 있는 CPU 시간에 상한이 있다. 무료 요금제는 이 상한이 매우 짧고, 유료 요금제는 기본 상한이 넉넉하며 설정으로 더 늘릴 수도 있다. 그래도 무한은 아니라, 무거운 연산은 이 한계에 부딪힐 수 있다.


여기서 중요한 건 CPU 시간과 전체 처리 시간이 다르다는 점이다. 앞서 다뤘듯 데이터베이스나 외부 서비스를 기다리는 시간은 CPU 시간에 안 든다. 기다리는 동안은 CPU가 놀기 때문이다. 그래서 실제 연산이 짧고 기다림이 긴 웹 요청은 대체로 이 한계에 안 걸린다. 문제는 실제 연산이 무거운 경우다.


이미지 처리나 복잡한 계산처럼 CPU를 많이 쓰는 작업이 한계에 걸린다. 이런 건 앞서 다룬 큐로 넘겨 뒤에서 처리하거나, 작업을 나눠 여러 요청으로 분산하는 식으로 우회한다. 또는 정말 무거운 연산은 서버리스가 아닌 다른 방식을 고려한다. CPU 한계를 알면 어떤 작업을 어떻게 처리할지 미리 설계할 수 있다.


CPU 시간 한계가 가장 중요한 제약이다. 다만 데이터베이스나 외부 서비스를 기다리는 시간은 CPU 시간에 안 들어서, 실제 연산이 짧고 기다림이 긴 웹 요청은 대체로 이 한계에 안 걸린다. 문제는 이미지 처리나 복잡한 계산처럼 실제 CPU를 많이 쓰는 작업이다. 이런 건 큐로 넘기거나 나눠서 우회한다.


조금 더 배경을 주면, 한계를 아는 건 도구를 제대로 쓰는 첫걸음이다. 무엇이 되고 무엇이 안 되는지의 경계를 알아야 그 안에서 자유롭게 설계할 수 있다. 한계를 모르고 개발하다 벽에 부딪히면 당황하지만, 미리 알면 그 안에서 설계하거나 넘는 방법을 준비한다. 제약을 아는 게 오히려 자유를 준다.


한 가지 더, 한계에 부딪혔을 때 그게 정말 한계인지 설계 문제인지 구분해야 한다. 많은 경우 한계처럼 보이는 게 실은 비효율적 설계다. 무거운 연산을 요청 안에서 하려니 CPU 한계에 걸리는 거라면, 그건 한계가 아니라 큐로 넘겨야 할 신호다. 한계에 부딪히면 우회하기 전에, 설계를 먼저 돌아보는 게 순서다.

2. 시작 시간 한계

또 하나가 시작 시간이다. 워커의 전역 스코프, 즉 핸들러 밖의 최상위 코드는 1초 안에 실행돼야 한다. 이걸 넘으면 배포가 거부된다. 앞서 다룬 것처럼, 무거운 초기화를 전역에서 하면 이 한계에 걸린다.


그래서 무거운 초기화는 전역이 아니라 핸들러 안에서, 필요할 때 하는 게 원칙이다. 전역에는 가벼운 준비만 두고, 실제 무거운 작업은 요청이 왔을 때 처리한다. 이렇게 하면 시작 시간 한계를 피하면서도 필요한 초기화를 할 수 있다. 무엇을 전역에 두고 무엇을 핸들러에 둘지 구분하는 게 중요하다.


이 시작 시간 한계는 콜드 스타트가 빠른 것과 관련이 있다. 앞서 다뤘듯 워커가 밀리초 단위로 빠르게 시작하는데, 이게 가능하려면 시작 코드가 가벼워야 한다. 그래서 시작 시간에 제한을 두는 것이다. 빠른 콜드 스타트의 대가로 시작 코드를 가볍게 유지해야 하는 제약이다.


시작 시간 한계는 전역 코드를 가볍게 하라는 제약이다. 핸들러 밖 최상위 코드는 1초 안에 실행돼야 하니, 무거운 초기화는 전역이 아니라 핸들러 안에서 필요할 때 한다. 이건 빠른 콜드 스타트의 대가다. 워커가 밀리초 단위로 시작하려면 시작 코드가 가벼워야 하고, 그래서 이 제한을 두는 것이다.

3. 서브리퀘스트 한계

서브리퀘스트는 워커가 요청을 처리하며 외부로 보내는 요청이다. 데이터베이스 조회, 스토리지 접근, 외부 API 호출 같은 게 다 서브리퀘스트다. 한 요청을 처리하며 보낼 수 있는 서브리퀘스트 수에 한계가 있다. 예전엔 이 한계가 낮았는데, 최근 크게 늘었다.


이 한계가 늘어난 게 반가운 변화다. 예전엔 한 요청에서 외부 호출을 많이 하는 작업이 이 한계에 걸렸는데, 이제 상한이 훨씬 높아져 여유가 생겼다. 그래도 무한은 아니라, 한 요청에서 지나치게 많은 외부 호출을 하는 구조는 여전히 조심해야 한다. 대량의 외부 호출이 필요하면 큐로 나누는 걸 고려한다.


서브리퀘스트 한계를 의식하면 코드 구조가 달라진다. 한 요청에서 데이터베이스를 수십 번 조회하는 대신, 한 번에 필요한 걸 다 가져오게 쿼리를 짜는 식이다. 이건 성능에도 좋다. 외부 호출을 줄이면 그만큼 응답이 빨라진다. 한계가 좋은 설계를 유도하는 셈이다.


서브리퀘스트 한계는 최근 크게 늘어 여유가 생겼다. 예전엔 한 요청에서 외부 호출을 많이 하면 걸렸는데, 이제 상한이 훨씬 높다. 그래도 무한은 아니라, 한 요청에서 데이터베이스를 수십 번 조회하기보다 한 번에 필요한 걸 다 가져오게 짜는 게 좋다. 이건 한계를 피하는 동시에 성능에도 이롭다.


조금 더 실무적으로, 서브리퀘스트를 줄이면 성능도 좋아진다. 한 요청에서 외부 호출을 적게 할수록 응답이 빠르다. 그래서 데이터베이스를 여러 번 조회하기보다 한 번에 필요한 걸 다 가져오게 쿼리를 짜는 게 좋다. 한계를 의식하는 게 자연스럽게 좋은 설계로 이어진다. 제약이 좋은 습관을 유도하는 셈이다.

4. 번들 크기 한계

번들 크기는 배포하는 코드의 크기다. 워커로 올리는 코드에 크기 제한이 있다. 무료 요금제는 작고, 유료 요금제는 더 크다. 대부분의 워커는 이 한계에 안 걸리지만, 큰 라이브러리를 많이 넣으면 부딪힐 수 있다.


그래서 번들을 가볍게 유지하는 게 좋다. 꼭 필요한 라이브러리만 넣고, 무거운 의존성은 피한다. 앞서 다룬 경량 라우팅 프레임워크를 권한 것도 이 때문이다. 워커스 환경에 최적화된 가벼운 도구를 쓰면 번들이 작게 유지된다. 무거운 프레임워크를 통째로 올리면 번들이 커진다.


번들이 작으면 배포도 빠르고 시작도 빠르다. 앞서 다룬 빠른 콜드 스타트도 번들이 가벼워야 유지된다. 그래서 번들 크기는 단순한 한계가 아니라 성능과도 연결된다. 가벼운 번들을 지향하는 게 한계를 피하는 동시에 성능을 챙기는 길이다.


번들 크기 한계는 코드를 가볍게 유지하라는 제약이다. 꼭 필요한 라이브러리만 넣고 무거운 의존성은 피한다. 경량 프레임워크를 권한 것도 이 때문이다. 번들이 작으면 배포도 빠르고 시작도 빠르다. 그래서 번들 크기는 단순한 한계가 아니라 성능과도 연결된다. 가벼운 번들이 한계를 피하고 성능을 챙긴다.

5. 한계를 알고 설계한다

이 한계들을 알면 서버리스로 무엇을 어떻게 할지 판단할 수 있다. CPU를 많이 쓰는 무거운 연산, 오래 걸리는 작업, 대량의 외부 호출 같은 건 그대로 하면 한계에 걸리니, 큐로 나누거나 다른 방식을 쓴다. 반면 짧고 가벼운 요청은 서버리스에 딱 맞는다.


중요한 건 한계를 단점으로만 보지 않는 것이다. 이 한계들은 빠른 콜드 스타트와 저렴한 비용을 위한 대가이기도 하다. 가벼운 실행 단위라 빠르고 싼 대신, 무거운 작업엔 제약이 있는 것이다. 이 교환을 이해하면, 서버리스의 강점을 살리면서 한계를 우회하는 설계를 할 수 있다.


정리하면 워커스에는 CPU 시간, 시작 시간, 서브리퀘스트, 번들 크기 같은 한계가 있고, 이건 빠름과 저렴함의 대가이며, 알고 설계하면 그 안에서 자유롭게 만들 수 있다. 다음 편에서는 이 한계를 넘어 실제로 비용이 튀는 상황, 즉 비용 폭탄을 피하는 법을 실전 사례로 다룬다.


한계를 알고 설계한다는 게 이 편의 결론이다. 이 한계들은 단점이 아니라 빠른 콜드 스타트와 저렴한 비용을 위한 대가다. 가벼운 실행 단위라 빠르고 싼 대신 무거운 작업엔 제약이 있는 것이다. 이 교환을 이해하면, 짧고 가벼운 요청은 서버리스로, 무거운 건 큐나 다른 방식으로 나눠 설계할 수 있다.


또 하나, 이 한계들은 시간이 지나며 완화되기도 한다. 실제로 서브리퀘스트 한계는 최근 크게 늘었다. 플랫폼이 발전하며 제약이 느슨해지는 것이다. 그래서 지금의 한계를 절대적으로 여기기보다, 플랫폼의 변화를 주기적으로 확인하는 게 좋다. 예전에 안 되던 게 지금은 되는 경우가 있다.


다음 편에서는 이 한계를 넘어 실제로 비용이 튀는 상황, 즉 비용 폭탄을 피하는 법을 실전 사례로 다룬다. 서버리스가 저렴하다는 게 방심의 이유가 되지 않게, 어디서 비용이 나는지를 짚는다.