재우니 개발자 블로그

 

IS + ASP.NET Core 8 환경에서의 Application Pool 튜닝 전략을 최신 기준으로 재정리한 기술 블로그 글입니다.
불필요한 과장은 제거하고, 실무 중심·이론 근거·최신 운영 패턴이 일관되게 잡히도록 구성했습니다.


IIS에서 ASP.NET Core 8 운영 시 Application Pool 설정 최적화 가이드

– AlwaysRunning, Idle Timeout, Preload, Recycle까지 완전 정리 –

 

운영 환경에서 ASP.NET Core 기반 웹서비스를 IIS 위에서 구동할 때, 서비스 첫 요청 시 응답이 지연되거나 아침 시간대 Gateway Timeout 문제가 발생하는 경우가 자주 보고된다. 이는 대부분 Application Pool의 기본 동작 모델과 서비스의 유휴 상태 전환(Idle Timeout) 때문에 발생한다.

 

이 글에서는 최신 기준(2025년)으로, IIS의 동작 메커니즘을 올바르게 이해하고 실무적으로 가장 안정적인 설정 전략을 정리했다.


1. 웹서비스가 첫 요청에서 느려지는 이유

IIS는 트래픽이 일정 시간 발생하지 않으면 Application Pool을 Idle 상태로 전환한다.
Idle 종료 또는 Suspend 상태에서는 서비스가 Cold Start를 수행해야 한다.

 

Cold Start가 영향을 주는 요소:

  • ASP.NET Core In-Process 초기화
  • Kestrel 프로세스 생성(Out-of-Process)
  • DI 초기화, Entity Framework 연결
  • 캐시 준비, Config 로딩

 

AWS ALB·CloudFront·WAF 같은 네트워크 구성에서는 백엔드에서 Cold Start가 1~5초 이상 걸리면 바로 504 Gateway Timeout이 발생할 수 있다.

따라서 “첫 요청 딜레이”는 IIS 기본 설정이 만든 구조적 현상이다.

 


2. AlwaysRunning vs Idle Timeout — 가장 많이 오해한 지점

❌ 잘못된 정보

"AlwaysRunning을 설정하면 Idle Timeout은 자동으로 비활성화된다."

 

✔ 실제 사실

AlwaysRunning과 Idle Timeout은 서로 독립적이다.
AlwaysRunning을 켜도 Idle Timeout은 정상 동작하며 프로세스는 여전히 종료된다.

Microsoft 공식 문서에서도 다음이 명시되어 있다:

AlwaysRunning을 사용하더라도 IdleTimeout이 0이 아니면 프로세스는 종료됩니다.
장시간 유지하려면 idleTimeout=0을 반드시 설정해야 합니다.

즉,

  • AlwaysRunning만 설정 → 여전히 종료됨
  • IdleTimeout=0만 설정 → 지속 유지 가능
  • 두 값을 함께 설정해야 진짜 Always-On 환경이 된다

 

 

3. PreloadEnabled가 Out-of-Process에서 동작하는지?

일부 오래된 문서에서는 Out-of-Process에서 PreloadEnabled가 효과가 제한적이라고 언급한다.

 

 

최신 기준 정리(2025)

호스팅 모델 PreloadEnabled 동작 특징

In-Process ✔ 정상 작동 IIS 내부 프로세스(w3wp)에서 빠른 초기화
Out-of-Process ✔ 작동 Kestrel 프로세스 생성 과정이 추가되어 상대적으로 느림

결론

Out-of-Process에서도 PreloadEnabled는 정상 동작한다.
단지 초기화 과정이 복잡하여 시간이 더 소요될 뿐이다.


 

4. Suspend 모드(Idle Timeout Action)의 실제 의미

IIS 8.5 이후 도입된 Suspend는 프로세스를 바로 종료하지 않고 메모리 상태를 보존한다.

장점

  • 재활성 시 빠르게 복구됨
  • CPU 사용량 감소 효과

단점

  • 메모리 누수 위험이 존재
    → 장기간 Suspend된 프로세스는 메모리 증가 추세를 유지할 수 있음

Suspend를 사용하는 경우에는 일정 주기로 메모리를 정리해야 하므로 정기 재시작(Periodic Restart) 전략이 필요하다.


 

5. Periodic Restart(정기 재시작)의 중요성

IIS는 기본적으로 29시간마다 자동 재시작을 수행한다.
이는 예측 불가능한 시간에 재시작이 일어나 서비스 지연을 초래할 수 있다.

운영 환경에서는 반드시 재시작 시간을 명시적으로 설정하는 것이 좋다.

