A consumer is a client application that subscribes to topics and processes messages from ApsaraMQ for RocketMQ. Consumers connect to brokers, retrieve messages based on their subscriptions, and pass them to your business logic for processing.
Three factors determine how a consumer behaves:
Consumer group: Every consumer must belong to a consumer group. The group defines shared behavior settings -- such as delivery order and retry policy -- and tracks consumption progress across its members.
Consumer type: Choose between a push consumer (broker-driven delivery) and a simple consumer (application-driven pull). See Consumer types.
Client-side settings: Thread count, concurrency, and other local configurations control how the consumer processes messages on your application host.
How it works
The following diagram shows where consumers sit in the ApsaraMQ for RocketMQ domain model.

Producers send messages to the ApsaraMQ for RocketMQ broker.
The broker stores each message in the queue specified by the target topic, preserving arrival order.
Consumers retrieve and process messages from the broker based on their subscriptions.
Consumers within the same consumer group share the full set of messages delivered to that group.
Internal attributes
- The name of the consumer group that this consumer belongs to. A consumer inherits its delivery order and retry policy from its consumer group.
- Consumer groups are logical resources. Create them through the console or API before use. For naming rules and other constraints, see Usage limits.
- A unique identifier for each consumer client instance within a cluster. The ApsaraMQ for RocketMQ SDK generates this value automatically. Client IDs appear in logs and are useful for troubleshooting but cannot be modified.
- The list of topics and filter expressions that a consumer subscribes to. Specify subscriptions during consumer initialization so the broker can validate topic permissions and availability upfront, rather than after the application starts.
- If no subscription is specified at initialization -- or if subscribed topics change at runtime -- ApsaraMQ for RocketMQ performs dynamic validation, which may delay error detection.
- A callback interface that the broker invokes to deliver messages to a push consumer. Configure the message listener on the consumer client.
- Simple consumers retrieve messages explicitly and do not use listeners. For more information, see Consumer types.
Behavior constraints
All consumers in the same consumer group must share identical settings for:
| Setting | Description |
|---|---|
| Message delivery order | Determines whether messages are delivered sequentially or concurrently |
| Consumption retry policy | Defines how failed messages are retried |
Inconsistent settings across consumers in the same group lead to unpredictable delivery behavior. How these settings are enforced depends on the broker version. See the next section for details.
Version compatibility
| Behavior | 5.x brokers | 3.x / 4.x brokers |
|---|---|---|
| Where delivery order and retry policy are defined | On the consumer group (server-side) | On each consumer client (client-side API) |
| Developer responsibility | No client-side configuration needed -- consumers inherit settings from the group | Set delivery order and retry policy on every consumer client to ensure consistency across the group |
If you use an earlier SDK version to connect to a 5.x broker, the consumer still reads delivery order and retry policy from the client-side API configuration rather than from the consumer group.
Best practices
Initialize one consumer per group per process
ApsaraMQ for RocketMQ consumers use a non-blocking protocol that supports concurrent, multi-threaded access. A single consumer instance can handle high throughput. In most cases, initialize one consumer per consumer group in each process. Creating multiple consumer instances with the same configuration within a process wastes resources without improving performance.
Reuse consumers instead of creating and destroying them
Treat consumer instances like database connection pools -- create them once and reuse them throughout the application lifecycle. Creating a new consumer for every batch of messages and destroying it afterward generates excessive short-lived connections on the broker, increasing system load unnecessarily.
Correct -- create once, consume in a loop, shut down on exit:
Consumer c = ConsumerBuilder.build();
for (int i = 0; i < n; i++) {
Message m = c.receive();
// process message
}
c.shutdown();Incorrect -- create and destroy inside the loop:
for (int i = 0; i < n; i++) {
Consumer c = ConsumerBuilder.build();
Message m = c.receive();
// process message
c.shutdown();
}What's next
Consumer groups: Learn how consumer groups manage shared delivery settings and track consumption progress.
Consumer types: Compare push consumers and simple consumers to decide which fits your use case.
Usage limits: Check naming rules, quotas, and other constraints for consumer groups.