#8
AI Agents

When OpenAI Needed an Agent Orchestrator, They Reached for Elixir

OpenAI published Symphony — a multi-agent coding orchestrator — as 96% Elixir. The README offers no justification. In 2026, that silence says something.

When OpenAI published Symphony in late February, the headline was the product: an agentic framework that watches a Linear issue tracker, spawns a Codex AI instance per ticket in an isolated workspace, monitors CI feedback, and delivers pull requests. Autonomous software development, productized.

The more interesting detail is what the 14,000-star repository is actually built in. Pull it up. The language breakdown: Elixir, 96.4%. 616,000 bytes of it.

This is worth sitting with. OpenAI — whose primary engineering stack is Python, whose public tooling ships in Python first, whose client libraries assume Python — built the reference implementation of their multi-agent coding orchestrator in Elixir. Specifically: Phoenix 1.8, Phoenix LiveView 1.1, Bandit as the HTTP server, Req for HTTP client work, Ecto for schema validation. They compiled it as an escript binary. They knew the ecosystem well enough to pick Req over the alternatives, to use Bandit — the modern Plug-compatible HTTP server that’s now Phoenix’s default — rather than something bespoke. The README doesn’t include a section called “Why Elixir.” There’s no justification. The code is just Elixir.

Symphony’s architecture is defined in a SPEC.md that describes seven components: Workflow Loader, Config Layer, Issue Tracker Client, Orchestrator, Workspace Manager, Agent Runner, and Status Surface. The Orchestrator is the core. It owns all system state in memory, creates per-issue isolated workspaces to prevent agents from interfering with each other, and monitors issue state so agents halt when a ticket closes or goes duplicate. No persistent database. State lives in BEAM processes. An optional observability dashboard — the --port flag — brings up a Phoenix LiveView view of all running agent sessions in real time. This is not an incidental architectural choice. It’s the whole point.

Here’s the thing about orchestrating AI coding agents: the technical problem is exactly the kind of problem OTP was built for. Each agent is a long-running, stateful process. Agents can fail, and the system should notice and recover. Multiple agents run concurrently, and their state must be isolated — a bug in one workspace should not bleed into another. The work is heterogeneous: some agents are waiting on CI, some are actively writing code, some have stalled on ambiguous specs. Supervision trees, process isolation, in-memory state owned by processes that die and restart cleanly — this maps directly. The BEAM’s model isn’t just an interesting choice for this problem. It’s close to the obvious one. What’s new in 2026 is that someone at a frontier AI lab reasoned through that mapping and reached the same conclusion.

In 2022, an Elixir choice at a company like OpenAI would have required a manifesto. A blog post, at minimum. “We picked Elixir because of the BEAM’s process model and fault tolerance. Here’s what that means.” In 2026, the code is self-explanatory enough that it doesn’t. The absence of justification is the justification.

There’s an honest caveat worth making. Symphony is labeled experimental — “prototype software intended for evaluation only,” in the README’s words. OpenAI’s production stack for agent workloads almost certainly lives in Python. This is a reference implementation, not a disclosure about how OpenAI runs its internal engineering. It’s meant to be a starting point that adopters harden for their own use. But starting points reveal what you reach for when you’re thinking, not performing. And what someone at OpenAI reached for, when building a system that manages many concurrent long-running AI processes, was Phoenix, OTP, and a supervision tree.

The question Symphony opens is worth watching: as AI coding agents become a standard part of software delivery — tools that run perpetually, manage their own state, spin up and down in response to ticket activity — what language properties actually matter? Raw throughput doesn’t. Low latency per request doesn’t. Concurrency model, fault tolerance, process isolation, observability at the process boundary: those do. The BEAM has had clear answers to all of those questions for thirty years. Symphony is evidence that those answers are now visible enough that someone reaching for a new problem sees Elixir first.

The repository is at github.com/openai/symphony. If you want to see what an idiomatic Phoenix 1.8 application looks like at the component boundary — how Orchestrators and Workspace Managers compose, how LiveView gets wired into a non-web-first application — it’s a useful read. Independent of who wrote it or why.