예) 매일 새벽 04:00 재시작
→ 야간에 안정적으로 재시작을 수행


 

6. 서비스 유형별 추천 설정값

🔥 고트래픽 / 핵심 서비스 (항상 Warm 상태)

설정 값

Start Mode AlwaysRunning
Idle Timeout 0 (필수)
Idle Timeout Action N/A
PreloadEnabled True
Periodic Restart 특정 시간(04:00 권장)

 

 

효과:
Cold Start 완전 제거.
항상 활성 상태로 유지되어 AWS 타임아웃 이슈 해결.


 

📘 중트래픽 서비스

  • 대부분 고트래픽 설정과 동일하게 IdleTimeout=0 권장
  • 메모리가 제한될 경우만 Suspend 고려

🟦 저트래픽 / 비용 최적화 서비스

설정 값

Start Mode AlwaysRunning
Idle Timeout 20분
Idle Timeout Action Suspend
PreloadEnabled True
Periodic Restart 0 또는 특정 시간

 

 

조건:
메모리 누수가 없는 안정적인 앱만 적용.


🧪 개발/테스트 환경

  • Start Mode = OnDemand
  • Idle Timeout = 기본 20분
  • Action = Terminate
  • PreloadEnabled = Off

7. PowerShell 기반 실전 설정 코드

고트래픽 운영 서비스

Import-Module WebAdministration

$AppPool = "DefaultAppPool"
$Site = "myhome.domain.kr"

# AppPool 설정
$AppPoolInstance = Get-Item IIS:\AppPools\$AppPool
$AppPoolInstance.startMode = "AlwaysRunning"
$AppPoolInstance.processModel.idleTimeout = [TimeSpan]::FromMinutes(0)
$AppPoolInstance.Recycling.periodicRestart.time = [TimeSpan]::Parse("0")
$AppPoolInstance | Set-Item

# 기존 Recycle 스케줄 모두 삭제
Clear-ItemProperty "IIS:\AppPools\$AppPool" -Name recycling.periodicRestart.schedule

# 새로운 스케줄 추가 (첫 번째는 Set-ItemProperty 사용)
Set-ItemProperty "IIS:\AppPools\$AppPool" -Name recycling.periodicRestart.schedule -Value @{value="04:00:00"}

# 추가 스케줄이 더 필요하면 New-ItemProperty 사용
# New-ItemProperty "IIS:\AppPools\$AppPool" -Name recycling.periodicRestart.schedule -Value @{value="12:00:00"}

# Site의 Preload 설정
Set-ItemProperty "IIS:\Sites\$Site" -name applicationDefaults.preloadEnabled -value True

 

$AppPoolInstance.startMode = "AlwaysRunning"

 

 

$AppPoolInstance.Recycling.periodicRestart.time = [TimeSpan]::Parse("0")

 

 

$AppPoolInstance.processModel.idleTimeout = [TimeSpan]::FromMinutes( 0 )

 

Set -ItemProperty "IIS:\AppPools\$AppPool" -Name recycling.periodicRestart.schedule -Value @{value= "04:00:00" }

 

 

Set -ItemProperty "IIS:\Sites\$Site" -name applicationDefaults.preloadEnabled -value True

 


8. 최종 체크리스트

항목 필요 여부

Application Initialization 모듈 설치 ✔ 필요
Hosting Model = InProcess ✔ 권장
AlwaysRunning + IdleTimeout=0 ✔ 핵심 조합
PreloadEnabled ✔ Cold Start 방지
Periodic Restart 시간 지정 ✔ 안정성 증가
Suspend 모드 메모리 추적 ✔ 모니터링 필요

9. 최종 정리

  1. AlwaysRunning만으로는 절대 Always-On이 되지 않는다
    Idle Timeout=0 설정이 반드시 필요하다.
  2. PreloadEnabled는 In/Out-of-Process 모두 작동한다
  3. Periodic Restart를 명시적으로 설정해야 운영 안정성이 확보된다
  4. Suspend는 메모리 누수가 없는 환경에서만 권장
  5. AWS 환경에서는 Cold Start가 바로 Timeout을 유발하므로 Always-On 구성이 사실상 필수

결론

ASP.NET Core 8을 IIS에서 운영할 때 가장 안정적인 설정은 AlwaysRunning + IdleTimeout=0 + Preload + 정기 Restart 시간 설정이다.
이 조합은 Cold Start 문제를 완전히 제거하고, AWS 환경에서 빈번한 504 Timeout 이슈를 구조적으로 차단한다.