Modal container capacity Β· priced 14 Aug 2026

Warm Pool Economics

Two ways to keep 150 job containers ready for a spike. One pays for readiness around the clock. One pays for it only in the hours spikes actually arrive.

1,000 jobs / day 500 image Β· 500 video peak target 150 at once orchestration only β€” generation billed separately

The two options

Option A

Always‑On 150

$2,613per month

150 containers stay warm every second of every day. Any spike, at any hour, waits zero seconds. Set once in code and never touched again.

Warm at 03:00
150
Warm at 14:00
150
Paid container-hours / mo
108,000
Cost per job
$0.087
Per year
$31,356
Option B

Scheduled Window

$1,418per month

150 warm from 08:00 to 18:00, dropping to a 20-container floor overnight. Identical response inside the window. Off-hours spikes above 20 wait for a cold start.

Warm at 03:00
20
Warm at 14:00
150
Paid container-hours / mo
53,400
Cost per job
$0.047
Per year
$17,016
Saves $14,340 / year

Where the money goes β€” the clock

The two options are identical in capability. They differ only in when capacity is warm. Each bar is one hour of the day; bar height is warm containers.

Option A Β· always-on 108,000 paid container-hours / month
Option B Β· warm 08:00–18:00 53,400 paid container-hours / month
0246 8101214 16182022

Option B cuts paid container-hours by 51% β€” 54,600 hours a month that were bought and never used.

Cost breakdown

Line item Container-hours / mo Option A Option B
150 warm β€” full day (24 h)108,000$2,363β€”
150 warm β€” window (10 h)45,000β€”$985
20 floor β€” off-hours (14 h)8,400β€”$184
Job compute (already inside the warm pool)β€”$0$0
Team plan β€” required above 100 containersβ€”$250$250
Total per month $2,613 $1,418

Jobs run on the warm containers you already pay for, so per-job compute adds nothing. That is the counter-intuitive part: the work is free, the readiness is the bill.

How the bill moves with the window

Every hour you hold 150 warm costs $98. Every hour you drop to the 20-floor costs $13. Pick the window and read the price.

24 h (= A) $2,613
16 h $1,930
12 h $1,589
10 h (= B) $1,418
8 h $1,248
4 h $906

The curve flattens because two costs never move: the 20-container overnight floor and the $250 plan. Shrinking the window past 8 hours buys little and costs coverage.

What each option actually covers

ScenarioOption AOption B
150 jobs land at once, 14:000 s wait0 s wait
150 jobs land at once, 03:000 s wait130 wait ~25 s
30 jobs land at once, 03:000 s wait10 wait ~25 s
20 jobs land at once, 03:000 s wait0 s wait
Jobs beyond 150, any hourqueuequeue
Moving parts to operatenone2 cron jobs

Option B is not weaker in the window. It is weaker outside it. So the whole choice reduces to one question for the customer: can spikes arrive at 3 a.m.?

Option B β€” how it is built

Two scheduled functions flip the warm-pool size. Modal supports this natively; no external scheduler.

@app.cls(min_containers=20, max_containers=150, scaledown_window=600, ...)
class Processor: ...

@app.function(schedule=modal.Cron("50 7 * * *", timezone="Asia/Ulaanbaatar"))
def warm_up():
    Processor().update_autoscaler(min_containers=150)   # 10 min before the window

@app.function(schedule=modal.Cron("0 18 * * *", timezone="Asia/Ulaanbaatar"))
def cool_down():
    Processor().update_autoscaler(min_containers=20)

Risk 1 β€” a deploy silently cancels it

update_autoscaler values revert to the decorator on the next deploy. Deploy at 10:00 and the pool drops from 150 to 20 mid-window, with no error anywhere. Any deploy inside the window must re-run warm_up.

Risk 2 β€” 150 containers do not appear instantly

The cron must fire before the window, not at it. 10 minutes of lead time is why warm_up runs at 07:50 for an 08:00 window.

Free upgrade β€” scaledown_window=600

Containers spun up during a spike stay warm for 10 minutes afterwards. A second spike inside that window is instant. This helps both options and costs nothing extra.

Sensitivity β€” memory per container

Neither cpu= nor memory= is set on the class today, so Modal bills whatever the container actually uses. The 2 GiB row is the working estimate; the others bracket it.

RAM per container$/container/moOption AOption B
1 GiB$10.00$1,750$992
2 GiB β€” estimate used$15.75$2,613$1,418
4 GiB$27.26$4,339$2,272

Worst case doubles the bill. Setting an explicit memory= caps that exposure and makes the forecast firm β€” a bill you cannot bound is not a quote.

Recommendation

Start on Option B at a 10-hour window: $1,418/month. It is identical to Option A during the hours that carry traffic and saves $14,340 a year on hours that carry none.

Move to Option A only if the customer confirms spikes can land outside the window. The difference is $1,195/month for overnight readiness β€” priced honestly, that is what a 3 a.m. spike costs.

Two things before either number is firm: set an explicit memory= so the bill is bounded, and re-measure the cold start. The 25-second figure in the code predates memory snapshots; if restore is really 3–5 seconds, a much smaller warm pool covers the same spike and both numbers fall.