
Streamlit in SnowflakeのWarehouseランタイムとContainerランタイムの違いまとめ
はじめに
データ事業本部の荒木です。
Streamlit in Snowflakeでアプリを作るとき、WarehouseランタイムとContainerランタイムのどちらを選ぶのが適切か悩むことがあるかと思います。
料金で選ぶにも、公式ドキュメントには「Containerは分単価が安い」と書かれていますが、アプリの使われ方によっては逆にWarehouseの方が安くなります。また、料金以外にもキャッシュ・使えるパッケージ・Pythonのバージョンなど、選んだ後に変えにくい違いが多くあります。
2つのランタイムの根本的な違いは、Warehouseランタイムが「閲覧者ごとに個別のプロセスを起動し、使っていない間は止まる」のに対し、Containerランタイムが「アプリごとに1つのプロセスを常駐させ、全閲覧者で共有する」点です。この違いから、キャッシュの効き方・起動の速さ・課金のされ方がすべて異なります。
以降では、2つのランタイムの仕組みを説明し、機能面の違いを表にまとめたうえで、最後に公式の料金表をもとにランタイムごとの料金の違いを試算したいと思います。
Streamlit in Snowflakeの2つのランタイムとは何か
Streamlit in Snowflakeは、PythonのWebアプリフレームワークであるStreamlitで作ったアプリを、Snowflakeアカウント内でそのまま動かせる機能です。アプリを動かす実行環境 (ランタイム) として、次の2種類から選べます。
| ランタイム | アプリを動かす場所 | 公式ドキュメントでの説明 |
|---|---|---|
| Warehouseランタイム | 仮想ウェアハウス | 閲覧者ごとに個人用のアプリインスタンスを作る |
| Containerランタイム | Snowpark Container Servicesのコンピュートプール | 長時間稼働するサービスとして、全閲覧者で共有するインスタンスを1つ作る |
公式ドキュメントでは、それぞれ次のように説明されています。
Serves an app as a long-running service and creates a dedicated instance of the app that is shared among all viewers.
creates a personal instance of the app for each viewer.
WarehouseランタイムとContainerランタイムは仕組みがどう違うのか
仕組みの違いを、App1を2人 (A1・A2)、App2を1人 (B1) が同時に開いている状況で比べます。
Warehouseランタイムは閲覧者ごとにStreamlitのプロセスが起動する
Warehouseランタイムでは、閲覧者がアプリを開くとウェアハウスが再開し、接続ごとに新しいStreamlitのサーバープロセスが起動します。同じアプリを開いていても、閲覧者ごとに別のプロセスになります。プロセスどうしはディスク・メモリ・キャッシュを共有しません。

プロセスは閲覧者の数だけ増えますが、すべて同じウェアハウスの中で動きます。課金されるのはウェアハウスが稼働している時間なので、閲覧者が増えてもウェアハウスのサイズが同じなら時間あたりの料金は変わりません。その代わり、閲覧者が増えるとウェアハウスのリソースを分け合うことになります。
Containerランタイムはアプリごとに1つの常駐プロセスを全員で共有する
Containerランタイムでは、アプリごとにコンピュートプールのノード上でStreamlitのサーバーが常駐します。同じアプリの閲覧者は全員そのサーバーに接続するため、キャッシュも共有されます。アプリ内で実行するSQLは、コンピュートプールではなく別に指定したクエリ用ウェアハウス (QUERY_WAREHOUSE) で実行されます。

1つのノードで動くアプリの数は、使うコンピュートプールによって変わります。1ノードで動くアプリの数は料金に直結するため、特に注意が必要です。
注意: 1ノードで動くアプリの数はコンピュートプールによって異なります
- Snowflakeが用意している
SYSTEM_COMPUTE_POOL_CPUでは、1ノードで3つのアプリが動きます- それ以外のコンピュートプール (自分で作成したもの) では、1つのアプリが1ノードを占有します。ノードのvCPUやメモリを大きくしても、1ノードで複数のアプリは動きません
公式ドキュメントの原文: "When an app runs on
SYSTEM_COMPUTE_POOL_CPU, Snowflake runs three Streamlit apps per compute pool node. Otherwise, a single app can run on a node in the compute pool; a Streamlit app takes an entire node."

