Skill 111 · Amazon Eventbridge Event Bus
Subchapter 111.12
references/replay-and-recovery.mdMarkdown5 KBView on GitHub
Load this when a subscriber must read history rather than only new events, when pausing or resuming a subscriber, or when a replay appears not to be working.
There is no separate replay API. Replay is a subscriber’s starting position, evaluated against the bus’s retained events.
Retention is set per bus with StorageConfiguration.RetentionPeriodInDays. Reads return
StorageConfigurationOutput with an extra field, RetentionWindowStartTime: the earliest point from which
stored events are still available.
That field is computed, not stored:
RetentionWindowStartTime = max(now - RetentionPeriodInDays, time the bus was created)Two consequences people trip over. A bus younger than its retention period reports its creation time, and changing the retention period does not move the value until the bus is older than the period, because no event can predate its own bus. And any time you name a point in the past, the service clamps it against this same boundary; a point earlier than the window is rejected.
So on a young bus even a recent past timestamp can fall outside the window.
StartingPosition is one of:
LATEST: deliver only events published after this subscriber exists.POINT_IN_TIME: deliver from a point in the retained history. Requires PointInTimeConfiguration, whose
PointType is either HORIZON (the oldest retained event) or TIMESTAMP (a StartingPoint you name).
An optional EndPoint bounds the window, giving a finite replay that then stops.Take a bus holding five events, all published before any subscriber existed, three of them before a chosen midpoint and two after. Each starting position then delivers:
| Subscriber | Delivers |
|---|---|
LATEST | none of the five |
POINT_IN_TIME / HORIZON | all five, once each |
POINT_IN_TIME / TIMESTAMP at the midpoint | exactly the two published after it |
Replay is exact. Three practical notes:
SystemMetadata."aws:DeliveryType" reads REPLAY instead of LIVE. Use
it if a replay must be idempotent on the consumer side, and use WITH_METADATA or a JSONata transformer
to surface it.StartingPoint is a timestamp, so you MUST send it in the wire form for timestamps, epoch seconds,
because an ISO-8601 string is not accepted.The validation around starting positions is precise:
StartingPoint earlier than the retention window
-> PointInTimeConfiguration.StartingPoint (...) falls outside the bus's retention window
StartingPoint in the future
-> PointInTimeConfiguration.StartingPoint must not be in the future
POINT_IN_TIME without PointInTimeConfiguration
-> PointInTimeConfiguration is required when StartingPosition is POINT_IN_TIME
PointType TIMESTAMP without StartingPoint
-> PointInTimeConfiguration.StartingPoint is required and must be > 0 when PointType is TIMESTAMP
PointInTimeConfiguration supplied with StartingPosition LATEST
-> PointInTimeConfiguration must not be provided when StartingPosition is LATESTAfter the subscriber exists, pausing and resuming is State on UpdateSubscriber:
State: STOPPED stops delivery. Events continue to accrue as a backlog, bounded by retention.State: RUNNING resumes. ResumePosition chooses what happens to the backlog: LAST_PROCESSED (the
default) delivers it, and LATEST skips it and resumes at the tip.ResumePosition is honoured only on an update that moves State from STOPPED to RUNNING, and is
rejected on any other call.LATEST is a one-shot instruction applied asynchronously. No read surface reports whether it has been
applied yet, so a caller cannot distinguish “backlog already skipped” from “backlog about to be skipped”.
If that distinction matters, you SHOULD drive it from the consumer side using aws:SequenceNumber
rather than infer it from the control plane.StartingPosition is create-only, and a subscriber replacement is delete-then-create, so a replacement
starts from its own starting position. With LATEST it never sees anything published during the gap. To
fill in that gap, you SHOULD give the replacement POINT_IN_TIME with a TIMESTAMP from before the
change.
See infrastructure-as-code.md for the CloudFormation form of this.