# Modal

Official pricing: https://modal.com/pricing  
Category: agent-sandbox · Isolation: gvisor

## Pricing regimes (raw)

- **Sandbox (gVisor), request = size, any region** (resource): $0.141912/vCPU-h, $0.024012/GiB-h
- **Sandbox, minimal request + burst (billed ~ on usage; burst capacity not guaranteed)** (resource): $0.141912/vCPU-h, $0.024012/GiB-h
- **Sandbox pinned to broad region (us / eu / ap)** (resource): $0.141912/vCPU-h, $0.024012/GiB-h
- **Sandbox pinned to narrow region (us-west, uk, jp ...)** (resource): $0.141912/vCPU-h, $0.024012/GiB-h
- **VM Sandbox (beta, real kernel)** (resource): $0.141912/vCPU-h, $0.024012/GiB-h [beta]

## Features

Yes: snapshots, memory snapshots, fork/clone, persistent disk, volumes, idle auto-stop, ≥24 h sessions, custom image (Docker or snapshot), start from your own snapshot, your own Docker/OCI image, nested virtualization, root, systemd, SSH, HTTPS preview URLs, custom domains, raw TCP inbound, egress allowlist, open internet, static egress IP, SOC 2, HIPAA, SSO, GPU, Python, Node.js, memory fork, audit logs, EU data residency, snapshots on demand, fast boot (benchmarked), gVisor or VM (no shared kernel), inbound access rules, firewall inside (nftables), extra volumes, shared volumes

No: pause/resume, full VM (own kernel), Docker inside, browser, desktop GUI, computer-use API, code interpreter, browser + desktop control, anti-bot stealth, CAPTCHA solving, residential IPs, preinstalled agents, public IPv4, self-hosting, BYOC, open source, arm64, Windows, macOS, GPU desktop, HTTP method/path egress rules, wake on request, live resize, live fork (no pause), MCP server, automatic snapshots, agent harness API, hosted agent API (their own agent), secret proxy, secret proxy for any API

Unknown: everything else. Evidence (source + quote) per feature: https://battleships.dev/data/providers/modal.json → feature_evidence

## Caveats

