Jev vs asynchronous jobs
An asynchronous job accepts work and finishes later. Jev still runs as a sync call inside the worker. The compare is whether the product should enqueue that call.
Unofficial operate page. docs.typesafe.ai. No keys.
Comparison scope
Bulk backfills, low-urgency triage, and “refresh labels overnight” belong on queues. Interactive gates may still be sync with a timeout.
Criteria that decide the architecture
| Axis | Jev (System One) | Asynchronous jobs |
|---|---|---|
| User ACK | 202 + job id (yours) | 200 + answer |
| Burst control | Queue depth | Client concurrency |
| Exactly-once side effects | Outbox | Harder if you act in the request |
| Jev API | Still sync in the worker | Still sync |
Decision quality and control
Jobs let you honor 429 without failing the click. They also let labels go stale — show labeled_at in the UI.
Integration trade-offs
Enqueue {ticket_id, state_hash}. Worker calls pinned Jev. Write answers + response.model. Idempotent on state_hash.
TypeSafe’s public models page lists jev-1.13 at $0.042 per million input tokens with output tokens free — a vendor claim, not a jev.pro measurement. Confirm on the models page before you bid.
When each approach fits
Prefer Jev when
- The judgment can wait seconds to hours
Prefer Asynchronous jobs when
- The user must have the answer in this HTTP response and p95 allows it
Async is how you operate Jev at burst. Sync is how Jev is served.
What this page does not claim
-
No invented job API on TypeSafe.
-
Schema-safe output is not the same as factual correctness.
-
No independent bake-off numbers live here.
When not to use Jev
Do not block a click on a Jev POST if the user can wait. Enqueue; show labeled_at when the worker finishes. TypeSafe does not host your queue.
Do not invent a TypeSafe async job API. The public evaluation call is still a synchronous POST (REST channel). Your worker hides that.
Do not retry 401/422 as if they were 429. Schema errors are poison messages — dead-letter, do not loop.
Skip a Jev hop entirely when the “job” is only a deterministic transform (see deterministic pipelines).
If the UX requires the typed answer in this HTTP response and your p95 budget allows a sync POST, put the call on the request path instead — that pairing is synchronous APIs.
Pairing-specific failure modes
- Stale labels. Overnight refresh without
labeled_atlooks live. UI must show freshness. - Non-idempotent side effects. Acting (refund, page) inside the first Jev response without an outbox double-fires on retry.
- Date math in the worker. “Older than 48h” is code on
created_at, not a Noul. - Alias in the cron. Pin
jev-1.13.0in the worker. A nightlyjev-latestis a silent model change, not a backfill.
Production sketch
- Click enqueues
{ticket_id, state_hash}and returns 202 + job id. - Worker POSTs pinned
jev-1.13.0. Honorretry-afteron 429. Dead-letter 422. - Write answers +
response.model+labeled_atidempotently onstate_hash. - Side effects go through an outbox after the write, not in the TypeSafe request.
- UI reads the stored label. Burst lives on queue depth; Jev remains a sync POST inside the worker.
Hub: Comparisons. Siblings: vs synchronous apis, vs batch processing.
FAQ
Does TypeSafe host my queue? No.
Poison messages? 422 → dead letter. Do not retry schema errors.
Is there a TypeSafe jobs product? Not in the public docs we used. You own the queue.
Disclaimer
This is an independent unofficial site and is not affiliated with TypeSafe AI; official documentation is available at https://docs.typesafe.ai. Never treat jev.pro as TypeSafe official documentation. We do not sell, issue, or proxy API keys.