The agentic AI industry is building on a foundation of sand. We’re chasing features with frameworks that have grown to 400,000 lines of code, but our production deployments are slow, fragile, and impossible to scale. The excitement of the demo has given way to the reality of deployment, and it’s not working.
Developers face an impossible choice. Use a batteries-included Python framework and fight with dependency hell and the Global Interpreter Lock. Or use a TypeScript equivalent and get lost in a jungle of async/await and callback chains. The stark reality? What works for a weekend prototype collapses under the strain of real-world concurrency, long-running tasks, and the simple need to cancel a job that’s gone off the rails.
But what if the problem isn’t our agent’s logic, but something more fundamental? What if the very frameworks we use to build them are the source of their failure?
My 166MB Wake-Up Call
I learned this lesson the hard way. A client project required a multi-agent system to process real-time data streams. Using a popular Python framework seemed magical—until we tried to deploy it. The pip install process pulled in hundreds of megabytes of dependencies. Our ‘simple’ agent now lived in a 1.2GB Docker image with a cold start time measured in minutes, not milliseconds.
That was just the beginning. The system needed to handle hundreds of concurrent users, but Python’s Global Interpreter Lock (GIL) meant our 16-core server could only ever use one core for our code. Throughput hit a wall. Worse, when a user cancelled a long-running job, the agent often kept running in the background, burning through expensive API calls because cancellation in a complex async environment was a ‘best-effort’ affair.
We were spending all our time fighting the framework, not building the product. This experience revealed a deeper truth: the problem wasn’t just our architecture; it was the tools themselves.
The ‘Framework Trap’
The real issue is that our current agent frameworks were built for rapid prototyping, not production workloads. This is a critical design mismatch. A data scientist can tolerate a massive environment to run a Jupyter notebook. A production system running thousands of concurrent agents cannot. An AI researcher can manually kill a runaway process. An automated system needs deterministic, guaranteed cancellation to prevent catastrophic bills.
This is the Framework Trap: we adopt tools that accelerate initial development, only to find they have built-in ceilings that make production scale, performance, and reliability nearly impossible. They trade foundational soundness for a long list of high-level features, trapping us in an ecosystem that wasn’t designed for the job.
Even state-of-the-art systems built with LangChain or LlamaIndex suffer from this. While their integrations are vast, the moment you need high concurrency or reliable cancellation, you hit the fundamental limits of Python or Node.js. This trap is the direct cause of fragile deployments, performance bottlenecks, and systems that are impossible to maintain.
The Real Scale of the Problem: Production Statistics
This isn’t theoretical. Here are the documented, measurable impacts from production systems:
- Python’s GIL Bottleneck: Benchmarks show Python 3.12 with GIL takes 8.5 seconds for multi-threaded tasks that complete in 1.75 seconds without GIL—a 4.8x performance penalty. On 8-core machines, Python agents effectively use only one core, wasting 87.5% of available compute.
- JavaScript Memory Leaks: Node.js v18.16.0 had a critical memory leak when using AbortController with fetch()—affecting thousands of production systems. Apollo Client promises hung indefinitely when cancelled, leaving API calls running and accumulating costs.
- LangChain’s Deployment Crisis: Real measurements show 6-8 second cold starts on AWS Lambda with basic LangChain imports. Teams are forced to use 10GB container deployments for what should be 250MB functions. The framework alone is responsible for 90% of cold start delays.
- Supply Chain Chaos: The urllib3 2.0 release (April 2023) broke production Python environments worldwide. The colors.js sabotage affected 3.3+ billion downloads. As of 2024, 13% of developers still download vulnerable Log4j versions through transitive dependencies.
In every case, the pattern is identical: the framework, chosen to make things easier, became the single greatest source of failure.
From Frameworks to Primitives
For years, we’ve focused on ‘framework engineering’—adding more abstractions, integrations, and wrappers. But this misses the point. You can have a perfect abstraction for a tool, but if the underlying language can’t run more than one agent at a time efficiently, your system will never scale.
The real solution lies in building on first-class primitives.
As Hatchet’s post ‘Why Go is a good fit for agents’ articulated, the core challenges of agentic systems are concurrency, communication, and cancellation. The goal isn’t just to abstract these problems, but to use a language where they are solved primitives. Go isn’t just another language choice; its core features are the exact solution to the Framework Trap.
Zig presents an intriguing alternative with its upcoming ‘colorless functions’—a new async/sync unification that could simplify concurrency even beyond Go’s goroutines. But Zig’s async story is still being written. For production systems that need to ship today, Go’s proven primitives and mature tooling remain the practical choice.
Where Agent Systems Break: Common Failure Patterns
These production failures aren’t edge cases; they are born from the fundamental limitations of the ecosystems we’ve chosen.
- Single-Thread Bottlenecks: Python’s Global Interpreter Lock (GIL) prevents true parallelism for CPU-bound tasks. JavaScript/TypeScript faces the same limitation with its single-threaded event loop—both languages force your multi-agent system to run on one core, regardless of hardware.
- Ineffective Cancellation:
asyncio.Task.cancel()in Python or aborting Promises in JavaScript don’t offer strong guarantees, especially across I/O. This leads to runaway processes and wasted money. - Async Complexity: JavaScript’s callback hell meets Python’s asyncio soup—both create complex, non-linear control flows that become nearly impossible to reason about, debug, or maintain.
- Dependency Bloat: JavaScript’s node_modules routinely exceeds 1GB for simple apps (13,506 dependencies for Create-React-App). Python fares better but still suffers—TensorFlow containers reach 7.2GB. Both create massive attack surfaces with regular supply chain compromises.
- Deployment Fragility: Relying on complex virtual environments and package managers like
pipornpm, which create a ‘works on my machine’ nightmare in production.
Enter Flow (flw): Agentic Primitives in Go
Flow (flw) solves the Framework Trap by giving you the one thing you need: a solid foundation built on production-grade primitives.
For startups and enterprises, it means building systems that are scalable, reliable, and maintainable from day one. For developers, it means escaping dependency hell and writing clean, concurrent code that just works.
Flow is not another framework. It is a radically minimal, zero-dependency library that provides the essential graph structure for agentic workflows, built directly on Go’s strengths.
This simple, composable structure gives you the power to build complex agents without the weight of a thousand abstractions.
Key Features That Matter
- Massive Concurrency via Goroutines: Spawn thousands of agents with a tiny 2KB memory footprint each. Your 16-core server can now actually use all 16 cores—unlike Python’s GIL or JavaScript’s single thread.
- Deterministic Cancellation via Context: Use Go’s standard
context.Contextto reliably terminate entire trees of work, from the top-level agent down to the deepest HTTP request. No more runaway API calls burning through your budget. - Zero-Dependency Core: Flow itself has no external dependencies. No 1GB node_modules folders, no 7GB TensorFlow containers. The supply chain attack surface is minimized—third-party integrations like LLM calls are made via API endpoints, not SDKs, eliminating the weekly npm/PyPI compromises.
- Single-Binary Deployment: Compile your entire agent system—runtime and all—into a single executable file. Deploy a 10MB binary instead of a 1.2GB Docker image. Copy it to a server and run it. The age of
requirements.txtandpackage.jsonis over.
The Broader Implications: Building a Production-Grounded Future
Flow represents a fundamental shift. By escaping the Framework Trap, we can move from building brittle prototypes to engineering robust, scalable systems.
- The GIL Concurrency Disaster would have been avoided. Instead of being stuck on one core, a Go-based system would have scaled effortlessly across all 8, handling 8x the load.
- The Runaway Agent Incident would have been prevented. Instead of a ‘best-effort’ cancel, a
context.CancelFunccall would have sent a guaranteed stop signal down through every goroutine, terminating the LLM call instantly.
Important clarification: Flow is not LangChain in Go. It doesn’t have thousands of integrations out-of-the-box. It is specifically designed to solve the foundational crisis—the problems of concurrency, cancellation, deployment, and performance that plague existing frameworks. It is a minimalist core for those who need to build systems that last.
Future extensibility: Flow will support adding functionality through a bundler approach or simple imports—maintaining the zero-dependency core while allowing developers to compose only the capabilities they need. Think of it like Datastar’s plugin system: you’ll be able to create custom bundles including only required components, avoiding the bloat that plagues current frameworks while preserving Flow’s production-grade foundation.
A Sustainable Path for AI Development
As agents become more critical parts of our infrastructure, the cracks in our current foundations will become chasms. The choice is not between Python’s ecosystem and Go’s performance. It’s between building on fragile abstractions and building on solid primitives.
The future of production AI doesn’t have to be complex, slow, or unreliable. With the right foundation, we can build a sustainable, scalable, and powerful ecosystem. The age of the Framework Trap must end.
Flow is open source and the initial implementation is in progress: github.com/slavakurilyak/flw
‘Do not communicate by sharing memory; instead, share memory by communicating.’ - The Go Proverb that changed everything
Follow the project: github.com/slavakurilyak/flw
Built by @slavakurilyak • Inspired by PocketFlow and Hatchet