Delayed Messages

Delaying events or commands is a common use case in many applications. For example, you may want to send the user a reminder after a few days of signing up. It’s not a complex logic to implement, but you can leverage messages to use it out of the box.

Delay Metadata

Watermill’s delay package allows you to add delay metadata to messages.

The delay metadata does nothing by itself. You need to use a Pub/Sub implementation that supports it to make it work.

See below for supported Pub/Subs.

There are two APIs you can use. If you work with raw messages, use delay.Message:

msg := message.NewMessage(watermill.NewUUID(), []byte("hello"))
delay.Message(msg, delay.For(time.Second * 10))

If you use the CQRS component, use delay.WithContext instead (since you can’t access the message directly):

// ...
				cmd := SendFeedbackForm{
					To:   event.Customer.Email,
					Name: event.Customer.Name,
				}

				// In a real world scenario, we would delay the command by a few days
				ctx = delay.WithContext(ctx, delay.For(8*time.Second))

				err := commandBus.Send(ctx, cmd)
				if err != nil {
					return err
				}
// ...

Full source: github.com/ThreeDotsLabs/watermill/_examples/real-world-examples/delayed-messages/main.go

You can also use delay.Until instead of delay.For to specify time.Time instead of time.Duration.

Supported Pub/Subs

Full Example

See the full example in the Watermill repository.


Check our online hands-on training