Tasks
Run a Python script to completion on a matched GPU or CPU node — submit code, pick an image and hardware, stream the logs, and download the output files.
A task runs a Python script once, to completion, on a node matched to the hardware you pick. You submit the code, an image, and the hardware — Meshive schedules it, streams the logs live, uploads whatever the script writes to /outputs, and charges your prepaid credit only for the time the container actually ran.
Script (main.py + optional requirements.txt) │ Submit — image + hardware + max run time ▼Runs on a matched node ──▶ logs stream live in the console │ script exits (or hits max run time) ▼Files in /outputs uploaded ──▶ download from the consoleEverything lives under Serverless › Tasks in your workspace console.
Tasks vs Serving
Section titled “Tasks vs Serving”Serving keeps a model resident behind an always-on endpoint. Tasks run a script and stop.
| Serving | Tasks | |
|---|---|---|
| What runs | A model behind an OpenAI-compatible endpoint | Your Python script, once |
| Lifetime | Until you pause or delete it | Until the script exits (or max run time) |
| You get back | API responses | Live logs + files from /outputs |
| Billing | GPU-hour × running replicas | Runtime of the container, from prepaid credit |
Typical task workloads: batch inference over a dataset, fine-tuning a model, data preprocessing — anything with a start and an end.
Quickstart
Section titled “Quickstart”-
Open Serverless › Tasks in your workspace console and click New task.
-
Name the task.
-
Add your script — write it in the code editor, or upload
main.pyplus an optionalrequirements.txt(see below). -
Pick an image — an official template, or your own image from a custom registry (see Container images).
-
Pick hardware — a GPU model and count, or a CPU-only preset:
Preset vCPU RAM Micro 2 8 GB Small 4 16 GB Standard 8 32 GB Balanced 16 64 GB Compute 8 16 GB Compute L 16 32 GB Compute XL 32 64 GB Compute 2XL 64 128 GB Compute 3XL 96 192 GB Compute 4XL 128 256 GB High-mem 8 64 GB High-mem XL 16 128 GB A preset with no node able to host it right now is shown as Unavailable.
-
Environment variables & secrets (optional) — available to your script as regular env vars.
-
Max run time — 1 to 24 hours. The task is stopped when it hits this ceiling (see Task billing & refunds).
-
Webhook (optional) — get a signed POST when the task finishes (see Webhooks).
-
Submit. The task card shows the live status, streaming logs, and Cost so far.
You can Stop a running task at any time — you’re charged for the time it actually ran, and no webhook event is sent for a manual stop.
requirements.txt
Section titled “requirements.txt”If you attach a requirements.txt, pip install -r requirements.txt runs inside the container, before your script starts.
Container images
Section titled “Container images”| Source | Requirements |
|---|---|
| Official template | None — guaranteed to work with tasks out of the box |
| Custom registry image | Must have python (with pip, if you use requirements.txt) on the PATH |
A custom image without a working python fails at startup — that’s a user fault and is charged like any other user-code failure. Test the image locally first: docker run --rm <image> python --version.
Private registries use the registry credentials already connected to your workspace — the same ones used for custom pod templates.
Writing your script: outputs
Section titled “Writing your script: outputs”Your script starts with /outputs as its working directory. Anything it writes there is uploaded automatically after the container exits and becomes downloadable from the task’s page in the console.
- Relative writes (
open("result.csv", "w")) already land in/outputs— no path handling needed. _task.logis added automatically: a tail of the run’s log, archived alongside your files.- When the run ends, everything in
/outputsbecomes an asset in your workspace — kept until you delete it, and billed as storage if it lives in managed storage. Re-running the task adds a new version. Only_task.logfollows the log retention policy. - The upload resumes after interruptions and retries automatically for up to ~3 days; its progress and state are shown on the task page. If you don’t need the files, Discard outputs on the task page stops the transfer and releases the storage.
| Output limit | Value |
|---|---|
| Max size per file | 5 GiB |
| Max number of files | 200 |
| Output disk budget | 20 GiB |
Local disk
Section titled “Local disk”A task gets the same disk a pod does: it’s ephemeral (wiped when the task ends) and split into two parts, both counted against one on-node budget.
- System storage — the container’s working space for package installs, model/HF caches, temp files, and logs. It’s sized automatically from your hardware, the same formula a GPU or CPU pod uses:
- GPU:
max(15 + 10 × GPU count, 5)GB - CPU:
max(5 + 1 × vCPU, 5)GB
- GPU:
/outputs— a separate 20 GiB budget for the files you want back (see above).
The submit form shows both numbers for your selected hardware (e.g. a single 24 GB GPU → 25 GB system + 20 GB /outputs = 45 GB total).
Webhooks
Section titled “Webhooks”Add a webhook to be notified when a task reaches a terminal state:
| Event | When |
|---|---|
task.succeeded | Script exited with code 0 |
task.failed | Script failed — non-zero exit, OOM, eviction, install failure, or a platform fault |
task.timed_out | Max run time reached |
task.outputs_ready | Every output file has finished saving to Assets. Fires after the terminal event — outputs can still be uploading when task.succeeded arrives. |
Terminal states only (plus task.outputs_ready once the outputs land). A manual Stop sends no event.
The payload envelope matches inference webhooks:
{ "id": "evt_3f9c1a2b4d5e6f70", "type": "task.succeeded", "created_at": 1780000000, "data": { "id": "task_abc123", "name": "nightly-batch-embed", "status": "succeeded", "fault_class": "none", "exit_code": 0, "failure_reason": null, "namespace_name": "my-workspace", "gpu_model": "RTX 4090", "created_at": 1779996400, "finished_at": 1779999998, "total_cost": "0.42000000" }}fault_class—none(succeeded),user, orplatform. This is what decides whether anything is refunded.total_cost— the final, trued-up charge in credit.- Terminal payloads also carry
output_upload_state— where the output transfer stands at that moment. Wait fortask.outputs_readybefore fetching files programmatically.
Deliveries carry the same X-Meshive-Signature HMAC header as every other Meshive webhook — verify it exactly as described in Webhooks → Verifying the signature. Retries, idempotency (dedupe on the event id), and security rules are also identical.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Max run time | 1 – 24 hours |
Script + requirements.txt size | ~960 KiB combined |
| Environment variables | Up to 64, ~32 KiB total |
| GPUs per task | Up to 8 |
| Concurrent tasks | No cap — every task is paid |
| Output files | 5 GiB / file · 200 files · 20 GiB total |
- Task billing & refunds — when the meter starts and stops, the fault table, and what gets refunded.