- GigaElixir Gazette
- Posts
- đź§ Stop Maintaining State, Rebuild It
đź§ Stop Maintaining State, Rebuild It
GenServer message chains got out of hand until event sourcing clicked—here's the pattern
Welcome to GigaElixir Gazette, your 5-minute digest of Elixir ecosystem news that actually matters đź‘‹.
. WEEKLY PICKS .
🚀 Elixir v1.19 Ships 4x Faster Compilation and Enhanced Type Checking: José Valim's latest release delivers module type inference that catches bugs without manual annotations, up to 4x faster builds in large codebases through lazy module loading, and parallel dependency compilation. Type system now infers integer() -> boolean() even without guards, catches protocol implementation errors at compile time, and type-checks anonymous functions automatically. The MIX_OS_DEPS_COMPILE_PARTITION_COUNT variable lets you compile multiple dependencies simultaneously—users report 4x speedups on CI.
📝 Developer Explains Phoenix LiveView Choice Over Rails, Laravel, and Next.js: Solo developer building Hyperzoned.com needed speed—both application performance and development velocity. Rails Hotwire looked fast for MVPs but required extra setup for background jobs and real-time updates. Laravel Livewire simplified frontend but still felt like maintaining two stacks. Next.js meant JavaScript on the backend. Phoenix LiveView delivered WebSocket-based two-way communication, Oban background jobs out of the box, and fault tolerance that auto-restarts failures without breaking the app.
đź”§ Phoenix Pulse VSCode Extension Launches for LiveView Development: New beta extension streamlines Phoenix and HEEx template editing with LiveView-specific tooling. Created initially for personal workflow, now published for community feedback. Early stage but includes multiple features targeting Phoenix developers who want smoother editing experience in VSCode. Author seeks bug reports and feature suggestions from the community.
💻 Livebook Remote Execution Lets You Test Phoenix Code Without Opening Editor: Tutorial shows using Erlang distribution to connect Livebook to running Phoenix apps with iex --name [email protected] --cookie secret -S mix phx.server. Write modules in Livebook, execute them in your app's context, validate logic with quick tests. Author reports writing complete LiveViews and complex components in Livebook before porting to application codebase—enables rapid prototyping without pulling hair over setup.
🤖 AI Agent Workflow Platform Built on Elixir's GenServers: Developer exploring AI agents after 20+ years with BEAM (ejabberd integration at Sega circa 2001) settled on Elixir for reliability after Python and Node.js experiments. Agents manipulating text broke state constantly. Solution: MVC-like "Lenses" pattern where agents manipulate structured data (DOM trees, not HTML strings) and GenServers manage state with supervision. Semantic routing nodes let agents make workflow decisions. Currently seeking feedback on approach before public release.

Your GenServer Message Chains Got Out of Hand Because You're Maintaining State Instead of Rebuilding It
Every now and then you hit a concept that makes you go "huh..." and realize you've been fighting the wrong problem. Mine was storing LLM message chains in GenServer state—seemed obvious at first, then became a maintenance nightmare when implementing anything beyond basic chat.
The instinct: keep the chain of messages in GenServer state, persist as role/content pairs, update as conversation progresses. Works fine until you need compaction, dynamic context control, tool call result management, multi-agent coordination, or complex document handling. Each requirement meant more state synchronization, more message passing, more GenServers communicating over PubSub channels trying to stay consistent.
One project had observer AI systems monitoring conversations and providing live feedback. The Elixir-influenced instinct led to supervision trees with multiple GenServers per therapy session—SolutionFocusedObserver, CognitiveBehavioralObserver, CommunicationPatternObserver, all communicating over shared PubSub. Things got out of hand quickly. Some agents needed message subsets. Some had time-keeping mechanisms others didn't need. Altering the message chain meant coordinating across multiple processes maintaining slightly different views of the same conversation.
The breakthrough came from seeing Ash framework's reference implementation reload the chain from database and rebuild it at every user message. Not groundbreaking on its face, but it clicked: stop thinking about message chains as mutable state to maintain. Think of them as projections you rebuild from richer interaction history—event sourcing for LLM conversations.
Instead of storing [%{role: "user", content: "analyze contracts"}, %{role: "assistant", content: "I'll help..."}], store typed interactions with metadata: user messages, file uploads with processing status, assistant responses, compaction events. Rebuild chains dynamically by loading interactions, starting from last completed compaction, transforming files to metadata or full content as needed, and formatting as messages. The database becomes source of truth. No syncing between memory and persistence.
This simple shift—from managing mutable state to rebuilding projections—makes previously complex features trivial. Compaction? Just another interaction type that future rebuilds use as starting point. Multiple agents? Each builds their own view from same interaction history. Document management? Store metadata as interactions, fetch content on demand. Branching conversations? Filter interactions differently. Audit trails? You already have complete history. The pattern works regardless of stack—Ash, Ecto, or different languages entirely.
Remember, for managing conversation state:
Store interactions, not messages – Rich typed events with metadata enable flexible projections instead of fixed message chains
Rebuild on every request – Database as source of truth eliminates synchronization complexity across processes
Let projections diverge – Multiple agents build custom views from same history without coordination overhead
Compaction becomes metadata – Mark compaction events in history; rebuilds start from there automatically
. TIRED OF DEVOPS HEADACHES? .
Deploy your next Elixir app hassle-free with Gigalixir and focus more on coding, less on ops.
We're specifically designed to support all the features that make Elixir special, so you can keep building amazing things without becoming a DevOps expert.
See you next week,
Michael
P.S. Forward this to a friend who loves Elixir as much as you do đź’ś