Your code gets its own kernel.
Untrusted code in its own Firecracker MicroVM. A warm VM can serve your next run.
You describe what the work is. Ignitify derives the machine it needs, boots it, and destroys it when the work is done.
You don’t configure a runtime. You describe a workload.
You set seven axes
Cardinality, duration, state, interaction, network, residency, storage. The VM size is a preset your plan allows.
The platform derives the rest
VM lifecycle, teardown, worker instructions, network, and the boot fingerprint.
A garbage collector reclaims it
When its work ends the VM is destroyed and its slot returned to the pool. A warm or pinned VM waits for your next run first.
A rate above the host ceiling is refused — a tenant may only lower it. max_concurrent defaults to round(per_vcpu × preset.vcpu).
Rejected at deploy
Containers share a kernel. This doesn’t.
Your code runs on its own kernel inside a MicroVM, and a warm VM can serve your next run. One tenant’s code cannot read another’s memory, reach another’s filesystem, or talk to another’s network — not because a policy forbids it, but because there is no shared surface to cross.
Separate kernel
Not a namespace on a shared one. A hypervisor boundary, not a container boundary.
Nothing shared
Its own uid, its own root filesystem, its own network path.
Verified, not assumed
Cross-tenant and guest→host traffic are dropped at the packet level.
Two files to write. Export run. That’s the contract.
This is a complete, real task — the whole developer surface in one screen. The Node version has no imports; Go and Rust import a small bundled client. The starter also holds a package.json and its lockfile, so a Node task has four files to deploy.
schema_version: 1 slug: streaming-job runtime: node execution: cardinality: one duration: short state: independent interaction: continuous network: type: egress build: system_packages: [ffmpeg, git] run: payload: q: war timeout_sec: 15
export async function run(payload, ctx) { const res = await fetch( `https://api.datamuse.com/sug?s=…`, ); const json = await res.json(); const top = json.map((w) => w.word).slice(0, 5); for (const [i, suggestion] of top.entries()) { ctx.chunk({ suggestion, i }); } return { q: payload.q, count: top.length }; }
$ ignitify task:create streaming-job ✓ Task Registered task_id 019fdebb-171e-7198-a812-a755d67e0aa2 resource_id tsk_EZWekgdGJSLt $ ignitify task:deploy streaming-job ✓ Deployment Created deployment_id 019fdebb-199b-75cc-8a15-650f3de2c717 status READY reused false content_hash sha256:fbb55da6adde4995… $ ignitify task:run streaming-job ✓ Run Submitted run_id 019fdebb-1ce5-7048-bc36-ce8821f02c08 status PENDING
Content-addressed
Deployments are immutable and hashed. Unchanged source reuses the existing image.
Image integrity
The code image is read-only inside the guest. It is verified before boot, not trusted after it.
Secrets
Only secret names enter the upload. Values are injected at run time.
Start with nothing installed.
What you get today, and what is honestly still ahead.
Easy to start
Export run() — that is the contract. In Node and Python that is all — no client, no framework. Go and Rust import a small client that task:create copies in.
An SDK for logs, metrics and more — soonNode.js, Python, Go & Rust
Pick a runtime in task.yaml. Go and Rust compile to a binary and run on the same task image — no separate runtime image to manage. A binary that needs a system library the image lacks is caught at deploy.
One CLI
ignitify — every task, deployment, run and secret from one command line.
Telemetry that leaves the box
Runs emit structured events to pluggable sinks.
Custom Observability — coming soonPer-run timelines
Every run leaves a per-tenant, append-only timeline of what happened and when.
Visualizer — coming soonOne noisy tenant can’t take the host down with it.
Running this for other people is a different job from running it for yourself. The controls for that are first-class, not bolted on.
Tiers, not overrides
Every limit a tenant has comes from a tier they are granted. A one-off deal is a new tier.
Fair queueing
One tenant’s deploy storm cannot starve another’s build. The work queue claims fairly across tenants.
Honest capacity
Entitlement and room are separate ledgers, so “allowed” and “available” are never conflated.
From your machine
to a MicroVM in one crossing.
- 01
task:create
Scaffolds task.yaml and an entry file. Add --local to stay fully offline.
Reserves the slug and gives the task a stable id.
- 02
task:validate
Checks the execution nature and the seven axes against the platform's own rules.
Nothing leaves your machine.
- 03the crossing
task:deploy
Uploads your source and lockfile as they are. Nothing is built on your machine.
- in its own microVM
- the result, hashed
- the image, by digest
- 04
task:run
Submits a job and returns its id at once.
Boots a MicroVM against that image and executes your run().
- 05
run:get
Asks for the status and result.
Returns the status, the result and the last streamed chunk.