- free.monthly_credit ($30) IS the Starter plan's included_usd, so don't subtract both. Team replaces it with $100 included.
- Billing is max(request, actual). The on-demand mode assumes request = workload size, so cpu_util gives no saving. Low-request-burst is optimistic: burst depends on spare host capacity, and its active_floor (0.03125) is exact only for 4 vCPU (0.125 / W.vcpu).
- CPU unit: card vCPU = 1 Modal `cpu` unit = 1 guest-visible CPU, priced at the per-'physical core' rate ($0.00003942/s = $0.141912/h). The pricing page and sandbox-resources guide say '1 core = 2 vCPU', but measurements (hpc-sandbox-benchmarks PR #121; HPC + ComputeSDK DAX runs) show cpu=N gives nproc N and N CPUs of throughput, i.e. the same capacity other cards call N vCPU. Modal does not disclose whether hosts run SMT; under the literal '2 vCPU equivalent' reading (cpu = W.vcpu/2) the same '4 vCPU' would cost half as much ($0.476/h at 4/8) but the guest sees only half the CPUs; that regime was removed (2026-09-28) because it is not the same machine. Evidence: research/verify/modal-cpu.md.
- Uncapped burst can bill MORE than the requested size (default soft limit is request + 16 cores) and the gVisor guest then reports ceil(limit) CPUs (ComputeSDK DAX 2026-07-17 at SDK defaults: nproc 17). The engine can't model this; set cpu=(req, limit).
- Egress at $0.04/GiB is charged only from 2026-10-01 (tracked, not billed, in Sep 2026). The allowance is plan-dependent (Starter 1 TiB, Team 10 TiB, Enterprise 100 TiB) and counts private container-to-container traffic and Cloud Bucket Mount uploads.
- Snapshot storage (filesystem/directory/memory) price is not published, so snapshot_gib_month is null. Filesystem snapshots default to a 30-day TTL (configurable/indefinite). Memory snapshots (alpha) expire after 7 days and terminate the source sandbox.
- Ephemeral disk: 512 GiB default quota, max 3 TiB. An explicit disk request is billed by raising the memory request to disk/20 GiB, so it costs extra only when disk/20 > the memory request. disk_gib_month is null because it is not a flat rate.
- No pause/stopped state. Default timeout is 5 min, max 24 h. Idle sandboxes pay the full request until idle_timeout terminates them.
- VM Sandbox rates are assumed equal to gVisor sandbox rates (the docs link to the same cpu/memory rates). Beta.
- GPU sandboxes are preemptible. GPU concurrency is 10 (Starter) and 50 (Team). H100->H200 and A100-40->80 auto-upgrades are billed at the requested type's price.
- Volumes cost $0.09/GiB-month beyond 1 TiB free (not modelled in the storage block).
- Enterprise discounts and reservations are unpublished. Startup credits are unpublished. Academic grants are up to $10k one-time (not in free.one_time_credit).
- Max vCPU/RAM per sandbox is not published (the docs say a max is enforced). A third-party snippet cites 64 cores / 336 GB per container.
- Adjacent option not in modes: running the same code as a preemptible Modal Function costs 1/3 of the sandbox rate ($0.04716/vCPU-h per cpu unit, $0.007992/GiB-h), but it isn't a sandbox.
- perf is mode-level (card-level nulled): gVisor modes 9.56 runs/s (HPC), cold 549 ms, burst 908 ms, DAX 111.4 s (ComputeSDK); vm-sandbox 15.07 runs/s (HPC). The 15.1 runs/s on boat.dev/compare is the VM runtime, not the default gVisor sandbox. Both HPC runs and ComputeSDK DAX passed cpu=4/cpuLimit=4 and observed nproc=4; the card now prices exactly that shape as '4 vCPU' ($0.759744/h at 8 GiB). boat.dev/compare's $0.476/h is the half-cores price (2 CPUs), not what was measured. See research/perf-costs.md.
- GPU counts (https://modal.com/docs/guide/gpu): A10 max 4 per container; T4/L4/L40S/A100/H100/H200/B200/B300 max 8; RTX PRO 6000 count unverified. H100 requests may be upgraded to H200 (billed as H100), B200 to B300 (billed as B200). GPU charge is not reduced by CPU utilisation in the low-request-burst mode.
- Egress: not charged in September 2026 (usage shown only). From 2026-10-01 egress is $0.04/GiB beyond 1 TiB (Starter) / 10 TiB (Team) / 100 TiB (Enterprise) per workspace per billing cycle; first invoice 2026-11-01. Card uses the current (free) rate; switch egress_gib to 0.04 on 2026-10-01 and add plan egress_free_gib 10240 on Team. https://modal.com/docs/guide/network-egress-billing
- GPU concurrency caps: Starter 10, Team 50, Enterprise custom (modal.com/pricing, 2026-09-28). The engine plan concurrency is the container cap (100 / 5,000); a workload with >10 concurrent GPU sandboxes needs Team.
- Snapshot storage re-checked 2026-09-28 (modal.com/docs/guide/sandbox-snapshots): retention is documented (filesystem/directory 30 days default, memory 7 days) but no price; snapshot_gib_month stays null.
- VM Sandbox (beta) is kept as its own regime: same published cpu/memory rates (no surcharge, modal.com/docs/guide/vm-sandboxes), but a different runtime (real kernel: Docker, systemd) with different CPU throughput, so its totals equal on-demand by design.
- Features check 2026-09-28: card.features.docker_inside true -> null for the default gVisor runtime. Current docs only document Docker via VM Sandboxes ("VM Sandboxes are also the recommended method to run Docker in Sandboxes", modal.com/docs/guide/vm-sandboxes); no current doc statement that Docker runs under gVisor. vm-sandbox mode keeps docker_inside true. nested_virt stays false in all modes: VM Sandboxes "Nested KVM virtualization is disabled by default. Please reach out to us if you'd like access."
- Included compute ($30 Starter / $100 Team) applies to Functions, Sandboxes and Notebooks CPU/memory/GPU; Volumes have their own 1 TiB; Shared Endpoint tokens are billed from the first request (since 2026-09-01). Whether egress overage is covered by included compute is not stated.
- Volumes: storage is sampled once a day and deleted data may still be billed for up to 4 days.
- Sidecars (public alpha, Sep 2026) share the Sandbox's CPU/memory request; there is no separate sidecar charge but the request must cover all containers.

## How this provider charges


As of 2026-09-28. Units: Modal lists CPU per **"Physical core (2 vCPU equivalent)"** at $0.00003942/core-s (sandboxes) and memory at $0.00000667/GiB-s.
The `cpu=` parameter is in those same "core" units, and billing is per unit. Measured, though, `cpu=N` (with `cpu` limit N) gives a guest that sees **N CPUs** (nproc N) and N CPUs of throughput, the same as N vCPU on other providers (evidence: `research/verify/modal-cpu.md`).
So this write-up (and the card) treats **1 Modal core = 1 vCPU = $0.141912/h**. With **$0.024012 per GiB-h**, a 4 vCPU / 8 GiB sandbox (`cpu=(4,4)`, 8 GiB) costs **$0.759744/h**. The literal "1 core = 2 vCPU" reading (`cpu=2`, $0.47592/h) gets you a 2-CPU guest.

## Regimes

| # | Regime | When it applies | How billed | Numbers | Source |
|---|---|---|---|---|---|
| 1 | **Default Sandbox (gVisor), no region** | `modal.Sandbox.create()` with no `region=` | Per second, CPU and RAM each billed on **max(request, actual usage)**. There are no minimum increments. | $0.141912 per core-h (= per guest CPU), $0.024012/GiB-h. Minimum is 0.125 core per container. The default request is 0.125 core / 128 MiB. The guest sees ceil(cpu limit) CPUs, so set `cpu=(req, limit)`. | https://modal.com/pricing , https://modal.com/docs/guide/sandbox-resources , https://modal.com/docs/guide/billing |
| 2 | **Sandbox rate = 3x Function rate ("non-preemptible")** | Every CPU sandbox is non-preemptible, and the 3x is already baked into the sandbox rate | Same basis as #1 | Functions cost $0.0000131/core-s and $0.00000222/GiB-s. Sandboxes cost $0.00003942 and $0.00000667, which is exactly 3.0x. The 3x multiplier on Functions (`nonpreemptible=True`, v1.1.2, 2025-08-14) gives the sandbox rate. | https://modal.com/pricing , https://modal.com/docs/guide/preemption , changelog v1.1.2 |
| 3 | **Low request + burst** | The request is set below the size (e.g. `cpu=(0.125, 2)`) and the sandbox bursts into spare host capacity | max(request, actual) per second, so an idle sandbox pays only the request. Bursting beyond the request depends on spare host capacity and is **not guaranteed**. | Same rates. The CPU floor is 0.125 core. The default soft limit is request + 16 cores (the gVisor guest then reports 17 CPUs at the default request). Memory is also max(req, used). The memory limit is a hard OOM kill. | https://modal.com/docs/guide/resources , https://modal.com/docs/guide/sandbox-resources |
| 4 | **Region pinned: broad** (`us`, `eu`, `ap`) | `region=` set to a broad region | Multiplier on **all resource charges**, including GPU | 1.15x. A 4/8 sandbox costs $0.873706/h. If you list several regions that span both classes, the smaller multiplier applies. | https://modal.com/docs/guide/region-selection |
| 5 | **Region pinned: narrow** (`us-west`, `uk`, `jp`, `ca`, `me`, `sa`, `af`, `mx`, `au` ...) | `region=` set to a narrow region | Multiplier on all resource charges | 1.75x. A 4/8 sandbox costs $1.329552/h. | same |
| 6 | **VM Sandbox (beta)** | Opt in to a real-kernel VM (needed for Docker, systemd, eBPF, FUSE) | CPU is elastic (burst, max(req, used)). **Memory is static**: you get and pay for exactly the request. The default is 1 GiB. | Same rates as far as published ("our rates for cpu and memory"). The root FS is capped at 512 GiB. No GPU. | https://modal.com/docs/guide/vm-sandboxes |
| 7 | **GPU Sandbox** | `gpu=` set on a sandbox | GPU per second at the standard GPU rate, plus CPU/RAM at the sandbox rate. **Preemptible.** Fallback lists bill the GPU actually allocated. H100 can be auto-upgraded to H200, and A100-40 to A100-80, **at the requested type's price**. | Per hour: T4 0.5904, L4 0.7992, A10 1.1016, L40S 1.9512, A100-40 2.0988, A100-80 2.4984, RTX PRO 6000 3.0312, H100 3.9492, H200 4.5396, B200 6.2496, B300 7.0992. Up to 8 GPUs per container (A10 max 4). GPU concurrency is 10 on Starter and 50 on Team. | https://modal.com/pricing , https://modal.com/docs/guide/gpu , https://modal.com/docs/guide/preemption |
| 8 | **Ephemeral disk request** | An explicit disk request larger than 20x the memory request | Disk is billed by **raising the memory request at 20 GiB disk : 1 GiB RAM** | Example: 500 GiB disk becomes a 25 GiB memory request, which costs $0.60/h (about $438/mo at 730 h). The default quota is 512 GiB and the max is 3 TiB. | https://modal.com/docs/guide/resources |
| 9 | **Lifecycle: running / idle** | Idle but not terminated | Billed at the full request. There is no reduced idle rate. | Same as running. `idle_timeout` terminates the sandbox; it does not pause it. | https://modal.com/docs/guide/sandboxes |
| 10 | **Lifecycle: terminated** | After timeout (default **5 min**, max **24 h**), idle_timeout, or terminate | $0 compute. There is no stopped or paused state. | Nothing | same |
| 11 | **Filesystem / directory snapshots** | You snapshot a sandbox to an Image | Storage price **not published** | TTL is 30 days by default, configurable, and can be indefinite. | https://modal.com/docs/guide/sandbox-snapshots |
| 12 | **Memory snapshots (alpha)** | `_experimental_snapshot` | Storage price **not published**. Snapshotting **terminates** the sandbox. | 7-day expiry, not extendable. No GPU, no region pinning, and the restore must use the same instance type. | same |
| 13 | **Volumes** | Modal Volumes mounted into sandboxes | Per GiB-month | $0.09/GiB-mo, with **1 TiB/mo free**. Volume reads and writes are not counted as egress. | https://modal.com/pricing |
| 14 | **Egress (new, dated)** | Outbound traffic from Modal tasks | Tracked from **2026-09-01** with no charge. **Charged from 2026-10-01**, first appearing on the bill of 2026-11-01. Counts container NIC traffic, **private container-to-container traffic** and Cloud Bucket Mount uploads. Ingress is free. | $0.04/GiB over a workspace-wide allowance: **Starter 1 TiB, Team 10 TiB, Enterprise 100 TiB**. No region multiplier is mentioned. | https://modal.com/docs/guide/network-egress-billing |
| 15 | **Plan: Starter** | Default plan | $0 fee, plus $30/mo of included compute. A payment method is required. | 3 seats max, 100 containers, 10 GPU concurrency, 200 apps, 1-day logs | https://modal.com/pricing , https://modal.com/docs/guide/billing |
| 16 | **Plan: Team** | Upgrade | **$250/mo fee, of which only $100 comes back as compute credit.** The fee is not a full credit. | Unlimited seats, 5,000 containers, 50 GPUs, 10 TiB egress, static IP proxy, custom domains, environment budgets | https://modal.com/pricing |
| 17 | **Plan: Enterprise** | Contract | Custom. Volume discounts and "compute reservations" (billing API reports "impact of any compute reservations"). AWS and GCP marketplace committed spend is accepted, but at Modal's retail rates. | Numbers not published. 100 TiB egress. HIPAA BAA, SSO, audit logs. | https://modal.com/pricing , changelog v1.5.3 |
| 18 | **Credits** | Startup / academic grants | One-time grants | Startups: amount not published. Academics: up to $10k. | https://modal.com/pricing |
| 19 | **Spend controls** | Workspace budget, spend limit (all plans), environment budgets (Team+) | A hard stop: "Modal stops workloads that would incur additional out-of-pocket charges" | n/a | https://modal.com/docs/guide/budgets |
| 20 | *Adjacent: Functions (not Sandboxes)* | Running the code as a preemptible Modal Function instead of a Sandbox | Same max(req, used) basis, preemptible | $0.04716 per core-h and $0.007992/GiB-h, one third of the sandbox rate. A 4-core / 8 GiB function costs $0.252576/h. | https://modal.com/pricing |

## Gotchas

- **The "pay by the CPU cycle" pitch doesn't hold for sandboxes as usually sized.** Billing is `max(request, actual)`, so a sandbox at 30% CPU (or fully idle) pays its full request. You only save on low utilisation if you deliberately request below your need and rely on bursting, which is not guaranteed.
- **Bursting above the request costs more.** With no `cpu=(req, limit)` cap, the default soft limit is request + 16 cores. A runaway agent process can bill you for far more cores than you asked for, so your price isn't fixed in advance.
- **"1 core = 2 vCPU" does not mean you get 2 vCPU per core billed.** The pricing page says "Physical core (2 vCPU equivalent)", but `cpu=1` gives a guest with 1 CPU (nproc 1) and half the throughput of `cpu=2`. To get what other providers call 4 vCPU you request `cpu=4` and pay for 4 cores ($0.568/h of CPU). Comparisons that price Modal "4 vCPU" as 2 cores ($0.476/h at 8 GiB, e.g. boat.dev/compare) understate it by 1.6x at this shape.
- **Sandboxes cost 3x Functions** for the same CPU and RAM. The pricing page's "non-preemptible 3x" row is already included in the sandbox rate; don't apply it twice. Third-party blogs (Beam, Blaxel) wrongly stack it again and also misquote the region multiplier as 1.5x. The docs say 1.15x.
- **Region pinning multiplies everything, GPU included.** A narrow region (e.g. `us-west`, `uk`) costs 1.75x. EU data residency needs at least `eu`, which costs 1.15x. Memory-snapshot sandboxes cannot be region-pinned at all.
- **Team costs $250, not $150 net.** Only $100 of the fee comes back as compute, so Team costs $150/mo more than Starter at equal usage. The only reasons to upgrade are more than 100 concurrent containers, more than 3 seats, static IP or custom domains, or 10 TiB of egress.
- **Egress billing starts 2026-10-01** and counts *private container-to-container* traffic, which is unusual. Sidecar and multi-container architectures that chat a lot internally can burn through the 1 TiB Starter allowance.
- **Disk is billed as memory.** Asking for a large ephemeral disk (above 20x your RAM request) silently raises your billed memory request.
- **No pause state.** A sandbox either runs (full price) or is gone. The default timeout is **5 minutes** (surprise terminations) and the hard max is **24 h**. Long-lived agents have to snapshot and recreate the sandbox. Memory snapshots are alpha, terminate the source and expire in 7 days.
- **Snapshot storage has no published price**, so the cost of retained state is an unknown, not a confirmed zero.
- **GPU sandboxes are preemptible**, while CPU sandboxes aren't. GPU fallback and auto-upgrade (H100 to H200) run at the requested type's price.
- **Starter has only 3 seats** and needs a card on file. Usage beyond $30 is auto-charged, including incremental charges when you cross spend thresholds mid-cycle. A community report (ColeMurray/background-agents #1894) describes a sandbox-spawn loop that cost about $100 over a weekend, so set a spend limit.

## Worked example

Workload: 4 vCPU (`cpu=(4,4)`, 4 Modal cores, guest nproc 4) / 8 GiB, 50 concurrent sandboxes × 8 h/day × 22 days = **8,800 sandbox-hours**, 30% CPU utilisation, 50 GiB of retained snapshots, 100 GiB egress.
50 concurrent sandboxes fit Starter's 100-container limit. 100 GiB of egress is under the 1 TiB allowance, so it costs $0. Snapshot storage is unpublished and counted as $0 (unknown).

| Regime | Compute calc | Compute $ | Plan fee | Credit | **Monthly total** |
|---|---|---|---|---|---|
| Default gVisor, Starter (request = limit = 4 cores / 8 GiB) | 8,800 × 0.759744 | 6,685.75 | 0 | −30 | **$6,655.75** |
| Default gVisor, Team | same | 6,685.75 | 250 | −100 | **$6,835.75** |
| Low request + burst, Starter (CPU billed ≈ 30% × 4 = 1.2 cores; RAM fully used at 8 GiB) | 8,800 × (1.2 × 0.141912 + 8 × 0.024012) = 1,498.59 + 1,690.44 | 3,189.04 | 0 | −30 | **$3,159.04** (burst not guaranteed) |
| Region broad `eu`/`us` (×1.15), Starter | 6,685.75 × 1.15 | 7,688.61 | 0 | −30 | **$7,658.61** |
| Region narrow e.g. `us-west` (×1.75), Starter | 6,685.75 × 1.75 | 11,700.06 | 0 | −30 | **$11,670.06** |
| VM Sandbox (beta), Starter | same rates. RAM is static, so the low-request RAM trick is unavailable. CPU could still burst. | 6,685.75 | 0 | −30 | **$6,655.75** |
| *Half cores (`cpu=2`, guest sees 2 CPUs), Starter* | 8,800 × 0.47592 | 4,188.10 | 0 | −30 | *$4,158.10* (half the CPU of the other rows) |
| Enterprise | discounts not published | n/a | custom | n/a | **unknown** |
| *Adjacent: preemptible Function, Starter* | 8,800 × 0.252576 | 2,222.67 | 0 | −30 | *$2,192.67* (not a sandbox) |

Egress sensitivity: at 2 TiB/month on Starter, you'd pay (2,048 − 1,024) × $0.04 = **+$40.96** from 2026-10-01. On Team, 2 TiB is free.
