KubeMQ
Client SDKsGoHow-to guidesQueues

Delayed Messages

Send KubeMQ queue messages with a delivery delay using the Go SDK so consumers see them only after a wait.

Which to use

This is the task-oriented guide for sending delayed messages via the single-send API. For the stream-based SetDelaySeconds option and its edge cases, see Delay Policy.

Overview

A delivery delay holds a queue message out of consumers' reach for a fixed window after it's sent — the message is accepted and persisted immediately, but invisible to pollers until the delay expires. It's the building block for scheduled work — a reminder to fire in an hour, a retry with back-off, a task queued for off-peak processing — without standing up a separate scheduler or cron service.

Set it with SetDelaySeconds on the message before sending; the broker does the waiting. The send result's DelayedTo field returns the Unix timestamp when the message becomes visible, so you can log or monitor exactly when delivery will happen. Until then, any poll against that channel simply returns nothing for that message — it isn't hidden in a separate place, it's the same queue, just not yet eligible for delivery.

Gotchas: the delay is set once at send time and can't be extended or shortened afterward — if you need a different wait, send a new message. A long delay still counts as an in-flight, persisted message, so it survives a broker restart, but it also occupies queue storage for the whole waiting period. Don't confuse this with a visibility timeout after delivery — that's a separate mechanism for redelivery on failed acknowledgment, not initial availability.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Go SDK installed (go get github.com/kubemq-io/kubemq-go/v2)

Code

main.go
// Example: queues/delayed-messages
//
// Demonstrates sending a delayed queue message. The message becomes
// available for consumption only after the specified delay period.
//
// Channel: go-queues.delayed-messages
// Client ID: go-queues-delayed-messages-client
//
// Run with a KubeMQ server on localhost:50000
// (see https://docs.kubemq.io/deploy).
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/kubemq-io/kubemq-go/v2"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	client, err := kubemq.NewClient(ctx,
		kubemq.WithAddress("localhost", 50000),
		kubemq.WithClientId("go-queues-delayed-messages-client"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	channel := "go-queues.delayed-messages"

	// Send a message with a 3-second delay.
	delayedMsg := kubemq.NewQueueMessage().
		SetChannel(channel).
		SetBody([]byte("delayed message")).
		SetDelaySeconds(3)

	result, err := client.SendQueueMessage(ctx, delayedMsg)
	if err != nil {
		log.Fatal(err)
	}
	if result.IsError {
		log.Fatalf("Send failed: %s", result.Error)
	}
	fmt.Printf("Delayed message sent: id=%s delayedTo=%d\n",
		result.MessageID, result.DelayedTo)
	fmt.Println("Message will be available after 3 seconds")
}

How It Works

  1. kubemq.NewQueueMessage().SetDelaySeconds(3) attaches a delivery delay to the message; the broker holds the message invisibly until the delay expires, then makes it available for consumption.
  2. result.DelayedTo in the send response contains the Unix epoch timestamp (seconds) at which the message will become visible — useful for logging or monitoring delayed message pipelines.
  3. A consumer polling the queue before the delay expires will receive zero messages even though the message is stored; it becomes visible only after the delay elapses.
  4. Delayed messages are durable — a broker restart during the delay period does not lose them.

Was this page helpful?

On this page