Let me tell you about one of the most audacious engineering decisions I’ve seen this year.
A team looked at the problem of running Redis alongside their application runtime and thought: “You know what would be simpler than spinning up a container? Rewriting the entire thing from scratch in Rust.”
25,000 lines of Rust. To avoid a docker-compose up.
I need a moment.
If your solution to “managing one more container” is “maintaining a 25,000-line reimplementation of a constantly evolving database,” you haven’t eliminated complexity. You’ve just moved it somewhere harder to see.
The team at Encore.dev published a blog post titled “We put a Redis server inside our runtime,” and to their credit, it’s a genuinely fascinating piece of engineering. They ported Redis to Rust, embedded it directly into their Go runtime, and eliminated the need for developers to configure and manage a separate Redis instance during local development.
The pitch is seductive. No more “another container to run and manage.” No networking overhead. No configuration drift between local and production. Just import and go.
But here’s where my spider sense started tingling.
Redis isn’t a static target. It’s a living, breathing project with releases, bug fixes, performance improvements, and new features landing constantly. The Encore team now has to chase byte-for-byte parity with upstream Redis — forever. Every new Redis release isn’t just an upgrade opportunity; it’s a maintenance obligation. A 25,000-line debt instrument with a compounding interest rate.
When you embed a dependency, you don’t just adopt its functionality. You adopt its entire future. Every bug, every security patch, every breaking change becomes your problem — and yours alone.
The Hacker News commenters saw right through it. The top comment cuts to the bone: “I’d really like to understand why they didn’t just also have a small container for this running. The only reasoning given in the article is ‘another container to run and manage,’ which Docker Compose, TestContainers, etc. will make trivial.”
That’s the thing. The problem they’re solving — “another container to manage” — was already solved. Docker Compose exists. TestContainers exists. Kubernetes sidecars exist. The developer experience of running Redis locally has been effectively trivial for years. You write six lines of YAML and move on with your life.
Instead, this team chose to write 25,000 lines of Rust.
Now, let me be fair for a moment. There’s a legitimate thread here about the desire for embedded, library-style dependencies versus external services. When Cloudflare was unhappy with Nginx, they built Pingora in Rust. When Discord outgrew ScyllaDB’s behavior, they built their own storage layer. There’s a tradition in engineering of “if the tool doesn’t fit, build one that does.”
But there’s a critical difference. Cloudflare and Discord built new tools to solve new problems at unprecedented scale. Encore rebuilt an existing tool to solve a problem that Docker Compose already handles.
There’s a fine line between engineering ambition and engineering hubris. That line is usually drawn by the question: “Did we actually need to build this, or did we just want to?”
The deeper issue here isn’t about Redis or Rust or containers. It’s about a pattern I see repeatedly in software engineering: the tendency to absorb external complexity into internal codebases because internal complexity feels more controllable. It doesn’t. It just feels that way until three years from now, when the upstream Redis team ships a critical security patch and your Rust port is six versions behind.
Every build-vs-buy decision is really a question about where you want to spend your attention. You can spend it configuring and maintaining an external dependency — which is boring, predictable, and well-understood. Or you can spend it reimplementing that dependency — which is exciting, unpredictable, and a bottomless pit.
The most expensive code in your codebase is the code you wrote to avoid using someone else’s code.
I don’t doubt that the Encore team is talented. Porting Redis to Rust in 25,000 lines is genuinely impressive engineering. But impressive engineering in service of the wrong problem is just expensive showmanship.
If you’re a software architect or engineer reading this, here’s the real lesson: every time you’re tempted to absorb an external dependency into your own codebase, ask yourself one question. “Am I solving a real problem, or am I solving a problem that’s already been solved because I’d rather build than configure?”
Your future self — the one maintaining that code at 2 AM — will thank you for the honesty.
FAQ
Q: Why not just use Docker Compose like everyone else?
A: Exactly. Docker Compose, TestContainers, and similar tools have made running Redis alongside your app trivial for years. The article's justification — 'another container to manage' — describes a problem that was already solved.
Q: What's the real long-term cost of embedding Redis like this?
A: You're now responsible for chasing byte-for-byte parity with upstream Redis forever. Every security patch, bug fix, and feature release upstream becomes a maintenance obligation downstream. It's a 25,000-line debt instrument with compounding interest.
Q: Isn't this just like Cloudflare rewriting Nginx in Rust?
A: No. Cloudflare built Pingora to solve a new problem at unprecedented scale. Encore rebuilt an existing tool to solve a problem Docker Compose already handles. Ambition in service of the wrong problem isn't innovation — it's expensive showmanship.