Analytical jobs
Run a linux/amd64 container image with the CPU and memory you choose, follow it through its phases and read its output.
Images
Four prebuilt, digest-pinned linux/amd64 runtimes are ready for immediate use on registry.grid.zyxio.xyz. Copy the complete image reference into image; every attempt runs that exact digest, returned as imageDigest.
Python 3.12
Includes polars, pyarrow, duckdb, pandas, psycopg, asyncpg, sqlalchemy, redis, httpx, pydantic, boto3, openai, mlflow-skinny, beautifulsoup4 and lxml.
registry.grid.zyxio.xyz/zyxioxyz/browsergrid-compute-python-3.12@sha256:5ca0336a5d50df4e398a635cf8766ebcd13ab681c064c3cf59577bbf87c5644c
Node.js 22
A prebuilt Node.js 22 runtime for JavaScript jobs.
registry.grid.zyxio.xyz/zyxioxyz/browsergrid-compute-node-22@sha256:e3e739db5f101a0bda9ce4427b4bdf96cf8f0febd47c685032c6ca6e09d1fde8
Alpine 3.21
Includes curl, jq and bash for shell jobs.
registry.grid.zyxio.xyz/zyxioxyz/browsergrid-compute-alpine-3.21@sha256:f6134bff601557bd19d05c5505ce9a349a518035943a66ef045b9d7f5521ff00
Site-QA
Includes playwright-core, a zero-trust authenticated crawler, jev visual and sitemap evaluation, and SARIF 2.1.0 and JUnit XML reporting.
registry.grid.zyxio.xyz/zyxioxyz/browsergrid-compute-site-qa@sha256:ef201048e6670458dbcd1c59c1694caed90dfdcdefa8e64dd4e496f09abd1179
Custom images
Push your custom linux/amd64 image under an admitted repository prefix, zyxioxyz/* or tenants/*, on registry.grid.zyxio.xyz, then submit its immutable @sha256:... digest. Registry push credentials are separate from your Browsergrid API key. Images outside admitted prefixes are refused. If you submit a tag, the grid resolves it at admission; pin the digest to make a later submission reproducible.
What you ask for
| Field | Meaning | Bounds |
|---|---|---|
command, args | What to run; command replaces the image's entry point. | up to 128 items each |
resources.cpu | request and limit, as 500m or 2. | 250m to 8 |
resources.memory | request and limit, as 512Mi or 4Gi. | 256Mi to 16Gi |
resources.ephemeralStorage | Scratch disk, request and limit. | 256Mi to 32Gi |
runningDeadlineSeconds | The longest one attempt may run. | 1 to 21,600 (six hours) |
retries | Automatic replays of an attempt we lose to a machine that ran short of resources (PLATFORM_EVICTED). Any other ending is final; retry it yourself if you want. | 0 to 3; default 0 |
priority | Higher runs sooner. | 0 to 10; default 0 |
capabilities.networkProfile | none, public-https or managed-services; see Network profiles below. | |
env | Environment variables. Names starting AWS_, AZURE_, BROWSERGRID_, COMPUTE_ or GOOGLE_, and a few system names, are reserved. | up to 100 |
labels | Lower-case key and value pairs you can filter GET /jobs by. | up to 20 |
idempotencyKey | Your name for this submission. Sending the same key with the same body again returns the existing job instead of a new one. | 1 to 128 characters |
env, labels, capabilities and idempotencyKey are required; {} is fine for the first two.
Network profiles
| Profile | Network access |
|---|---|
none | No network egress. |
public-https | Outbound HTTPS on TCP port 443 to the public internet. |
managed-services | Outbound HTTPS on TCP port 443, plus in-cluster TCP access to managed PostgreSQL + PgBouncer on port 5432 and managed Valkey / Redis on port 6379. |
The managed-services profile permits those service connections; you still need the instance's credentials. It does not grant general access to internal addresses. See Managed services.
Phases
ACCEPTED → QUEUED → PROVISIONING → RUNNING → PUBLISHING → SUCCEEDED, FAILED, TIMED_OUT or CANCELLED.
A finished attempt has a termination with a class and a reason. The class says how the grid treats the attempt (whether it retries it), the reason says what happened, and the reason decides what you pay:
| Reason | Class | What happened | Billed |
|---|---|---|---|
WORKLOAD_SUCCEEDED | workload | Your container exited with code 0. | yes |
WORKLOAD_FAILED | workload | Your container exited with another code. | yes |
PLATFORM_OOM | platform | Your container used more memory than its own resources.memory.limit and was stopped. | yes |
RUNNING_DEADLINE_EXCEEDED | platform | It was still running when your runningDeadlineSeconds ran out, and was stopped. | yes, up to the deadline |
CANCELLED | cancelled | You cancelled it. | yes, for the time it ran |
PLATFORM_EVICTED | platform | We moved it off a machine that ran short of resources; it is retried automatically while retries allow. | no |
PLATFORM_STORAGE_EXCEEDED | platform | The machine it ran on ran short of disk. | no |
PLATFORM_IMAGE_ERROR | platform | The image could not be pulled or started. | no |
PLATFORM_PROVISION_TIMEOUT | platform | It did not start in time. | no |
PLATFORM_INTERNAL | platform | The grid lost the attempt. | no |
Output
Write results to stdout or stderr. After each attempt the grid publishes its output as one text log, up to 1 MiB; GET /jobs/{jobId}/logs returns it, and the x-browsergrid-logs-truncated header says whether the cap was reached.
What it costs
€0.04 per vCPU-hour plus €0.0064 per GiB-hour, accrued per millisecond, on the CPU and memory you request.
- At submission the job reserves one attempt's longest cost: (vCPU × €0.04 + GiB × €0.0064) per hour ×
runningDeadlineSeconds, whateverretriesyou set. - Each attempt is charged from the moment its container starts until it finishes, never beyond
runningDeadlineSeconds, when its reason is billed in the table above: your code's own exit, your own memory limit, your own deadline or your cancellation. Queueing and start-up are free. - Failures on our side are free: every other reason costs nothing, and a replay we make after one is never charged twice.
- At most one attempt is billed per submission, so one attempt is all it holds. A replay follows only an eviction, which is free, and every billed reason ends the job: the attempts before the billed one leave the reservation untouched, and the billed one is charged against it, never more.
retrieschanges neither what is held nor what a submission can cost. - A manual retry (POST /jobs/{jobId}/retry) is a new submission: it reserves one attempt's longest cost again and, with credit enforcement on, can be refused with
402. - Resubmitting the same
idempotencyKeyreturns the existing job and reserves nothing. - When it shows: attempts are settled by a periodic pass over the grid's records, so the charge, and the release of what the job did not use, appears up to one settlement interval (30 seconds) after an attempt or the job finishes.
A 2 vCPU, 4 GiB job that runs 10 minutes costs €0.0176. See Pricing units.
Reference
POST /jobs, GET /jobs, GET /jobs/{jobId}, POST /jobs/{jobId}/cancel, POST /jobs/{jobId}/retry, GET /jobs/{jobId}/logs, GET /jobs/{jobId}/artifacts.