AIAI EngineerJun 3, 2025· 13:32

How agents broke app-level infrastructure - Evan Boyle

Evan Boyle, founder of GenSX, argues that LLM-powered agents have broken assumptions about app-level infrastructure, as p1 latency jumps from milliseconds to seconds and workflows run minutes to hours. He explains that traditional serverless providers timeout after 5 minutes, lack native streaming, and force brittle Rube Goldberg machines on top of queues like SQS or tools like Airflow. Boyle presents an open-source library that separates API and compute layers using Redis streams for resumability, enabling users to refresh pages or navigate away without losing progress. He demonstrates components with built-in retries, caching, and tracing, and a workflow that automates Hacker News analysis. Key architectural lessons include starting simple but planning for long-running agents, keeping compute and API planes separate, and leaning on Redis for resumability.

Transcript

Intro0:00

Evan Boyle0:03

How agents broke infrastructure—particularly, we're going to focus on the compute layer today.

My name is Evan Boyle, founder and CEO of Genesx. I was an early employee at Pulumi, and I've spent my entire career working on cloud and developer tools. Typo warning: in the spirit of embracing AI for this talk, all diagrams are AI-generated, but 4.0 still has some spelling issues, so thank you for your patience.

We all know this journey: we start off as AI engineers with a simple prompt and a couple of tool calls, and typically this is enough to raise our $10 million seed round. But from there, when rubber meets the road, we end up building workflows,right?

The Journey0:30

Evan Boyle0:44

We take that fully non-deterministic code and make as much of it deterministic as possible. That might mean chaining a couple of very specific, tailored prompts together that we've written evals against, and more carefully controlling the context. This takes the runtime of our workflows from 30 seconds to a couple of minutes, but eventually we all end up becoming data engineers, because the most challenging part of the problem is getting theright context into the prompts.

Infra Shift1:12

Evan Boyle1:12

And that means that we might have to crawl a user's inbox, ingest code from GitHub, or many other artifacts that require lots and lots of LLM processing. But our assumptions around infra have changed. In web 2.0, you would build a simple web service where you'd make an API request, maybe talk to a database to fetch some data, and return all that back in a few tens of milliseconds.

In AI applications, our p1 is a couple of seconds at best, and that's only if you're using a fast model or if you hit a prompt cache. In the previous era of infrastructure, if you had a request that took a couple of seconds, your on-call was getting paged.

And so the infrastructure that was designed for the last 10 years of the web is not really designed for the applications that we're building today. LLM applications are really built on shoddy foundations. It's really hard to build reliable apps today.

Outages2:11

Evan Boyle2:11

And if you're like us and you run a tight ship, you might have a Slack channel that looks like this, where you subscribe to issues and outages from your dependencies. But luckily, this one only lasts an hour. By 10:00 PM, it's resolved.

But up at 1:20 AM, we're back at it, and 4:00 AM, it's still going on. But surely ChatGPT and OpenAI have better availability,right? Well, I wouldn't really trust this 99.9% uptime number. And no, it's not. Lots of yellow and red in this graph.

But maybe we could have failed over to Gemini during this time period. Nope, we have an outage during the exact same time period. And even if you don't hit an outage, you still have rate limits to contend with.

A lot of these traffic patterns are going to be extremely bursty as you batch process documents from a user or you onboard new customers, and not everybody has tier 5 rate limits that require spending thousands of dollars just to get to that point that you can start experimenting with high levels of traffic.

Scaling Prototypes3:14

Evan Boyle3:14

So we start off nice and happy with our prototype. Maybe we built something on top of the Next.js chatbot template. That's easy,right? But as our workflows start running for minutes and hours, us full-stack AI engineers accidentally become data engineers.

And so how do people solve this today? This used to be something that was rather niche: long-running workflows, data engineering. So there is an existing set of tools. People build these Rube Goldberg machines on top of queues like SQS.

Existing Tools3:30

Evan Boyle3:44

They might use batch processing, data engineering tools like Airflow, or durable execution engines like Temporal. But me personally, I'm a TypeScript developer, I'm a full-stack engineer, and frankly, I don't want to use anything that was designed by a Java engineer.

No offense. I'd much rather use serverless. What about existing serverless providers? They aren't really well-suited for these kinds of long-running workflows. Most of them time out after 5 minutes, and some of them even limit outgoing HTTP requests. And for all of them, they don't really have native streaming support.

Serverless Limits3:59

Evan Boyle4:18

Streaming is something that you have to bolt on at the application layer, and not something that's a native part of the infrastructure that you're building on top of. Something that's really important when you're building an application that might run for multiple minutes.

Users might refresh the page, so you want resumability. And so let's look at some of these common product experiences. We're going to look at both onboarding, where we might ingest a bunch of data from the user with an LLM upfront, and then also a product experience where we're going to run an agent that's going to take multiple minutes, and we have to keep the user engaged during that time period.

Product Experiences4:32

Evan Boyle4:53

So during this onboarding experience, the user puts in their URL,right? And we use a single LLM call to grab some information from that web page and then detect all the pages that we're going to scrape,right? And now we've kicked off that scraping job in the background, and it's going to take multiple minutes.

And we're going to be making hundreds of LLM calls to extract content from those web pages and enrich them. And we want the user to be able to start using the productright away. So this ingestion can take a varying amount of time, but we want users to use the app immediately.

If we wait 10 minutes, that means we're going to have increased falloff in the funnel, so we have to run this in the background,right? And we want to show users the status of this ingestion as they're using the product.

We want them to know, "Hey, as time goes on, we're going to enrich more data, and your experience is going to get better." Next, this is an example of building a content generation app,right? We're going to write a blog post about building high-performance web apps with Vercel and Next.js.

