Inngest

inngest.comcontributed by Samuele Ongaro

ALMOST

A weekend of work, and real gaps remain.

Durable background functions: steps that survive restarts, retries, sleeps that can last days, and events that fan out to many handlers.

Promptfree, for everyone, and the only version there is
Build me durable background functions that replace Inngest — and know why this is ALMOST.

The idea is genuinely valuable: **a function that sleeps for three days and resumes exactly where it stopped, across a deploy.** Reproducing it means checkpointed steps, a lease queue, and event fan-out, and none of that is exotic — but the correctness is unforgiving, because a step replayed twice does something twice in the real world. That is the verdict: buildable, and easy to get subtly wrong.

STACK
- Node 20+ with Fastify for the API and dashboard
- SQLite through better-sqlite3, WAL mode
- A worker process, or several
- Caddy in front

THE DATA MODEL
- functions: id, key, version, config_json, event_triggers_json, cron, concurrency_key, concurrency_limit, throttle_json, is_active
- events: id, name, payload_json, idempotency_key, received_at — the event log, append-only, and the thing that makes fan-out possible
- runs: id, function_key, function_version, event_id, status, attempt, queue, priority, scheduled_for, started_at, finished_at, output_json, error_json, parent_run_id
- steps: id, run_id, key, attempt, status, input_json, output_json, error, started_at, finished_at — one row per checkpoint, and the step cache
- waits: id, run_id, kind, resume_at, event_name, match_json, token, resumed_at
- queue: id, run_id, run_at, attempts, locked_by, lease_expires_at, priority
- Every step's output stored. When a function does the wrong thing at three in the morning, that record is the only thing that answers why

CHECKPOINTED STEPS, WHICH IS THE WHOLE DESIGN
- A function is ordinary code, and each meaningful operation is a named step
- A step that already succeeded returns its stored output instead of running again. A retry after a failure at step seven resumes at seven; one to six do not repeat
- Step keys must be deterministic — from the call order, or given explicitly. A key that changes between attempts breaks resumption silently, so validate it and fail loudly rather than quietly re-running
- A step calling something non-idempotent must pass an idempotency key through to that service. Sending an email twice is annoying; charging a card twice is a refund and an apology
- Never put a side effect outside a step. That rule is the one people break, and it is what makes replay dangerous

SLEEPING WITHOUT HOLDING A PROCESS
- `sleep for three days` records a resume time, releases the worker, and the run is picked up later. It is not a timer in memory, and it survives a deploy because nothing is in memory
- `wait for event` records a name and a match expression; an incoming event that matches resumes the run. With a timeout, always
- `wait for child run` resumes when a spawned run finishes
- This is what lets one small worker manage tens of thousands of runs that are mostly waiting

EVENTS AND FAN-OUT
- Send an event; every function subscribed to that name gets a run. One producer, many consumers, decoupled
- Idempotency key on the event, so a webhook delivered twice produces one set of runs
- The event log is queryable, which makes 'what happened to this order' one question rather than five

CONTROL
- Concurrency limits per function and per key, so one customer cannot starve the rest
- Throttling for functions calling a rate-limited service
- Debounce and batching for events that arrive in bursts
- Cancellation that stops at the next step boundary and marks the run cancelled rather than failed
- Retries with exponential backoff and jitter, a maximum, and a dead-letter state with a one-button replay

RELIABILITY
- The queue is a table with a lease. A worker claims a run, extends the lease, and a crashed worker's run is reclaimed when the lease expires
- Kill a worker mid-run and confirm it resumes at the right step, exactly once. That test is the acceptance criterion for the whole system

THE DASHBOARD
- Runs filterable by function, status, event and time, failures first
- A run view with every step's input, output, duration and error, and the waits and retries in the timeline
- Replay a run, and replay from a chosen step

SECRETS AND RETENTION
- Payloads are stored, so redact by key name and value match before writing, including encoded forms
- A stated retention with a sweeper — payloads are the bulk of the data

OPERATIONS
- .env: DATABASE_PATH, BASE_URL, SESSION_SECRET, EVENT_KEY, MAX_CONCURRENCY
- Migrations on boot, each once; nightly backup off the machine
- Health endpoint reporting queue depth, oldest unlocked run and expired leases

WHAT MATTERS MOST
The step cache and the lease. Get both right and everything else follows; get either wrong and the system will occasionally do something twice, which is every reason you had for building it.

What you lose

  • Durable execution, where a function sleeping for three days resumes exactly where it stopped after a deploy
  • Concurrency and throttling controls per function
  • A run history showing every step's input and output

If you would rather not build

  • A Postgres job table, which is what the prompt builds

What it costs

read from their page 15 Aug 2026

PlanBilled monthlyBilled yearlyLast read
—$99/mo—15 Aug 2026

Their pricing page is where these came from. Seeing a different price? Tell us.

The escape hatch

open source · no votes, no paid placement

Temporal

$0

Durable execution as a platform, self-hostable but operationally serious.

temporalio/temporalfree · open source

BullMQ

$0

A Redis-backed job queue with retries, delays and concurrency.

taskforcesh/bullmqfree · open source

Why this verdict

our own opinion · changed only by a person

58/100

Verdict kinda at 58. Durable execution is a step log and a replay rule; getting it right is a weekend, and the run history is what makes it debuggable.

History

tracked since 10 Aug 2026 · nothing is ever overwritten

Interest · last 30 dayspeak 1/day
views0130 Aug4 Sept9 Sept14 Sept19 Sept24 Sept28 Sept
— views— prompt copies none yet— votes none yet

Questions about Inngest

answered from the record above

Is Inngest free?

No — the plan we track is $99 a month. Pro from $99/month with a million executions included, then priced on usage; a free tier covers 50,000.

Can you replace Inngest by building your own?

ALMOST. A weekend of work, and real gaps remain. Replacement score 58 out of 100, build time a weekend. Read what you lose before you decide.

How much does Inngest cost?

$99 a month on Basic — $1,188 a year. Recorded 14 Aug 2026.

What do you lose by replacing Inngest?

Durable execution, where a function sleeping for three days resumes exactly where it stopped after a deploy; Concurrency and throttling controls per function; A run history showing every step's input and output. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Inngest?

Yes: Temporal, BullMQ. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 17 in Automation & notifications

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc