Madeleine is a Ruby implementation of transparent persistence of business objects, using command logging and complete system snapshots.


require 'madeleine'

# Create an application as a prevalent system

madeleine ="my_example_storage") {
  # Creating the initial empty system. This is how the application
  # is bootstrapped on each startup (until the first snapshot is taken).
  # All the persistent data needs to be reachable from this object.
  # For this example, the application's whole dataset is a hash
  # with a counter:
  {:counter => 0}

# To operate on the system, we need commands. For this example,
# we can do additions to our counter:
class AdditionCommand
  def initialize(number)
    @number = number

  def execute(system)
    # This is the only place from where we're allowed to modify
    # the system.
    system[:counter] += @number

# Do modifications of the system by sending commands through
# the Madeleine instance:

command =

# The commands are written to the command log before executed.
# The next time the application starts, all the commands in the
# log are re-applied to the system, returning it to the state it
# had when it was shut down.

# To avoid long start-up times when the command log gets large,
# you can do occasional snapshots of the entire system. You must
# also do a snapshot before deploying any changes in your application
# logic.


A Madeleine instance can be create with an execution context, that will

be passed to all commands as a second argument. This is useful for passing

in things that are neither persistent nor global, e.g. the current Rack application.

madeleine ="my_example_storage", execution_context: rack_app) { }

class WebRelatedCommand def execute(system, context) # The context will now be the Rack application ... end end


  • Ruby 1.8.7 or later




BSD (see the file COPYING)


Anders Kindberg (Bengtsson) - Prevalence core impl.

Madeleine's design is based on Prevayler, the original Java prevalence layer.

With the help of patches, testing and feedback from:

Steve Conover, David Heinemeier Hansson, Johan Lind, Håkan Råberg, IIMA Susumu, Stephen Sykes, Martin Tampe and Jon Tirsén

Thanks to Klaus Wuestefeld and the Prevayler developers for the model of this software; to Minero Aoki for the installer; to Matz and the core developers for the Ruby language!