And this agent, we tell the user up front, "Sit back and relax. This is going to take a couple of minutes." And on theright, we're showing them all of the different steps,right? We're running research, we're writing an outline, and we're writing each section step by step.

Since this takes multiple minutes, it's really important that if the user leaves the page or navigates away, that they don't lose this context,right?

And so that workflow that we built when working on a previous product took 3 to 4 minutes. And we really felt a lot of friction experimenting with longer workflows. Like, we were deterred from making our workflows longer than 5-plus minutes because that meant that we would have to make deep infra changes due to limitations from our serverless provider.

Eventually, we did rip it out, and it was a bunch of work, but it took us much longer than we should have to run those experiments because of the amount of work that was required to migrate off of our easy-to-use serverless offering.

Also, we need to stream both the final content as well as the intermediate status. And if the user refreshes the page and comes back, we want them to see that same thing, just like you get with deep research,right?

And if there's an intermediate error, users are going to be way more frustrated if it takes them 5 minutes to get back to that same point, versus if it's just a simple web page that you have to refresh or a form that you have to resubmit.

GenSX Library7:18

Evan Boyle7:18

So we built a lot to make this easy in our core product when we were working on agentic workflows, and we ended up turning a lot of this into an open-source library. So we built a simple component model that's infrastructure-aware,right?

The framework itself is very aware of the infrastructure it's running on, and the infrastructure is aware of the framework. And that's so that we can provide things like resumable streams for intermediate status and final output. And we call this a bit of an anti-framework.

It's unopinionated and focused on building blocks. It takes inspiration from React's component model and applies it to the backend, because we know that abstraction is bad when building agents. You don't want to abstract. You want to share. You want to compose.

You want to reuse code. And so we have components that are reusable, item-potent, independently testable steps, and then workflows that are collections of components that run together. So this is a simple component that uses a wrapped version of the OpenAI SDK.

It's wrapped so that we can get a bunch of other tooling for retries and tracing and things like that, but it's the same exact OpenAI surface area that you would expect. We give you full access to the model, so it's just a prompt, a little bit of context that's ingested, and it returns a response.

So a simple function that takes in some prompts and returns some output, and it can be independently run or tested. We can also combine it together into what we call a workflow. This workflow fetches the front page of Hacker News, analyzes those posts, generates reports, writes a tweet, and then edits the report.

And with this, every single step, we're going to get a retry boundary, an error boundary off each component, and we're going to get traces, both at the top level of the workflow, but also all of the components that run within it.

Each workflow can be turned into a set of REST APIs automatically by the framework that support synchronous invocation as well as asynchronous invocation and the relevant API so that we can retrieve the intermediate stream and the final output stream if needed.

When we run this workflow, we see that we get a trace. This trace shows us all of the nested components that run inside the workflow, including all the tokens, all the details on the OpenAI call, user messages, system messages, so it makes it super easy to debug.

And we have built-in retries. Every component has a fluent API hung off of it that allows you to configure a component with things like retries and a cache. So if I have one component that's particularly problematic, I can add an exponential retry policy and configure the number of retries that run.

And so this all gets deployed to a serverless platform that we built that's tailor-made for long-running workflows and building agentic UIs for processes that run in the background. So we have an API layer and a compute layer that are completely separate.

Platform Design10:02

Evan Boyle10:18

And this is really important for a lot of reasons. The API layer invokes the compute layer and passes it in a Redis stream ID. That's the last time that the API layer is going to have to talk to the compute layer.

The rest of it is going to happen via communication with this Redis stream. Status is going to come from the Redis stream. The output is going to come from the Redis stream. And as the sandbox program executes, it's going to emit heartbeats so that the background processes within the system can monitor and make sure that a workflow runs to completion and doesn't die or doesn't crash.

And if it does, we can automatically restart it or notify the user.

So key architectural points of this is this separation between the API and the compute layer. It allows us to scale things independently, scale the API layer independent of the compute layer. It also allows us to plug that compute layer.

So we can provide a compute layer by default on top of ECS, but we can allow users to bring their own compute layer as well, since it's completely stateless and just talks to the API layer in the Redis streams to store output.

All of that API goes to the Redis stream, both for sync and async workflows, which means that we get resumability,right? The API layer only reads from the Redis stream, not the compute layer directly. So that means that we can build UIs that allow users to refresh the page, navigate away, transparently handle errors, and they still get the full history of status messages and all of the output, something that you wouldn't get from a typical serverless-like infra platform.

Like we said, key point here is being able to refresh the page, resume directly from the Redis stream, and get all of your intermediate status messages. None of the work is lost if the user navigates away or if the web browser terminates the connection to the API server.

Lessons12:07

Evan Boyle12:07

So things and lessons to consider when you're building your own infrastructure for agentic workflows. Always start simple. You're not going to write a workflow that runs for an hour on day one, so don't build for it. But do plan for a future that's long-running.

In my opinion, this is where agents are going, and I think that we can see this with all of the recent coding agents that have come around, experiences like deep research. I think the future is giving your agent instructions and letting it go off and do work for you and communicate with you when you need it.

And to make that happen, think about keeping your compute and API plane separate and lean on Redis streams for resumability. Make it easy for users to navigate away from the page, not lose progress, and handle errors transparently. All this is also to say, you got to take care when deploying.

If you're going to let your workflows run for 60 minutes, you have to be very, very careful about how you drain workers and how you do kind of a blue-green deployment pattern. And overall, the devil is really in the details.

Easy to get started, but very hard to get thisright.

Closing13:11

Evan Boyle13:11

Now, it's really, really fun to build all of this infrastructure yourself. But if you don't want to build it yourself, I'd encourage you to check out GenSX on GitHub, where we've implemented a lot of this for you. Again, my name's Evan.

Thanks for having me at this talk, and happy building.