2つの構成図から分かる違いを1文にまとめると、次のようになります。
Warehouseランタイムは「閲覧者×アプリの数だけプロセスが増え、使っていない間は止まる」、Containerランタイムは「アプリの数だけサーバーが常駐し、閲覧者はそのサーバーを共有する」構造です。
なお、アプリを複数作るとランタイムに関係なくアプリごとに別のURLが発行されます。1つのURLで複数の機能を見せたい場合は、アプリを分けずに1つのアプリの中でページやタブを切り替える構成にします。
WarehouseランタイムとContainerランタイムの機能の違い一覧
公式ドキュメントに記載されている違いを1つの表にまとめました。料金以外にも、Pythonのバージョンやパッケージの入れ方など、アプリの作り方に影響する違いがあります。
| 項目 | Warehouseランタイム | Containerランタイム |
|---|---|---|
| アプリを動かす場所 | 仮想ウェアハウス | コンピュートプールのノード |
| SQLを実行する場所 | 同じウェアハウス (アプリ内で切り替え可) | クエリ用ウェアハウス |
| Streamlitサーバー | 閲覧者セッションごとに一時的に起動 | 全閲覧者で共有する常駐インスタンス |
| ディスク・メモリの共有 | 閲覧者間で共有しない | 閲覧者間で共有する |
キャッシュ (@st.cache_dataなど) |
セッションをまたいだキャッシュは使えない | セッションをまたいで使える |
| 閲覧者が開くときの速さ | 遅い (開くたびにプロセスを起動するため) | 速い (常駐しているため) |
| デプロイの速さ | 速い | 遅い (コンテナを起動するため) |
| Streamlitのバージョン | 1.22以上 (選択肢は限られる) | 1.50以上 (streamlit-nightlyを含め任意) |
| Pythonのバージョン | 3.9/3.10/3.11 | 3.11のみ |
| ベースイメージ | Pythonストアドプロシージャ内のLinux | Snowparkコンテナ内のLinux |
| パッケージの取得元 | SnowflakeのCondaチャネル | PyPIなどの外部インデックス (外部アクセス統合が必要) |
| パッケージの指定ファイル | environment.yml |
pyproject.tomlまたはrequirements.txt |
| エントリポイントの場所 | ソースディレクトリのルートのみ | ルートまたはサブディレクトリ |
| 停止のタイミング | 操作が止まって約15分後 (スリープタイマーで5〜240分に変更可) | 閲覧者のアクセスが3日間ないと停止 |
| メンテナンスの影響 | なし | Snowpark Container Servicesのメンテナンスウィンドウの対象 |
| 権限 | 所有者の権限 (Owner's rightsストアドプロシージャと同じ制限) | 所有者の権限。一部のクエリで制限付き呼び出し元の権限 (プレビュー) を使える |
| ログ | イベントテーブルに記録 | ライブのコンソールログ+イベントテーブルの履歴ログ |
| 対応リージョン | 制限の記載なし | 米国政府リージョンは非対応 |
作成したいアプリの要件によって適切なランタイムを選ぶ必要があります。
WarehouseランタイムとContainerランタイムでは料金のかかり方がどう違うのか
料金の違いは、上の表の「停止のタイミング」から生まれます。どちらのランタイムも、課金はクレジット単位です。
消費クレジット = 1時間あたりのクレジット消費量 × 稼働時間
料金 = 消費クレジット × クレジット単価
Warehouseランタイムは閲覧者がいなくなると止まる
Warehouseランタイムでは、閲覧者の最後の操作から約15分でWebSocket接続が切れ、アプリが停止します。アプリが停止するとウェアハウスは自動停止できる状態になり、ウェアハウスのAUTO_SUSPENDの設定に従って停止します。ブラウザのタブを開いたままでも、アプリの上でマウスを動かすと操作とみなされて接続が続く点に注意が必要です。
Mouse movement over the app counts as activity and keeps the WebSocket connection alive.
閲覧者の操作がなくなる
↓ 約15分 (WebSocketのタイムアウト。変更はSnowflakeサポートへの依頼が必要)
WebSocket接続が切れ、アプリが停止する
↓ ウェアハウスのAUTO_SUSPEND
ウェアハウスが停止し、課金が止まる
Warehouseランタイムはスリープタイマーで停止までの時間を変えられる
Warehouseランタイムでは、アプリごとにスリープタイマーを設定して、操作が止まってからアプリが停止するまでの時間を5〜240分の範囲で指定できます。設定しない場合は15分です。設定はアプリの.streamlit/config.tomlに書きます。
[snowflake]
[snowflake.sleep]
streamlitSleepTimeoutMinutes = 8
ただし、ブラウザの設定によっては開いていないタブでタイマーが止まることがあり、その場合はWebSocketのタイムアウト (約15分) が適用されます。公式ドキュメントでは、WebSocketのタイムアウトをアプリで使うスリープタイマーの最小値に合わせることが推奨されています。なお、スリープタイマーはWarehouseランタイムのみの機能で、Containerランタイムでは使えません。
Container runtimes are intended for long-running services and don't support sleep timers.
Containerランタイムは閲覧者がいなくても3日間は止まらない
Containerランタイムの停止について、公式ドキュメントには次のように書かれています。
After three days of viewer inactivity, the Streamlit server process ends and Snowflake suspends the compute pool according to its own AUTO_SUSPEND value.
閲覧者がいない状態が3日間続くとStreamlitのサーバーが終了し、そのあとコンピュートプールが自身のAUTO_SUSPEND_SECSに従って停止する、という流れです。公式ドキュメントには、新しい閲覧者が接続しないまま3日間セッションを維持しようとすると、アプリはおそらく停止される (probably be suspended) とも書かれています。
課金はアプリではなく、コンピュートプールの状態で決まります。公式ドキュメントでの状態の定義と課金の有無は次のとおりです。
| 状態 | 公式ドキュメントでの定義 | 課金 |
|---|---|---|
| ACTIVE | 少なくとも1つのサービスが実行中、または実行予定 | あり |
| IDLE | ノードは確保されているが、サービスがスケジュールされていない | あり |
| SUSPENDED | 稼働中のノードがない | なし |
このほか、起動中のSTARTINGは課金されず、停止処理中のSTOPPINGとノード数を調整中のRESIZINGは課金されます。
コンピュートプールのAUTO_SUSPEND_SECSは、プール内のどのノードでもサービスやジョブが動いていない状態が何秒続いたら自動停止するかを指定する値です。既定値は3600秒で、0にすると自動停止しません。
新しい閲覧者の接続がない状態が続く
↓ 3日間
Streamlitのサーバーが終了する
↓ プール内でほかのサービスやジョブが動いていなければIDLEになる (課金は続く)
↓ コンピュートプールのAUTO_SUSPEND_SECS (既定は3600秒)
コンピュートプールがSUSPENDEDになり、課金が止まる
Streamlitのサーバーが終了しても、すぐには課金は止まりません。プールがIDLEの間は課金が続き、AUTO_SUSPEND_SECSの時間がたってSUSPENDEDになった時点で止まります。また、同じコンピュートプールでほかのアプリやサービスが動いている間は、プールはACTIVEのままなので課金が続きます。
SYSTEM_COMPUTE_POOL_CPUの場合の注意
SYSTEM_COMPUTE_POOL_CPUのAUTO_SUSPEND_SECSの既定値は600秒です。ただし、Snowflakeはこのプールに無料のアイドル状態のノードを1つ以上提供することがあり、提供している間はAUTO_SUSPEND_SECSが一時的に259200秒 (3日) に設定されます。無料のアイドル状態のノードは稼働中の処理とはみなされず、プールの自動停止を妨げません。
この仕組みのため、1つのアプリだけを動かす自作のコンピュートプールでは、平日に毎日短時間だけ使うアプリでも、土日の2日間では3日に届かずサーバーが終了しないため、コンピュートプールが停止しません。結果として、利用時間に関係なく1か月すべての時間 (30日×24時間=720時間) 課金されることになります。
WarehouseランタイムとContainerランタイムはどちらが安いのか
Snowflake公式のService Consumption Tableをもとに、月額を試算します。
クレジット消費量とクレジット単価
試算には次の値を使います。仮想ウェアハウスはStandardウェアハウスの値、コンピュートプールは第1世代のCPUインスタンスの値です。
| 構成 | 1時間あたりのクレジット |
|---|---|
| ウェアハウスXS | 1 |
| ウェアハウスS | 2 |
| コンピュートプールCPU_X64_XS | 0.06 |
| コンピュートプールCPU_X64_S | 0.11 |
| コンピュートプールCPU_X64_M | 0.22 |
| コンピュートプールCPU_X64_L | 0.83 |
クレジット単価は、AWS東京リージョンのEnterpriseエディション (On Demand) の$4.30で計算します。
なお、試算で使うCPU_X64_XSなどの第1世代のインスタンスは、公式ドキュメントでは前の世代 (Previous generation) と位置づけられており、新しく使う場合は第2世代のGEN_X64_G2系を使うよう案内されています。
Previous generation x86 instances. For new workloads, use GEN_X64_G2 instances instead.
第1世代と第2世代は、vCPUとメモリが同じ構成のインスタンスが用意されています。
| 第1世代 | 第2世代 | vCPU | メモリ (GiB) |
|---|---|---|---|
| CPU_X64_XS | GEN_X64_G2_2 | 1 | 6 |
| CPU_X64_S | GEN_X64_G2_4 | 3 | 13 |
| CPU_X64_M | GEN_X64_G2_8 | 6 | 28 |
| CPU_X64_L | GEN_X64_G2_32 | 28 | 116 |
第2世代のクレジット消費量は、Service Consumption Tableに第1世代とは別の表で掲載されています。第2世代で見積もる場合は、そちらの値に置き換えて計算してください。
毎日8時間使うアプリはContainerランタイムが安い
1つ目のケースは、平日20日間、毎日8時間使われるアプリです。Warehouseランタイムは使っている160時間分だけ課金され、Containerランタイムは常駐する720時間分が課金されます。
| 構成 | 課金される時間 | 月間クレジット | 月額 (USD) |
|---|---|---|---|
| Warehouse XS | 160時間 | 160 | $688 |
| Warehouse S | 160時間 | 320 | $1,376 |
| Container CPU_X64_XS | 720時間 | 43.2 | $186 |
| Container CPU_X64_S | 720時間 | 79.2 | $341 |
| Container CPU_X64_M | 720時間 | 158.4 | $681 |
| Container CPU_X64_L | 720時間 | 597.6 | $2,570 |
利用時間が長いアプリでは、CPU_X64_Mまでの構成であれば、常駐で720時間課金されてもContainerランタイムの方が安くなります。
毎日1時間使うアプリはWarehouseランタイムが安い
2つ目のケースは、平日20日間、毎日1時間だけ使われるアプリです。Warehouseランタイムは20時間分だけ課金されますが、Containerランタイムは1つ目のケースと同じく720時間分が課金されます。
| 構成 | 課金される時間 | 月間クレジット | 月額 (USD) |
|---|---|---|---|
| Warehouse XS | 20時間 | 20 | $86 |
| Warehouse S | 20時間 | 40 | $172 |
| Container CPU_X64_XS | 720時間 | 43.2 | $186 |
| Container CPU_X64_S | 720時間 | 79.2 | $341 |
利用時間が短いアプリでは、分単価が高いWarehouseランタイムの方が安くなります。
料金が逆転するのは月約43時間
最小構成どうし (Warehouse XSとContainer CPU_X64_XS) で比べると、Containerランタイムの月間クレジットは43.2で固定です。Warehouseランタイムは1時間1クレジットなので、月の利用時間が約43時間で料金がほぼ同じになります。
| 月の利用時間 | Warehouse XS | Container CPU_X64_XS | 安い方 |
|---|---|---|---|
| 10時間 | 10クレジット ($43) | 43.2クレジット ($186) | Warehouse |
| 約43時間 | 43クレジット ($185) | 43.2クレジット ($186) | ほぼ同じ |
| 176時間 (平日8時間×22日) | 176クレジット ($757) | 43.2クレジット ($186) | Container |
| 720時間 (常時) | 720クレジット ($3,096) | 43.2クレジット ($186) | Container |
分単価だけを見るとContainerランタイムが安く見えますが、比べるべきは「そのアプリが月に何時間使われるか」です。
試算の注意点
この試算には含めていない費用や前提があります。実際に見積もるときは次の点も考慮してください。
- Containerランタイムは、SQLを実行するクエリ用ウェアハウスの料金が別にかかります。上の表はコンピュートプールの料金だけです
- Warehouseランタイムは、閲覧者の操作が止まってからアプリが停止するまでの時間 (既定で約15分) と
AUTO_SUSPENDの時間分、利用時間より長く課金されます。短くしたい場合はスリープタイマーを使います CPU_X64_XSは1vCPU/6GiBの最小のインスタンスで、複数人が同時に負荷の高い処理を実行するアプリには向いていません。そうしたアプリではCPU_X64_S(3vCPU/13GiB) 以上を前提に見積もることをおすすめします- Containerランタイムでも、業務時間外にコンピュートプールを手動またはタスクで停止すれば、常駐による課金は減らせます
WarehouseランタイムとContainerランタイムの選び方
ここまでの違いを、選ぶときの判断基準として整理します。
| こういうアプリなら | 選ぶランタイム |
|---|---|
| 毎日長時間使われる・閲覧者が多い | Container |
| キャッシュで表示を速くしたい | Container |
| PyPIのパッケージや新しいStreamlitを使いたい | Container |
| 週に数回しか使われない | Warehouse |
| 閲覧者ごとに処理やメモリを分けたい | Warehouse |
| Python3.9や3.10が必要 | Warehouse |
| 米国政府リージョンで動かす | Warehouse |
どちらのランタイムでも扱いにくいのが、「閲覧者ごとに重い処理を実行し、かつ同時に使う人が多い」アプリです。Containerランタイムでは1つのサーバーを全員で共有するため、重い処理が他の閲覧者の操作を遅くします。Warehouseランタイムでは閲覧者ごとにプロセスが分かれますが、同じウェアハウスのリソースを分け合うため、人数が増えるとウェアハウスを大きくする必要があります。こうしたアプリは、重い処理を別のサービスに切り出すか、Streamlit in Snowflake以外の基盤で動かすことも検討してください。
まとめ
Streamlit in SnowflakeのWarehouseランタイムとContainerランタイムについて、仕組み・機能・料金の違いをまとめました。2つのランタイムの違いは、閲覧者ごとにプロセスを起動して使い終わったら止まるか、アプリごとに1つのサーバーを常駐させて全員で共有するかに集約されます。料金は分単価だけで判断せず、Containerランタイムが3日間止まらないことを踏まえて、アプリが月に何時間使われるかで比べることが重要です。
お役に立てば幸いです。







