Show HN: Inngest 1.0 – Open-source durable workflows on every platform (inngest.com)
Inngest is an open-source durable workflow platform that works on any cloud. Durable workflows are stateful, long running step functions written in code, which automatically retry on failure. It abstracts everything about queues, event streams and state for you, letting you focus on code. Some examples of uses: managing stateful AI chained step functions; managing search/rag indexes and data pipelines; integrations and webhooks; billing and payment flows.
Technical details: unlike other solutions, we put lots of effort into designing our SDK’s step.run APIs to make them extremely easy to use — developer experience is the most important thing for us.
We had to design and build our own queueing system to work with multi-tenancy, batching, and debouncing, and we’re iterating on this as we move to FoundationDB. It’s largely all Go in the backend, with a bunch of caching, clickhouse, event streams, and coordination on our behalf. Workers are shared nothing, and run based off of the queue and execution state.
We did a post last year as we iterated on our TS SDK. The product has changed a lot since then and wanted to show the community what’s changed as we reach 1.0:
* Golang, Java, and Python SDKs with cross-language function invocation (across clouds, too)
* Multi-tenant aware flow control (concurrency, throttling, debounce)
* Batching, grouping many events into a single function call
* Much improved dashboard, with tracing and metrics built in
* Advanced recovery tools like function replay, temporary pausing, bulk cancellation (with optional expressions). No more dead letter queues!
* Branch deploys built in, with staging env support out of the box
* Full local testing with production parity
There's a ton on the roadmap, with more launching next week. We’re hiring systems & infra engineers, too — it’s a fun job with lots of challenges!Wanted to say thank you to the HN community for feedback so far! Happy Friday :)
54 comments
[ 4.0 ms ] story [ 115 ms ] threadIn general, fairness means distributing work evenly amongst all accounts. This largely means partitioned queues. Firstly, every functions have their own queues. We have queues of queues: queues of functions available. And then we have queues of accounts. And so on. It's like nesting dolls all the way down.
There are lots of really fine details to get right: continuations, step parallelism, `connect()` with long running workers all mess with fairness, as do batching, debounce, throttling.
We wrote about it in some detail here: https://www.inngest.com/blog/building-the-inngest-queue-pt-i.... We'll probably do some deeper dives on this next year, too!
Congrats on the big one-oh. Question: I’ve been using Rust a lot more lately — does Inngest work natively with Rust? Is there an SDK or another way to use it?
Looks great but do not appreciate deceptive marketing
SSPLv1 for anyone similarly interested https://github.com/inngest/inngest/blob/v1.0.0/LICENSE.md
Seems they had a change of heart around 2022: https://github.com/inngest/inngest/pull/81 but they actually only started lying about the license in this go-around because their previous Show HN <https://news.ycombinator.com/item?id=36403014> not only didn't mislabel things but they even said "we're gonna open source in the future" but I guess the future isn't here yet
Of course you're free chose the license what is right of your business, but trying to use Open Source name in deceptive marketing is the problem.
I've written quite a lot of CI for projects because it's something I believe in and am willing to roll up my sleeves to get done (as a concrete example). I believe strongly that being able to reference the canonical CI build helps contributors since they can see how it's built for different systems and also ensure they don't submit "works on my machine" patches
Earlier this year we didn't want folks to roll their own production cloud due to queueing migrations. It would make your life hard. We're entirely responsible for that right now, as we discouraged self hosting.
That's actually coming to a close, and we'll make it easy to spin up prod clusters using this code and eg. MemoryDB, Dragonfly, or what have you.
My only issue was that the execution of an inngest function wasn't completely intuitive, at least in TS, and you have to think in terms of inngest or, more precisely, the abstraction it is providing. Is it an actor, a step function, an event consumer, a saga? or a combination of some?
When you get used to it it's nice, less overhead than building your own actor model or your own event sources, and really good visibility into what is happening.
I'm personally curious about this. I'm not saying you don't, but why would you need to understand what kind of abstraction it is beyond it just being Inngest"? I like to think I've been able to use it effectively without this having ever crossed my mind. But I also just might be dumb. Hence the curiosity!
You have to be careful about how you structure effectful code and how you might share data between steps, and you have to understand when that code might be executed, so the more you know about that, the better. Inngest itself, at least with Vercel, doesn't do its own compute.
Inngest, as far as I know, does not do its own compute, it piggybacks on your own, so if you're not careful you can go hard with inngest but you'll see the impact on your hosting bill; especially with Vercel.
Inngest is a breath of fresh air but, you know, you have to audit your dependencies whether they're SaaS or not. Know how they work, know how to debug them, know how much they'll cost you.
Disclaimer: CEO of DBOS here (Ingest competes with some of what we do).
DBOS provides compute and we don't charge for CPU wait time, so bills are a lot cheaper with our solution.
A few critical things:
* Inngest is primarily event driven. You send an event, we run one or more functions.
* Events give you lots of benefits: batching, rate limiting, replay, archiving, fan-out, etc.
* You also get a powerful event-based API in functions: `step.waitForEvent`. This lets you do a lot of things: human in the loop flows, coordination — and you don't have to learn complex APIs, worry about state, can handle timeouts easily.
* And events also let you connect things like webhooks, CDC, external systems to functions with basically zero overhead.
* Because of this, you can pause individual functions, then redrive events through specific functions - as events are stored for you in an OLAP event store for your workspace.
Fundamentally, in terms of DX:
* You don't have to register individual activities and workflows. Steps are lambdas. It's easy to work with
* Every step (activity) has an ID, which means versioning, replay, determinism is easier to reason about and see in our model.
* We also run on servers as well as serverless. It's actually quite nice bringing state and retries to serverless functions - they're good for (some) bursty workloads
* We also embed a bunch of flow control into the system for you.
Overall, both replace queueing systems. I think that's a good thing: you shouldn't really have to think about the specifics of your underlying infra when you're writing application code.
While the edit window on your comment is still open, you may want to consider removing the leading whitespace from your bullet points (since they're already newline delimited) because on HN those leading spaces make it pre-formatted and that means folks on mobile have to horizontally scroll to see your whole sentence
Afaict, this seems like a more restrictively licensed & less capable alternative to Dagster and Prefect. However, there may be some specific areas it is ahead -- the multitenancy bullet point sounds interesting, for example. Maybe you can share a comparative description?
The TL;DR is both us and Temporal help with durable execution. We layer on events and a differing DX to make things easier, faster, and to also work on serverless if people need.
I can't speak to Trigger, as they've changed a lot since I last looked. It doesn't look like they do durable execution, workflows, steps, or events — it looks like they're an alternative to Lambda + SQS for TS only, so very different — more for your simple "run one thing in the background", from what I can gather. Take this with a grain of salt, though!
Amazing devEx. Thanks so much for all the work and enabling a local mode too
It's good to see the ecosystem form around the APIs we've developed. From feedback we've received, they're easy to use.
[2] https://docs.dbos.dev/python/tutorials/transaction-tutorial
if scale is low, it's not an issue. but once you have high usage, what typically people do is they move it to a separate database, otherwise you're saturating the resources and it starts impacting the application itself.
at that point, that's not much different from external state stored else where.
also another thing about databases is their ACID transactions can only handle up to certain amount of load. again, if you don't hit that limit, it's totally fine. once you do, which usually means outages, severe delays, etc, and it'll be a shit show.
disclaimer: I do work at Inngest, but also this is speaking from experience. :)