# inngest-dotnet > inngest-dotnet is a community Inngest SDK for .NET. It runs durable functions and background workflows written in C#: steps that run once and retry on their own, sleeps and waits for events that last days, parallel steps, and flow control such as concurrency, throttling and rate limits. Functions are served from an ASP.NET Core endpoint, from Azure Functions or AWS Lambda, or from a Connect worker. Durable endpoints, in beta, let an ASP.NET Core endpoint run steps and answer its caller directly. It is not affiliated with or endorsed by Inngest Inc. The API is not the TypeScript SDK's. Steps are methods on `context.Step`, such as `RunAsync` and `SleepAsync`, a function is a class or a delegate, and an event's data is a record. Read [Writing Inngest .NET code with AI coding assistants](https://damikun.github.io/inngest-dotnet/guides/ai-assistants.md) before writing code with it. Every page is also a Markdown file next to its web page, at the same address with `.md` in place of the trailing slash. [llms-full.txt](https://damikun.github.io/inngest-dotnet/llms-full.txt) holds all of them in one file. ## Start here - [Inngest .NET SDK for durable functions and workflows](https://damikun.github.io/inngest-dotnet/index.md): inngest-dotnet is an Inngest SDK for .NET. Write durable functions and background workflows in C# with steps that retry, sleep and wait for events, served from ASP.NET Core, Azure Functions, AWS Lambda or a Connect worker. - [How Inngest runs .NET functions](https://damikun.github.io/inngest-dotnet/how-it-works.md): How durable execution works with the Inngest .NET SDK. Inngest calls your ASP.NET Core endpoint once per step, the function replays saved step results and answers 206 or 200. Step through a real run. - [Getting started with Inngest in ASP.NET Core](https://damikun.github.io/inngest-dotnet/guides/getting-started.md): Add the Inngest .NET SDK to an ASP.NET Core app, write a first durable function in C#, run it against the Inngest dev server and watch each step run. - [Project templates and the dotnet inngest command](https://damikun.github.io/inngest-dotnet/guides/templates-and-tools.md): Start an Inngest app with dotnet new inngest-web or inngest-worker, and run the Inngest dev server for it with dotnet inngest dev, which downloads the Inngest CLI, checks its SHA-256 and finds the app in its launch settings. - [Writing Inngest .NET code with AI coding assistants](https://damikun.github.io/inngest-dotnet/guides/ai-assistants.md): The names that differ from the TypeScript SDK and the rules that keep a function correct when it replays, for AI coding assistants and the people who use them, with a block for AGENTS.md, CLAUDE.md or Cursor rules. ## Writing functions - [Functions, event triggers and cron in C#](https://damikun.github.io/inngest-dotnet/guides/functions-and-triggers.md): Define Inngest functions as classes or delegates, with their options as attributes or in code, type their events, and start them from events, filtered events or cron schedules. - [Durable steps: RunAsync and step ids](https://damikun.github.io/inngest-dotnet/guides/steps.md): How RunAsync and the other step tools make code durable, how step ids work, and what to keep in and out of steps. - [Scoped steps and Entity Framework Core](https://damikun.github.io/inngest-dotnet/guides/scoped-steps.md): Run a step in a dependency injection scope of its own with RunScopedAsync, so a DbContext never carries state from one step or call to the next, and write database steps that are safe to retry and replay. - [Parallel steps with Task.WhenAll](https://damikun.github.io/inngest-dotnet/guides/parallel-steps.md): Run steps at the same time with Task.WhenAll and Task.WhenAny, how Inngest executes them, and what to watch out for. - [Fan-out over a list](https://damikun.github.io/inngest-dotnet/guides/fan-out.md): Run a step for each item of a list with a limit on how many run at once, get the results back in order, stop at the first failure or collect every outcome, and send lists too long for one run to child runs in chunks. - [Sleep and wait for events in a workflow](https://damikun.github.io/inngest-dotnet/guides/sleep-and-wait-for-events.md): Pause a run for a duration, until a point in time, or until a matching event arrives, without holding a thread, a request or a worker. - [Invoking functions from other functions](https://damikun.github.io/inngest-dotnet/guides/invoking-functions.md): Run another Inngest function from a step with InvokeAsync, by its class or its id, pass it data, get its typed result back, and handle failures and timeouts. - [Sending events from .NET to Inngest](https://damikun.github.io/inngest-dotnet/guides/sending-events.md): Send events to Inngest from application code with IInngestClient and from functions with SendEventAsync, with ids for deduplication, delayed starts and retries. - [Transactional outbox](https://damikun.github.io/inngest-dotnet/guides/outbox.md): Save events in the same database transaction as your data with Inngest.EntityFrameworkCore, and let a hosted dispatcher send them to Inngest afterwards, under the same id on every attempt. - [The user behind an event in Inngest functions](https://damikun.github.io/inngest-dotnet/guides/user-context.md): Carry the signed-in user who caused a run into it with Inngest.UserContext, protected with ASP.NET Core Data Protection, and read it as ICurrentUser or ClaimsPrincipal in functions, steps, failure handlers and the events they send. - [Webhooks](https://damikun.github.io/inngest-dotnet/guides/webhooks.md): Receive webhooks from Stripe, GitHub, Shopify, Clerk, Resend and other providers in ASP.NET Core, verify their signatures before anything else, and send each as an Inngest event whose id is the delivery id, so that a redelivery starts no second run. - [Realtime](https://damikun.github.io/inngest-dotnet/guides/realtime.md): Publish updates and streams of text from a run, receive them in .NET, and relay them to browsers, through Inngest Realtime. - [Realtime in Blazor](https://damikun.github.io/inngest-dotnet/guides/blazor.md): Show Inngest realtime messages in Blazor Server, WebAssembly and interactive Auto with the RealtimeView component of Inngest.Blazor, or read them as an async stream from IRealtimeSource. - [SignalR: realtime messages for SignalR clients](https://damikun.github.io/inngest-dotnet/guides/signalr.md): Forward Inngest realtime messages to the clients of a SignalR hub with Inngest.SignalR, authorize who may join a channel, and scale out on Redis or Azure SignalR Service without duplicates. - [Durable endpoints in ASP.NET Core](https://damikun.github.io/inngest-dotnet/guides/durable-endpoints.md): Make an ASP.NET Core endpoint durable, so that its handler runs steps like an Inngest function, answers the caller directly and hands the run to Inngest when a step has to wait or fails. - [Chat clients as steps with Microsoft.Extensions.AI](https://damikun.github.io/inngest-dotnet/guides/ai.md): Make the model calls and tool calls of an IChatClient steps of an Inngest run, so that a retry or a replay never calls the model or a tool twice. ## Reliability - [Concurrency, throttling and rate limits](https://damikun.github.io/inngest-dotnet/guides/flow-control.md): Concurrency, throttling, rate limits, debounce, batching, priority, idempotency, singletons, cancellation and timeouts, set in FunctionOptions or with attributes and enforced by Inngest. - [Errors, retries and failure handlers](https://damikun.github.io/inngest-dotnet/guides/errors-and-retries.md): How failed steps and functions are retried, how to stop or delay retries with exceptions, how to recover from a failed step, and how to run code when a function fails for good. - [Middleware for Inngest functions](https://damikun.github.io/inngest-dotnet/guides/middleware.md): Observe and wrap function runs, steps and event sends with InngestMiddleware, for logging, metrics, tracing, error mapping, event enrichment, encryption and reporting errors to Sentry. ## Running and shipping - [Configuration and environment variables](https://damikun.github.io/inngest-dotnet/guides/configuration.md): Every InngestOptions setting, the INNGEST_* environment variables they fall back to, dev and cloud mode, and settings for proxies, branch environments and self-hosted Inngest. - [Connect: workers without a public endpoint](https://damikun.github.io/inngest-dotnet/guides/connect.md): Run functions in a worker that holds an outbound WebSocket to Inngest, with no public endpoint, using Inngest.Connect and AddConnect. - [Aspire: the Inngest server in your AppHost](https://damikun.github.io/inngest-dotnet/guides/aspire.md): Run the Inngest dev server or a self-hosted server as a container of an Aspire AppHost, link its UI in the dashboard, and give projects the settings the SDK reads, with Inngest.Aspire.Hosting. - [Testing Inngest functions with xUnit](https://damikun.github.io/inngest-dotnet/guides/testing.md): Unit test Inngest functions on the test host of Inngest.Testing, which replays them on the real execution engine with mocked steps, or with a fake IStepTools, and test them end to end against the Inngest dev server. - [Testing against a real Inngest server](https://damikun.github.io/inngest-dotnet/guides/testing-with-containers.md): Start the Inngest dev server or a self-hosted server in Docker from your tests with Inngest.Testing.Containers, point an app at it and sync it, and run an ASP.NET Core app under WebApplicationFactory with Inngest.Testing.Containers.AspNetCore. - [Native AOT and trimming](https://damikun.github.io/inngest-dotnet/guides/native-aot.md): Publish an app with Inngest functions as a trimmed or Native AOT binary by giving the SDK source-generated JSON metadata for your types. - [Source generator and analyzers](https://damikun.github.io/inngest-dotnet/guides/source-generator.md): Register every function class of a project with one generated call, and find the types a Native AOT app has not given its JsonSerializerContext while the project builds. - [Deploying background jobs to production](https://damikun.github.io/inngest-dotnet/guides/deploying.md): Run an app with Inngest functions in production, in a container or anywhere ASP.NET Core runs, with cloud mode, keys, syncs and health checks. - [Running on AWS Lambda](https://damikun.github.io/inngest-dotnet/guides/aws-lambda.md): Serve the Inngest endpoint from an AWS Lambda function behind API Gateway or a function URL, as a managed runtime function or a Native AOT executable, and plan around the timeouts and sizes of the platform. - [Inngest in Azure Functions](https://damikun.github.io/inngest-dotnet/guides/azure-functions.md): Serve the Inngest endpoint from an HTTP-triggered function of an Azure Functions app in the isolated worker model, run it locally with func start, and work within the 230-second response limit. ## Examples - [Order fulfillment workflow in C#](https://damikun.github.io/inngest-dotnet/examples/order-fulfillment.md): Reserve stock, charge the card, ship and confirm an order, release the stock when payment fails, cancel on request and alert someone when a run fails for good. - [User onboarding with waits and reminders](https://damikun.github.io/inngest-dotnet/examples/user-onboarding.md): Welcome a new user, wait up to three days for them to activate their account, remind them if they do not, and stop when the account is deleted. - [Nightly billing with cron and fan-out](https://damikun.github.io/inngest-dotnet/examples/nightly-billing.md): A cron function that finds every account due for billing and fans out one event per account, and a second function that bills each account with its own retries and limits. - [Fan-out with invoke and Task.WhenAll](https://damikun.github.io/inngest-dotnet/examples/fan-out-with-invoke.md): Build a weekly report from per-region figures by invoking one function per region in parallel, and finish the report even when a region fails. - [Webhook processing with idempotency](https://damikun.github.io/inngest-dotnet/examples/webhook-pipeline.md): Accept payment webhooks quickly, turn each delivery into one event, and process it with idempotency, a per-merchant throttle and retries that respect the downstream API. - [Scheduled reminders with sleep and cancel](https://damikun.github.io/inngest-dotnet/examples/scheduled-reminders.md): Sleep until a user's reminder is due, cancel it when the reminder is deleted, and replace the pending run when the reminder is moved. - [Background worker with Inngest Connect](https://damikun.github.io/inngest-dotnet/examples/connect-worker.md): A background worker with no HTTP endpoint that runs Inngest functions over Connect, with a web app that only sends events, a Dockerfile and graceful shutdown. - [Tracing runs with OpenTelemetry](https://damikun.github.io/inngest-dotnet/examples/tracing-middleware.md): Wrap every function call and step in an OpenTelemetry activity with InngestMiddleware, with tags for the function, the run and the step. ## Reference - [C# API overview](https://damikun.github.io/inngest-dotnet/reference/api.md): The public types of the Inngest, Inngest.AspNetCore, Inngest.AwsLambda, Inngest.AzureFunctions, Inngest.Blazor, Inngest.Connect, Inngest.Aspire.Hosting, Inngest.OpenTelemetry, Inngest.Encryption, Inngest.Sentry, Inngest.SignalR, Inngest.EntityFrameworkCore, Inngest.Extensions.AI, Inngest.Testing, Inngest.Testing.Containers, Inngest.Testing.Containers.AspNetCore, Inngest.UserContext, Inngest.UserContext.AspNetCore and Inngest.Webhooks packages, the method and diagnostics of the source generator in Inngest, the templates of Inngest.Templates and the commands of dotnet-inngest, with what they are for. ## Optional - [Function options builder](https://damikun.github.io/inngest-dotnet/explainers/function-options.md): Build a function's options in the browser and see them as attributes and in code, the JSON the SDK sends to Inngest when the app syncs, and which attribute sets each option. - [Flow control timeline](https://damikun.github.io/inngest-dotnet/explainers/flow-control.md): See how concurrency, throttling, rate limiting and debouncing change when the runs for a burst of events start. - [Roadmap](https://damikun.github.io/inngest-dotnet/roadmap.md): What each release of the Inngest .NET SDK added, from the test host of the first preview to realtime, durable endpoints, webhooks and hosting on AWS Lambda and Azure Functions in 1.0.0, and what comes next. - [Deployment readiness](https://damikun.github.io/inngest-dotnet/internals/readiness.md): Before recommending the SDK for containers and the cloud, we ran it the way production runs it: in Docker against Inngest's own server image, in dev mode... - [Benchmarks](https://damikun.github.io/inngest-dotnet/internals/benchmarks.md): benchmarks/Inngest.Benchmarks measures the work the SDK does on every call from Inngest: parsing the request, replaying memoized steps, writing the answer... - [Design](https://damikun.github.io/inngest-dotnet/internals/design.md): This document describes how the .NET SDK is put together and the wire protocol it speaks. It is written for people working on the SDK; the README covers usage.