Pipelines

Serverless pipelines, cron jobs, and background work

Run cron jobs, webhook-triggered workflows, and multi-step background jobs as serverless pipelines — staged work, retries, and fan-out built on the same functions that serve your live HTTP API.

Related guides and docs

Get started free

How serverless pipelines work

1

Define steps

Pick existing functions as pipeline steps, then wire up their inputs, outputs, and the dependencies between them.

2

Connect and schedule

Link steps into a DAG or a sequential chain, then add cron triggers or webhook listeners so runs start automatically.

3

Monitor in real time

Watch each step's status, logs, and output live, and replay a failed step without re-running the whole pipeline.

Built for real workflows

DAG execution

Steps run in parallel whenever their dependencies allow, with full dependency resolution handled out of the box.

Webhook triggers

Trigger a pipeline from the API or the UI and pass a structured payload straight into the first step.

Manual approval

Pause execution at any step and require a human sign-off before the pipeline proceeds.

Cron scheduling

Schedule pipelines with a plain cron expression — daily reports, batch jobs, cleanup tasks.

Pipelines reuse the same functions you expose through the gateway.

Pipelines vs direct functions vs async jobs

Use pipelines

Reach for pipelines when cron jobs, webhook-triggered workflows, or background jobs need retries, branching, fan-out, or staged orchestration across several functions.

Use direct functions

Stick with a direct function when a single HTTP request can finish quickly in one gateway handler — no cron, no webhooks, no multi-step state.

Use async jobs

Use async jobs when callers should return immediately and all you need is a queued background job, not a full DAG across many steps.

DAG pipeline (manual trigger)

customer-support-pipeline.json
{
  "schemaVersion": 1,
  "nodes": [
    { "id": "t1", "kind": "manualTrigger", "name": "Start", "position": { "x": 0, "y": 0 }, "config": {} },
    { "id": "n1", "kind": "lambda", "name": "Classify intent", "position": { "x": 240, "y": 0 }, "config": { "functionId": "intent-classifier", "onError": "failPipeline" } },
    { "id": "n2", "kind": "lambda", "name": "Billing agent", "position": { "x": 480, "y": 0 }, "config": { "functionId": "billing-agent", "onError": "failPipeline" } },
    { "id": "r1", "kind": "respond", "name": "Done", "position": { "x": 720, "y": 0 }, "config": { "statusCode": 200, "bodyMapping": { "ok": true } } }
  ],
  "edges": [
    { "id": "e1", "sourceNodeId": "t1", "targetNodeId": "n1" },
    { "id": "e2", "sourceNodeId": "n1", "targetNodeId": "n2", "sourceHandle": "success" },
    { "id": "e3", "sourceNodeId": "n2", "targetNodeId": "r1", "sourceHandle": "success" }
  ]
}

Sequential example (nightly processing)

nightly-sequential-pipeline.json
{
  "schemaVersion": 1,
  "nodes": [
    { "id": "cron", "kind": "cronTrigger", "name": "Nightly 02:00", "position": { "x": 0, "y": 0 }, "config": { "cron": "0 2 * * *", "timezone": "UTC" } },
    { "id": "extract", "kind": "lambda", "name": "Extract", "position": { "x": 240, "y": 0 }, "config": { "functionId": "nightly-extract", "onError": "failPipeline" } },
    { "id": "transform", "kind": "lambda", "name": "Transform", "position": { "x": 480, "y": 0 }, "config": { "functionId": "nightly-transform", "onError": "failPipeline" } },
    { "id": "publish", "kind": "lambda", "name": "Publish", "position": { "x": 720, "y": 0 }, "config": { "functionId": "nightly-publish", "onError": "failPipeline" } }
  ],
  "edges": [
    { "id": "e1", "sourceNodeId": "cron", "targetNodeId": "extract", "sourceHandle": "default" },
    { "id": "e2", "sourceNodeId": "extract", "targetNodeId": "transform", "sourceHandle": "success" },
    { "id": "e3", "sourceNodeId": "transform", "targetNodeId": "publish", "sourceHandle": "success" }
  ]
}

Get started free

Deploy your first function in minutes. No credit card required.

Get started free