Journey: Reliable Background Workflows
The Brittle Reality of Job Queues
When a user submits an order, your system might need to charge a credit card, reserve inventory, and send an email out. What happens when the server crashes midway between reserving the inventory and sending the email?
Microservice developers typically reach for complex infrastructure like Celery, Sidekiq, Temporal, AWS Step Functions, or Kafka. You write convoluted compensation logic, manual retry loops, and separate out small chunks of code across different services just to ensure task reliability. It fragments your business logic.
The Vox Paradigm: Native Durable Execution
Vox gives you Durable Execution out of the box using two keywords: @workflow and activity.
You write a single function that looks like linear, synchronous code. Behind the scenes, Vox records the result of each activity in a persistent journal or VoxDB. If your server is killed midway through a workflow, upon restart Vox rapidly replays the workflow state, skips the already-completed steps natively (without re-running them), and resumes execution at the exact line of code where it left off.
Core Snippet: Surviving a Server Crash
// vox:skip
// Activities are wrapped by the workflow runtime.
activity charge_payment(amount: int, token: str) -> Result[str] {
let result = std.http.post_json("https://api.stripe.com/v1/charges", {
amount: amount,
source: token
})
return Ok(result.json().id)
}
activity send_email(user: str, message: str) -> Result[Unit] {
std.http.post_json("https://api.sendgrid.com/v3/mail/send", {
to: user,
text: message
})
return Ok(())
}
workflow process_order(customer: str, amount: int, card_tok: str) -> Result[str] {
// 1. Charge via retryable activity.
let payment_id = charge_payment(amount, card_tok)
with { retries: 3, timeout: "30s", initial_backoff: "500ms" }
// 2. Send email
let _ = send_email(customer, "Receipt for " + payment_id)
return Ok(payment_id)
}
Running the Process
-
Save the snippet into your project.
-
The orchestrator runtime requires a local state store to persist workflow states. Running:
vox run server.voxWill automatically start the journal layer mapped to your local storage.
Maturity and limitations
- Maturity:
spec_plus_runtime— durable journal v1 is contract-first; operator UX and every language keyword path should be checked against the latest ADR and compiler release notes. - Limitation ids: L-028 (completion and skeleton policy span multiple CI commands, not a single switch).
Deep Dives
To learn more about the theoretical constraints and architectural layout of Vox's durable workflows:
- Tutorial: Workflow Durability: A step-by-step walkthough of the recovery mechanism.
- Explanation: Durable Execution: Deep dive into how Vox tracks replay safety and ensures side-effect idempotency.
- Durable Workflow Journal Contract v1: The ADR dictating the storage format and constraints placed on compiled state machines.