Skip to content

Message replays

Fluxzero allows you to replay past messages by tracking from an earlier index in the message log. This is useful for:

  • Rebuilding projections or read models
  • Repairing missed or failed messages
  • Retrospectively introducing new functionality

Since message logs — including commands, events, errors, etc. — are durably stored (with events retained indefinitely by default), replays are usually available.

The most common way to initiate a replay is to define a new consumer using the @Consumer annotation with a minIndex.

@Consumer(name = "auditReplay", minIndex = 111677748019200000L)
public class AuditReplayHandler {
@HandleEvent
void on(CreateUser event) {
// ... rebuild projections, audit, etc.
}
}
long index = IndexUtils.indexFromTimestamp(
Instant.parse("2024-01-01T00:00:00Z"));
// -> 111677748019200000L

This approach is perfect for:

  • Starting fresh consumers for replays
  • Bootstrapping projections without interfering with live handlers
  • Keeping logic encapsulated and isolated

If you want to reset an existing consumer to an earlier point in the log:

long replayIndex = 111677748019200000L;
Fluxzero.client()
.getTrackingClient(MessageType.EVENT)
.resetPosition("myConsumer", replayIndex, Guarantee.STORED);

Sometimes you want the same handler class to do both live processing and a historical replay (e.g., to rebuild read models).

Mark the handler’s consumer as exclusive = false:

@Consumer(name = "live", exclusive = false)
public class OrderProcessor {
@HandleCommand
void handle(SendOrder command) {
// submit an order
}
}

Then register a second consumer at runtime that targets the same handler but a different index window:

fluxzeroBuilder.addConsumerConfiguration(
ConsumerConfiguration.builder()
.name("replay") // new consumer
.handlerFilter(h -> h instanceof OrderProcessor) // same class
.minIndex(111677748019200000L) // start of window
.maxIndexExclusive(111853279641600000L) // end of window (exclusive)
.build(),
MessageType.COMMAND
);

This spins up a parallel tracker that replays messages between the two indices while the original live consumer continues uninterrupted.


For replaying failures from the error log (dynamic DLQ), use the dedicated Dynamic dead-lettering guide.


© 2026 Fluxzero