v2 · replay a run against your latest deploy
Durable workflowsthat finish whatthey start.
Nexora runs your functions as background jobs, cron schedules and multi-step pipelines — surviving restarts, retrying on failure, and keeping every run so you can inspect or replay it.
A workflow is a function. Nexora runs it durably.
No queue to provision, no state machine to draw. Call step.run for work that should be checkpointed, step.sleep for waits, and deploy.
import { workflow } from "nexora";
export const welcome = workflow("welcome", async (step, { user }) => {
await step.run("create-account", () => db.users.create(user));
await step.sleep("wait-a-day", "24h");
await step.run("send-tips", () =>
email.send(user.email, "getting-started")
);
});What one run does
A run moves through a few states. It never holds a worker while it waits, and it never repeats work it has already finished.
- 01 Queued
An event arrives and a run is created
Every trigger — an HTTP call, a cron tick, an event from your app — creates a run with a durable ID. If nothing is free to pick it up yet, it waits in line, not in memory.
- 02 Running
Steps execute one at a time, and each result is saved
- 03 Retrying
A step throws, so Nexora backs off and tries again
- 04 Sleeping
The run sleeps for 30 seconds without holding a worker
- 05 Complete
The last step returns and the run is sealed
The parts you'd otherwise build yourself
Everything here is the reason teams write a queue wrapper in the first place. Nexora ships it as the default behaviour.
Automatic retries
Per-step retry policies with exponential backoff and jitter. Completed steps are never repeated on a retry.
Cron and schedules
Attach a cron expression and a timezone to any workflow. Schedules are versioned with your code, not clicked into a dashboard.
Concurrency and rate limits
Cap a workflow to N runs at once, or key the limit by customer so one tenant can't starve the rest.
Full run history
Every run keeps its inputs, step outputs and timings. Replay a past run against new code to check a fix before you ship it.
Local dev parity
nexora dev runs the same engine on your machine against your real workflow files. No emulator, no drift.
Type-safe SDK
Event payloads and step return types flow through end to end. Rename an event and the compiler finds every handler.
import { workflow, NonRetriable } from "nexora";
import { charge, reserve, dispatch } from "./services";
export const fulfil = workflow(
"order.fulfil",
{ concurrency: { limit: 50, key: (e) => e.data.warehouseId } },
async (step, { data }) => {
const cart = await step.run("validate-cart", () =>
validate(data.cartId)
);
// step.run checkpoints the result — a retry after this
// point never charges the customer twice
const payment = await step.run("charge-card", () =>
charge(cart.total, data.token)
);
const stock = await step.run("reserve-stock", () =>
reserve(cart.lines)
);
if (!stock.ok) {
await step.run("refund", () => charge.refund(payment.id));
throw new NonRetriable("out of stock");
}
await step.sleep("hold-for-pick", "30s");
await step.run("dispatch", () => dispatch(cart, stock.bin));
return { order: cart.id, shipped: true };
}
);Written like normal code. Recovered like a database.
The same order.fulfil from the trace at the top of the page. Every step.run is a checkpoint.
Idempotency comes from step.run, not from you. Anything already checkpointed is skipped on replay.
If the process dies after charge-card, the run resumes at reserve-stock on another worker — with the payment result it already had.
Every run is on the record
Open a run and you see its inputs, each step's output, how long it took, and every retry. Nothing to instrument — it's how the engine works.
Runs today
Success rate
Retry rate
p99 step latency
| run | workflow | trigger | took | when |
|---|---|---|---|---|
| Runningrun_8f2c41 | order.fulfil | order.placed | 2m 41s | just now |
| Completerun_8f2c40 | order.fulfil | order.placed | 3.10s | 12s ago |
| Completerun_8f2c3e | weekly-digest | cron | 1m 04s | 40s ago |
| Retryingrun_8f2c3b | order.fulfil | order.placed | 18.4s | 1m ago |
| Sleepingrun_8f2c37 | welcome | user.signup | — | 4m ago |
| Completerun_8f2c31 | invoice.send | cron | 2.02s | 6m ago |
Dispatch latency · 24h
p50 9ms · p99 41ms
3 runs retried in the last hour
all workflows healthy
p99 dispatch latency
from event received to first step running, measured at the 99th percentile across all regions.
steps run last month
each one checkpointed, so any run can be replayed or resumed after a deploy.
regions
runs execute close to your data; schedules fire on the region's own clock.
Pricing that follows your usage
Every plan is the whole engine — retries, scheduling, history, local dev. Bigger plans raise the limits and add controls for teams.
Hobby
For side projects and trying Nexora in a real app.
Start building- 100k step-runs / month
- 7-day run history
- 1 environment
- Community support
Team
Most teamsFor teams running Nexora in production.
Start a trial- 5M step-runs / month, then usage
- 90-day run history and replay
- Unlimited environments
- Concurrency and rate-limit keys
- Email and Slack support
Enterprise
For scale, compliance and dedicated regions.
Contact sales- Volume pricing
- Unlimited history and audit export
- SSO, SCIM, and per-region isolation
- SLA and a named engineer
Move the retry logic out of your codebase.
Recent
- Apr 2 Replay a past run against the current deploy
- Mar 19 Concurrency keys — scope a limit to a tenant or resource
- Mar 4 nexora dev now hot-reloads workflow files