Skill Tracer
Skills › Scientific Agent Skills › modal › resources.md

resources.md

125 lines · skills/modal/references/resources.md at 5f2bc03

Open on GitHub
1# Modal Resource Configuration
2
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.
6

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 6
9### 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_THREADS based on your CPU request
Raw lines 9 to 20
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 31
32## Memory
34### 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
Raw lines 34 to 44
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.

Raw lines 45 to 58
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 77
78## 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_timeout controls startup independently
  • Expiry is approximate and eventually raises modal.exception.FunctionTimeoutError
Raw lines 78 to 91
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.

ResourceBilling Basis
CPUmax(requested, used)
Memorymax(requested, used)
GPUTime GPU is allocated
DiskIncreases memory billing at 20:1 ratio
Raw lines 92 to 102
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_window to minimize idle time
  • Use min_containers=0 when cold starts are acceptable
  • Batch inputs with .map() instead of individual .remote() calls
Raw lines 103 to 110
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,
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