Skills › Scientific Agent Skills › modal › resources.md
resources.md
125 lines · skills/modal/references/resources.md at 5f2bc03
1# Modal Resource Configuration
3Reviewed against SDK 1.6.0 and the official [resource guide](https://modal.com/docs/guide/resources)
4and [timeout guide](https://modal.com/docs/guide/timeouts). Examples are configuration
5fragments; no remote allocation or billing was measured.
Modal Resource Configuration
Reviewed against SDK 1.6.0 and the official resource guide and timeout guide. Examples are configuration fragments; no remote allocation or billing was measured.
Raw lines 1 to 69### Requesting CPU
11```python
12@app.function(cpu=4.0)
13def compute():
14 ...
15```
17- Values are **physical cores**, not vCPUs
18- Default: 0.125 cores
19- Modal auto-sets `OPENBLAS_NUM_THREADS`, `OMP_NUM_THREADS`, `MKL_NUM_THREADS` based on your CPU request
Requesting CPU
@app.function(cpu=4.0)
def compute():
...- Values are physical cores, not vCPUs
- Default: 0.125 cores
- Modal auto-sets
OPENBLAS_NUM_THREADS,OMP_NUM_THREADS,MKL_NUM_THREADSbased on your CPU request
21### CPU Limits
23- Default soft limit: 16 physical cores above the CPU request
24- Set explicit limits to prevent noisy-neighbor effects:
26```python
27@app.function(cpu=(1.0, 4.0)) # Request 1 core, soft limit 4 cores
28def bounded_compute():
29 ...
30```
CPU Limits
- Default soft limit: 16 physical cores above the CPU request
- Set explicit limits to prevent noisy-neighbor effects:
@app.function(cpu=(1.0, 4.0)) # Request 1 core, soft limit 4 cores
def bounded_compute():
...Raw lines 21 to 31Memory
Raw lines 32 to 3334### Requesting Memory
36```python
37@app.function(memory=16384) # 16 GiB in MiB
38def large_data():
39 ...
40```
42- Value in **MiB** (mebibytes)
43- Default: 128 MiB
Requesting Memory
@app.function(memory=16384) # 16 GiB in MiB
def large_data():
...- Value in MiB (mebibytes)
- Default: 128 MiB
45### Memory Limits
47Set hard memory limits to OOM-kill containers that exceed them:
49```python
50@app.function(memory=(8192, 16384)) # 8 GiB request, 16 GiB hard limit
51def bounded_memory():
52 ...
53```
55This prevents paying for runaway memory leaks.
56A scalar `memory=8192` is a request, not an explicit hard limit. Requests/limits
57are validated against platform capacity; do not assume a requested allocation is available.
Memory Limits
Set hard memory limits to OOM-kill containers that exceed them:
@app.function(memory=(8192, 16384)) # 8 GiB request, 16 GiB hard limit
def bounded_memory():
...This prevents paying for runaway memory leaks. A scalar memory=8192 is a request, not an explicit hard limit. Requests/limits are validated against platform capacity; do not assume a requested allocation is available.
59## Ephemeral Disk
61For temporary storage within a container's lifetime:
63```python
64@app.function(ephemeral_disk=102400) # 100 GiB in MiB
65def process_dataset():
66 # Temporary files at /tmp or anywhere in the container filesystem
67 ...
68```
70- Value in **MiB**
71- Default: 512 GiB quota per container
72- Maximum: 3,145,728 MiB (3 TiB)
73- Data is lost when the container shuts down
74- Use Volumes for persistent storage
76Larger disk requests increase the memory request at a 20:1 ratio for billing purposes.
Ephemeral Disk
For temporary storage within a container's lifetime:
@app.function(ephemeral_disk=102400) # 100 GiB in MiB
def process_dataset():
# Temporary files at /tmp or anywhere in the container filesystem
...- Value in MiB
- Default: 512 GiB quota per container
- Maximum: 3,145,728 MiB (3 TiB)
- Data is lost when the container shuts down
- Use Volumes for persistent storage
Larger disk requests increase the memory request at a 20:1 ratio for billing purposes.
Raw lines 59 to 7778## Timeout
80```python
81@app.function(timeout=3600) # 1 hour in seconds
82def long_running():
83 ...
84```
86- Default: 300 seconds (5 minutes)
87- Maximum: 86,400 seconds (24 hours)
88- Execution timeout is per attempt; configured retries get a fresh timeout
89- Queue time is excluded; `startup_timeout` controls startup independently
90- Expiry is approximate and eventually raises `modal.exception.FunctionTimeoutError`
Timeout
@app.function(timeout=3600) # 1 hour in seconds
def long_running():
...- Default: 300 seconds (5 minutes)
- Maximum: 86,400 seconds (24 hours)
- Execution timeout is per attempt; configured retries get a fresh timeout
- Queue time is excluded;
startup_timeoutcontrols startup independently - Expiry is approximate and eventually raises
modal.exception.FunctionTimeoutError
92## Billing
94You are charged based on **whichever is higher**: your resource request or actual usage.
96| Resource | Billing Basis |
97|----------|--------------|
98| CPU | max(requested, used) |
99| Memory | max(requested, used) |
100| GPU | Time GPU is allocated |
101| Disk | Increases memory billing at 20:1 ratio |
Billing
You are charged based on whichever is higher: your resource request or actual usage.
| Resource | Billing Basis |
|---|---|
| CPU | max(requested, used) |
| Memory | max(requested, used) |
| GPU | Time GPU is allocated |
| Disk | Increases memory billing at 20:1 ratio |
103### Cost Optimization Tips
105- Request only what you need
106- Use appropriate GPU tiers (L40S over H100 for inference)
107- Set `scaledown_window` to minimize idle time
108- Use `min_containers=0` when cold starts are acceptable
109- Batch inputs with `.map()` instead of individual `.remote()` calls
Cost Optimization Tips
- Request only what you need
- Use appropriate GPU tiers (L40S over H100 for inference)
- Set
scaledown_windowto minimize idle time - Use
min_containers=0when cold starts are acceptable - Batch inputs with
.map()instead of individual.remote()calls
111## Complete Example
113```python
114@app.function(
115 cpu=8.0, # 8 physical cores
116 memory=32768, # 32 GiB
117 gpu="L40S", # L40S GPU
118 ephemeral_disk=204800, # 200 GiB temp disk
119 timeout=7200, # 2 hours
120 max_containers=50,
121 min_containers=1,
122)
123def full_pipeline(data_path: str):
124 ...
125```
Complete Example
@app.function(
cpu=8.0, # 8 physical cores
memory=32768, # 32 GiB
gpu="L40S", # L40S GPU
ephemeral_disk=204800, # 200 GiB temp disk
timeout=7200, # 2 hours
max_containers=50,
min_containers=1,
)
def full_pipeline(data_path: str):
...Raw lines 111 to 125