Substructure vs. Inngest for AI agents

Checked August 7, 2026

Inngest is event-driven durable execution. You write step functions in your own codebase, things like step.run, step.sleep, and step.waitForEvent, and Inngest orchestrates them with retries and checkpointing. For AI work it adds AgentKit, a TypeScript framework for building agents and multi-agent networks, and step.ai.infer, which offloads LLM calls so a serverless function does not pay for the wait.

Substructure starts from the other end. You get a working agent from one config file: connected to Slack, holding MCP servers, your team's to use. Think of it as a default agent. Then the webhook worker lets you override every single step of its loop, which is more control than most agent SDKs hand you. Code enters the picture exactly where you want it, and nowhere else.

And to be clear: durability is table stakes here. Inngest checkpoints steps. Substructure saves every step before it runs. Both survive crashes, and neither of us gets credit for that anymore. What separates the two is how much you have to assemble before anyone on your team can talk to an agent.

The short answer

Pick Inngest when you are a TypeScript team that wants durable background jobs of every kind, and agents are functions like the rest, assembled with AgentKit inside your own app. Pick Substructure when you want a working agent in Slack this afternoon, with MCP auth, conversation history, and streaming already handled, and with your own code in the loop only when you choose to put it there.

What you build

AgentKit gives you real primitives: createAgent, createNetwork, routers, shared state, MCP tool loading. What it does not give you is the product around them. The app that hosts the network, memory beyond a single run, the Slack app, MCP authorization, the approval UI. Those are yours to build, in TypeScript, since AgentKit is TypeScript-only and still pre-1.0. Human approval is a documented pattern rather than a feature: a tool calls step.waitForEvent() and you build the surface that sends the resuming event.

Here is the Substructure version of all of that:

substructure.toml
[agent.oncall]
llm = "openrouter"
model = "z-ai/glm-5.2"
system = "You are the on-call assistant."
mcp = [{ id = "sentry", tools = { read_only = true } }]
worker = "https://example.com/agent"   # optional: your code in the loop

[slack]
mentions = "oncall"

Run subs apply and the bot answers in Slack threads. The engine authorizes Sentry and runs every tool call, so your code never holds a token. Human approval and conversation branching are engine features, not patterns you implement. And that worker line is doing more than it looks like: the engine sends every decision in the loop to that URL as JSON, and your endpoint can accept the step, rewrite the prompt, swap the model, or run the tool inside your own system. Every single step is overridable. And because the engine owns all the state, your endpoint is a plain stateless function: state in, decision out, nothing to keep alive between calls. You answer in whatever language your team already writes, because it is just HTTP. A Rails app or a Go service works as well as Node.

Streaming

Credit where due: Inngest's streaming is genuinely good. Realtime pub/sub plus the useAgent React hook stream runs to the browser durably, on their own protocol. Substructure emits AG-UI events, an open protocol that assistant-ui, CopilotKit, and other clients already speak, and the same events drive Slack. Their ecosystem, or an open one. Pick honestly.

Source and pricing

Inngest self-hosting exists as a single binary or Docker, with Postgres and Redis for multi-node. But look at the license: the server was SSPL and is now fair-source, meaning each release becomes Apache 2.0 three years after it ships. The SDKs and AgentKit are Apache 2.0 today. Substructure's engine is open source now, and the self-hosted engine serves the same APIs as the cloud, so the same file describes both.

On price, Inngest meters executions: a run plus every step counts, so an agent that thinks in many steps multiplies its own bill. The Pro plan is $99 a month with 1M executions, and your compute on Vercel or Lambda or your servers bills separately, because Inngest never runs your code. Substructure is one flat price. The engine runs the loop, you bring your own LLM key, and there are no per-step or per-token charges from us. Your bill does not change when your agents get busier.

Where Inngest is the right call

Flow control is Inngest's best feature and nobody near it does better: per-key concurrency, throttling, debounce, and priority as one-line config. If you need durable billing pipelines, ETL, and drip campaigns plus some agents, one platform covers all of it. step.ai.infer is the right shape for serverless economics. And if your team wants the whole agent expressed as TypeScript in your own repo, AgentKit is a real framework with real streaming.

But if you would rather the agent infrastructure be someone's product instead of your project, that is Substructure. The quick start takes about five minutes.