event sourcing · ruby on rails

Event-sourcing building blocks for Rails applications.

Funes is an event sourcing meta-framework for Rails, providing deep conceptual compression through an interpretations DSL that keeps you writing business logic instead of plumbing. Shaped by the "one person framework" philosophy, it invites progressive adoption.

Three new concepts. One concise mental model.

These three concepts are the conceptual compression of an event-sourced system, a synthesis of its mechanics and operation. Built on top of Rails components, they live well with the Rails way of doing things, which is why anyone fluent in Rails picks them up quickly.

01. Event

An immutable registry of a fact. Validated on the way in, every event composes the permanent history, the raw material from which your application's state is derived.

Read more

02. Stream

The write interface for one entity, and the way to aggregate related events in the event log. Appends are validated, concurrent writes are managed, and a new stream is born the first time you write to it. No provisioning, no setup.

Read more

03. Projection

Turns the immutable log into live state your app can use. Virtual for in-memory validation, persisted for fast reads. Funes handles replay, ordering, and concurrency for you.

Read more

Together, the three concepts give you perspective on the events accumulating in your log. And the interpretations inside each projection let you pilot a time machine: rewind to see how state actually was, or play forward to see how it could be if the domain unfolds the way you modeled it. That's the mental model: a record of facts, any of many possible interpretations, and time as a dial you can spin in either direction, with the resulting state either virtual in memory or persisted for fast reads.

That dial has two hands, because every event carries two clocks: one for the business reality (when something occurred), another for the system's awareness of it (when the event was recorded). Keeping both is what makes the past auditable and correctable without erasing it: a retroactive event appends a new fact to the history, dated in the past but recorded now, so both readings stay on the record along with the moment the correction landed. The bi-temporal event streams recipe covers the pattern in detail.

Frequently asked questions

Will it stay fast as the event log grows?

Yes — measurements consistently show that event-stream operations stay sub-linear as the log grows, which is an important property for medium- and long-sized streams. Treat any published figure as directional rather than definitive (workloads vary, hardware matters), but the overall trend stays the same. Latest measurements and methodology live in the performance measurements discussions.

That said, streams cannot be undefined in size. Model the system so that every stream has a sensible, bounded lifetime — a stream per order, per account period, per session — rather than a single ever-growing stream that accumulates forever. Good stream boundaries are part of the design, not an afterthought.

Is Funes responsible for infrastructure compliance?

No. Funes is an application-layer framework: it bridges Rails and event sourcing, and nothing below that. Everything at the infrastructure layer (encryption, SOC 2 controls, access governance) stays the responsibility of the developer or operator. The event log lives in your database, in your environment, configured to whatever your organization requires.

One friendly request, though: please don't persist PII inside an event. Events are immutable by design — once written, they stay written — so any personal data you drop into a payload is effectively there forever. Keep PII in mutable side tables you can redact or rotate, and reference it from events by stable identifiers.

Why not use one of the existing event-sourcing options on the market?

Fair question — there are excellent tools out there, and we have a lot of respect for them. Funes isn't trying to out-feature any of them. The bet is the opposite one: most existing options reach for broader concepts (CQRS, sagas, process managers, full DDD tactical patterns, dedicated event stores, message buses) that are useful in their own right but sit above and around event sourcing rather than inside it.

Funes deliberately compresses the surface area down to three primitives — events, streams, projections — wrapped in a small, precise DSL. The goal is to remove complexity rather than add more of it: keep the core idea sharp, keep the noise out, and let teams pick up event sourcing without first adopting a wider architectural vocabulary. If you already love the bigger toolkits, they remain great choices; Funes is for teams who want the essence of event sourcing inside a familiar Rails app.

Can I adopt Funes without rewriting my app?

No. Funes is designed for progressive adoption — it's a "good neighbor" that coexists with your existing ActiveRecord models and standard controllers. You can use it for a single mission-critical feature while keeping the rest of your app in plain old Rails. Nothing forces an event-source-everything commitment across the codebase.

Why "meta-framework" and not a Rails engine?

Technically, Funes is a Rails engine: it ships as a gem and mounts into your application like any other. The "meta-framework" label isn't about packaging, it's about vocabulary. A typical engine extends an application with features that fit cleanly into the lingo developers already share. Funes goes a step further: it introduces a small set of new concepts (events, streams, projections, interpretations) that aren't part of everyday Rails vocabulary. That extra vocabulary built on Rails, rather than just inside it, is what makes "meta-framework" a better fit than "engine."

How does Funes fit in an AI-coding era?

AI is far better at gluing well-defined building blocks together than at deriving an entire architecture from first principles. As the cost of writing code falls, the leverage shifts to whoever ships clean, composable primitives that an assistant (or an engineer) can stitch into a system without re-inventing the fundamentals every time. Funes is shaped for that posture: three concepts, a focused DSL, and a clear contract for events, streams, and projections. Mitchell Hashimoto calls this dynamic the building-block economy, and a well-defined event-sourcing framework is precisely the kind of block it rewards.

Who makes Funes?

Funes is architected and maintained by Vinícius Almeida, drawing on his experience building financial systems and complex auditable service operations. It's developed in the open at github.com/funes-org under the MIT license.

What's behind the name Funes?

Named after Funes the Memorious — the Borges short story about a young man who, after a fall from a horse, becomes incapable of forgetting. Every detail of every moment lodges in his mind in perfect resolution. The framework borrows that conceit: in some systems, the past matters as much as the present, and remembering everything is the point.