All Products
Search
Document Center

ApsaraMQ for RocketMQ:Send and receive scheduled messages

Last Updated:Mar 11, 2026

Scheduled messages are delivered to consumers at a specified timestamp rather than immediately. Use them in scenarios in which a time window between message production and message consumption is required, or scenarios in which scheduled tasks are triggered by messages -- for example, canceling an unpaid order after 30 minutes or triggering a periodic cleanup task.

The .NET sample code below demonstrates how to send scheduled messages with the TCP client SDK. For background on how scheduled and delayed messages differ, see Scheduled messages and delayed messages.

Supported regions

Scheduled messages are available in the following regions:

  • Internet

  • China (Hangzhou)

  • China (Beijing)

  • China (Shanghai)

  • China (Shenzhen)

How it works

  1. The producer calls setStartDeliverTime to set a delivery timestamp on the message.

  2. The broker holds the message until the specified timestamp.

  3. At the delivery time, the message becomes available for consumers.

The delivery time is a millisecond-level Unix timestamp (absolute time, not a relative delay).

Prerequisites

Before you begin, make sure you have:

Send a scheduled message

The following example sends a message scheduled for delivery 3 seconds from now. For more examples, see the ApsaraMQ for RocketMQ code repository.

Replace the placeholders before running the code:

PlaceholderDescriptionWhere to find it
<your-group-id>Consumer group IDApsaraMQ for RocketMQ console
<your-tcp-endpoint>TCP endpointInstance Details page, TCP Endpoint section
<your-topic>Topic nameApsaraMQ for RocketMQ console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using ons;

namespace ons
{
    class onscsharp
    {
        private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        public static long CurrentTimeMillis()
        {
           return (long) (DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
        }

        static void Main(string[] args)
        {
            // Configure the producer.
            ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
            // Consumer group ID created in the ApsaraMQ for RocketMQ console.
            factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<your-group-id>");
            // TCP endpoint from the Instance Details page.
            factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, "<your-tcp-endpoint>");
            // Topic created in the ApsaraMQ for RocketMQ console.
            factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
            // Message content.
            factoryInfo.setFactoryProperty(ONSFactoryProperty.MsgContent, "scheduled_msg_body");
            // Load AccessKey credentials from environment variables.
            // Make sure ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
            factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
            factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));

            // Create and start the producer. Call start() only once before sending messages.
            Producer pProducer = ONSFactory.getInstance().createProducer(factoryInfo);
            pProducer.start();

            Message msg = new Message(
                factoryInfo.getPublishTopics(),  // Topic
                "TagA",                          // Message tag for filtering
                factoryInfo.getMessageContent()  // Message body
            );

            // Set a business key for message tracing in the console.
            // Optional -- messages send and receive correctly without a key.
            msg.setKey("ORDERID_100");

            // Set the delivery time to 3 seconds from now (millisecond Unix timestamp).
            long deliverTime = CurrentTimeMillis() + 3000;
            msg.setStartDeliverTime(deliverTime);

            // Send the message. A successful call returns a SendResultONS object.
            try
            {
                SendResultONS sendResult = pProducer.send(msg);
            }
            catch(ONSClientException e)
            {
                // Handle send failures (network issues, invalid parameters, etc.).
            }

            // Shut down the producer before exiting to avoid memory leaks.
            pProducer.shutdown();

        }
    }
}

Subscribe to scheduled messages

Scheduled messages require no special consumer configuration. After the delivery time arrives, the message appears in the topic like any other message. Use the same consumer code as for normal messages.

For sample code, see Subscribe to messages.

Usage notes