Order messages

Message ordering is a feature in Pub/Sub that lets you receive messagesin your subscriber clients in the order that they were published by thepublisher clients.

For example, assume that a publisher client in a region publishes messages 1, 2,and 3 in order. With message ordering, the subscriber client receives thepublished messages in the same order. To be delivered in order, the publisherclient must publish the messages in the sameregion.However, subscribers can connect to any region and the ordering guarantee isstill maintained.

Message ordering is a useful feature for scenarios such as database changecapture, user session tracking, and streaming applications where preserving thechronology of events is important.

This page explains the concept of message ordering and how to set up yoursubscriber clients to receive messages in order. To configure your publisherclients for message ordering, seeUse ordering keys to publish amessage.

Overview of message ordering

Ordering in Pub/Sub is determined by the following:

  • Ordering key: This is a string that is used in thePub/Sub message metadata and represents the entity for whichmessages must be ordered. The ordering key can be up to 1 KB in length. Toreceive a set of ordered messages in a region, you must publish all messageswith the same ordering key in the same region. Some examples of orderingkeys are customer IDs and the primary key of a row in a database.

    The publish throughput on each ordering key is limited to 1 MBps. Thethroughput across all ordering keys on a topic is limited to the quotaavailable in apublish region. This limit can be increasedto many units of GBps.

    An ordering key is not equivalent to a partition in a partition-basedmessaging system as ordering keys are expected to have a much highercardinality than partitions.

  • Enable message ordering: This is a subscription setting. When asubscription has message ordering enabled, the subscriber clients receivemessages published in the same region with the same ordering key in theorder in which they were received by the service. You mustenable this settingin the subscription.

    Assume that you have two subscriptions A and B attached to the same topic T.Subscription A is configured with message ordering enabled and subscriptionB is configured without message ordering enabled. In this architecture, bothsubscriptions A and B receive the same set of messages from the topic T. Ifyou publish messages with ordering keys in the same region, subscription Areceives the messages in the order they were published. Whereas,subscription B receives the messages without any ordering expected.

In general, if your solution requires publisher clients to send both ordered andunordered messages, create separate topics, one for ordered messages and theother for unordered messages.

Considerations when using ordered messaging

The following list contains important information regarding the behavior ofordered messaging in Pub/Sub:

  • Within-key ordering: Messages published with the same ordering key areexpected to be received in order. Assume that for ordering key A, youpublish messages 1, 2, and 3. With ordering enabled, 1 is expected to bedelivered before 2 and 2 is expected to be delivered before 3.

  • Across-key ordering: Messages published with different ordering keys arenot expected to be received in order. Assume you have ordering keys A and B.For ordering key A, messages 1 and 2 are published in order. For orderingkey B, messages 3 and 4 are published in order. However, message 1 couldarrive before or after message 4.

  • Message redelivery: Pub/Sub delivers each messageat least once, so thePub/Sub service might redeliver messages. Redeliveries of amessage trigger redelivery of all subsequent messages for that key, evenacknowledged ones. Assume that a subscriber client receives messages 1, 2,and 3 for a specific ordering key. If message 2 is redelivered (because theacknowledgment deadline expired or the best-effort acknowledgment did notpersist in Pub/Sub), then message 3 is also redelivered. Ifboth message ordering and adead-letter topic are enabled on a subscription, this behavior might not be true, as Pub/Subforwards messages to dead-letter topics on a best-effort basis.

  • Acknowledgment delays and dead-letter topics: Unacknowledged messagesfor a given ordering key can potentially delay delivery of messages forother ordering keys, especially during server restarts or traffic changes.To maintain order across such events, ensure timely acknowledgment of allmessages. If timely acknowledgment is not possible, consider using adead-letter topic to prevent indefinite message holding. Be aware that ordermight not be preserved when messages are written to a dead-letter topic.

  • Message affinity (streamingPull clients): Messages for the same key areusually delivered to the same streamingPull subscriber client. Affinity isexpected when messages are outstanding for an ordering key to a specificsubscriber client. If there are no outstanding messages, affinity mightshift for load balancing or client disconnects.

    To ensure smooth processing even with potential affinity changes, it'scrucial to design your streamingPull application in a way that it can handlemessages in any client for a given ordering key.

  • Integration with Dataflow: Don't enable message ordering forsubscriptions when configuring Dataflow withPub/Sub. Dataflow has its own mechanism fortotal message ordering, ensuring chronological order across all messages aspart of windowing operations. This method of ordering differs fromPub/Sub's ordering key-based approach. Using ordering keyswith Dataflow can potentially reduce pipeline performance.

  • Automatic scaling: Pub/Sub's ordered delivery scales tobillions of ordering keys. A larger number of ordering keys allows moreparallel delivery to subscribers since ordering applies to all the messageswith the same ordering key.

  • Performance tradeoffs: Ordered delivery does come with some tradeoffs.Compared with unordered delivery, ordered delivery decreases publishavailability and increases end-to-end message delivery latency. In theordered delivery case, failover requires coordination to ensure the messagesare written to and read in the correct order.

  • Hot key: When using message ordering, all messages with the sameordering key are sent to your subscriber client in the order they arereceived by the service. The user callback doesn't run until the callbackcompletes for the previous message. The maximum throughput for messagessharing the same ordering key when delivering to subscribers is not limitedby Pub/Sub , but by the processing speed of your subscriberclient. A hot key occurs when a backlog builds on an individual orderingkey because the number of messages produced per second exceeds the number ofmessages that the subscriber can process per second. To mitigate hot keys,use the most granular keys that you can and minimize per-message processingtime. You can also monitor thesubscription/oldest_unacked_message_agemetric for a rising value, which might indicate a hot key.

For more information about how to use message ordering, see the followingbest-practices topics:

Subscriber client behavior for message ordering

Subscriber clients receive messages in the order they were published in aspecific region. Pub/Sub supports different ways of receivingmessages, such as subscriber clients connected to pull and pushsubscriptions. The client libraries use streamingPull(with the exception of PHP).

To learn more about these subscription types, seeChoose a subscription type.

The following sections discuss what receiving messages in order meansfor each type of subscriber client.

StreamingPull subscriber clients

When using the client libraries with streamingPull, you must specify a usercallback that runs whenever a message is received by a subscriber client.With client libraries, for any given ordering key, the callback is run tocompletion on messages in the correct order. If the messages areacknowledged within that callback, all computations on a message occurin order. However, if the user callback schedules other asynchronous workon messages, the subscriber client must ensure that the asynchronous workis done in order. One option is to add messages to a local work queue thatis processed in order.

Pull subscriber clients

For subscriber clients connected to pull subscriptions, Pub/Submessage ordering supports the following:

  • All messages for an ordering key in thePullResponseare in the proper order in the list.

  • Only one batch of messages can be outstanding for an ordering keyat a time.

The requirement that only one batch of messages can be outstanding at atime is necessary to maintain ordered delivery since the Pub/Subservice can't ensure the success or latency of the response that it sendsfor a subscriber's pull request.

Push subscriber clients

The restrictions on push are even tighter than those on pull.For a push subscription, Pub/Sub supports only one outstandingmessage for each ordering key at a time. Each message is sent to apush endpoint as a separate request. Thus, sending the requests outin parallel would have the same issue as delivering multiple batches ofmessages for the same ordering key to pull subscribers simultaneously.Push subscriptions might not be a good choice for topics where messages arefrequently published with the same ordering key or where latency isextremely important.

Export subscriber clients

Export subscriptions support ordered messages. For BigQuerysubscriptions, messages with the same ordering key are written to theirBigQuery table in order. For Cloud Storage subscriptions,messages with the same ordering key might not all be written to the same file.When within the same file, messages for an ordering key are in order. Whenspread across multiple files, later messages for an ordering key can appear in afile with a name that has an earlier timestamp than the timestamp in the name ofthe file with the earlier messages.

Enable message ordering

To receive the messages in order, set the message ordering property on thesubscription you receive messages from. Receiving messages in order mightincrease latency. You can't change the message ordering property after youcreate a subscription.

You can set the message ordering property when you create a subscription usingthe Google Cloud console, the Google Cloud CLI, or the Pub/Sub API.

Console

To create a subscription with the message ordering property, follow thesesteps:

  1. In the Google Cloud console, go to theSubscriptions page.

Go to Subscriptions

  1. ClickCreate subscription.

  2. Enter aSubscription ID.

  3. Choose a topic from which you want to receive messages.

  4. In theMessage ordering section, selectOrder messages with anordering key.

  5. ClickCreate.

gcloud

To create a subscription with the message ordering property, use thegcloud pubsub subscriptionscreate command and the--enable-message-ordering flag:

gcloudpubsubsubscriptionscreateSUBSCRIPTION_ID\--enable-message-ordering

ReplaceSUBSCRIPTION_ID with the ID of the subscription.

If the request is successful, the command line displays a confirmation:

Created subscription [SUBSCRIPTION_ID].

REST

To create a subscription with the message ordering property, send aPUTrequest like the following:

PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_IDAuthorization: Bearer $(gcloud auth application-default print-access-token)

Replace the following:

  • PROJECT_ID: the project ID of the project with the topic
  • SUBSCRIPTION_ID: the ID of the subscription

In the request body, specify the following:

{"topic":TOPIC_ID,"enableMessageOrdering":true,}

ReplaceTOPIC_ID with the ID of the topic to attach to thesubscription.

If the request is successful, the response is the subscription in JSONformat:

{  "name": projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID,  "topic": projects/PROJECT_ID/topics/TOPIC_ID,  "enableMessageOrdering": true,}

C++

Before trying this sample, follow the C++ setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub C++ API reference documentation.

namespacepubsub=::google::cloud::pubsub;namespacepubsub_admin=::google::cloud::pubsub_admin;[](pubsub_admin::SubscriptionAdminClientclient,std::stringconst&project_id,std::stringconst&topic_id,std::stringconst&subscription_id){google::pubsub::v1::Subscriptionrequest;request.set_name(pubsub::Subscription(project_id,subscription_id).FullName());request.set_topic(pubsub::Topic(project_id,topic_id).FullName());request.set_enable_message_ordering(true);autosub=client.CreateSubscription(request);if(sub.status().code()==google::cloud::StatusCode::kAlreadyExists){std::cout <<"The subscription already exists\n";return;}if(!sub)throwstd::move(sub).status();std::cout <<"The subscription was successfully created: "            <<sub->DebugString() <<"\n";}

C#

Before trying this sample, follow the C# setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub C# API reference documentation.

usingGoogle.Cloud.PubSub.V1;usingGrpc.Core;publicclassCreateSubscriptionWithOrderingSample{publicSubscriptionCreateSubscriptionWithOrdering(stringprojectId,stringtopicId,stringsubscriptionId){SubscriberServiceApiClientsubscriber=SubscriberServiceApiClient.Create();vartopicName=TopicName.FromProjectTopic(projectId,topicId);varsubscriptionName=SubscriptionName.FromProjectSubscription(projectId,subscriptionId);varsubscriptionRequest=newSubscription{SubscriptionName=subscriptionName,TopicAsTopicName=topicName,EnableMessageOrdering=true};Subscriptionsubscription=null;try{subscription=subscriber.CreateSubscription(subscriptionRequest);}catch(RpcExceptione)when(e.Status.StatusCode==StatusCode.AlreadyExists){// Already exists.  That's fine.}returnsubscription;}}

Go

The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, seethe migration guide to v2.To see a list of v1 code samples, seethe deprecated code samples.

Before trying this sample, follow the Go setup instructions inQuickstart: Using Client Libraries.For more information, see thePub/Sub Go API reference documentation.

import("context""fmt""io""cloud.google.com/go/pubsub/v2""cloud.google.com/go/pubsub/v2/apiv1/pubsubpb")funccreateWithOrdering(wio.Writer,projectID,topic,subscriptionstring)error{// projectID := "my-project-id"// topic := "projects/my-project-id/topics/my-topic"// subscription := "projects/my-project/subscriptions/my-sub"ctx:=context.Background()client,err:=pubsub.NewClient(ctx,projectID)iferr!=nil{returnfmt.Errorf("pubsub.NewClient: %w",err)}deferclient.Close()// Message ordering can only be set when creating a subscription.sub,err:=client.SubscriptionAdminClient.CreateSubscription(ctx,&pubsubpb.Subscription{Name:subscription,Topic:topic,EnableMessageOrdering:true,})iferr!=nil{returnfmt.Errorf("CreateSubscription: %w",err)}fmt.Fprintf(w,"Created subscription: %v\n",sub)returnnil}

Java

Before trying this sample, follow the Java setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Java API reference documentation.

importcom.google.cloud.pubsub.v1.SubscriptionAdminClient;importcom.google.pubsub.v1.ProjectSubscriptionName;importcom.google.pubsub.v1.ProjectTopicName;importcom.google.pubsub.v1.Subscription;importjava.io.IOException;publicclassCreateSubscriptionWithOrdering{publicstaticvoidmain(String...args)throwsException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringtopicId="your-topic-id";StringsubscriptionId="your-subscription-id";createSubscriptionWithOrderingExample(projectId,topicId,subscriptionId);}publicstaticvoidcreateSubscriptionWithOrderingExample(StringprojectId,StringtopicId,StringsubscriptionId)throwsIOException{try(SubscriptionAdminClientsubscriptionAdminClient=SubscriptionAdminClient.create()){ProjectTopicNametopicName=ProjectTopicName.of(projectId,topicId);ProjectSubscriptionNamesubscriptionName=ProjectSubscriptionName.of(projectId,subscriptionId);Subscriptionsubscription=subscriptionAdminClient.createSubscription(Subscription.newBuilder().setName(subscriptionName.toString()).setTopic(topicName.toString())// Set message ordering to true for ordered messages in the subscription..setEnableMessageOrdering(true).build());System.out.println("Created a subscription with ordering: "+subscription.getAllFields());}}}

Node.js

Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.

/** * TODO(developer): Uncomment these variables before running the sample. */// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';// Imports the Google Cloud client libraryconst{PubSub}=require('@google-cloud/pubsub');// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateSubscriptionWithOrdering(topicNameOrId,subscriptionNameOrId,){// Creates a new subscriptionawaitpubSubClient.topic(topicNameOrId).createSubscription(subscriptionNameOrId,{enableMessageOrdering:true,});console.log(`Created subscription${subscriptionNameOrId} with ordering enabled.`,);console.log('To process messages in order, remember to add an ordering key to your messages.',);}

Node.js

Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.

/** * TODO(developer): Uncomment these variables before running the sample. */// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';// Imports the Google Cloud client libraryimport{PubSub}from'@google-cloud/pubsub';// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateSubscriptionWithOrdering(topicNameOrId:string,subscriptionNameOrId:string,){// Creates a new subscriptionawaitpubSubClient.topic(topicNameOrId).createSubscription(subscriptionNameOrId,{enableMessageOrdering:true,});console.log(`Created subscription${subscriptionNameOrId} with ordering enabled.`,);console.log('To process messages in order, remember to add an ordering key to your messages.',);}

Python

Before trying this sample, follow the Python setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Python API reference documentation.

fromgoogle.cloudimportpubsub_v1# TODO(developer): Choose an existing topic.# project_id = "your-project-id"# topic_id = "your-topic-id"# subscription_id = "your-subscription-id"publisher=pubsub_v1.PublisherClient()subscriber=pubsub_v1.SubscriberClient()topic_path=publisher.topic_path(project_id,topic_id)subscription_path=subscriber.subscription_path(project_id,subscription_id)withsubscriber:subscription=subscriber.create_subscription(request={"name":subscription_path,"topic":topic_path,"enable_message_ordering":True,})print(f"Created subscription with ordering:{subscription}")

Ruby

The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3.To see a list of Ruby v2 code samples, seethe deprecated code samples.

Before trying this sample, follow the Ruby setup instructions inQuickstart: Using Client Libraries.For more information, see thePub/Sub Ruby API reference documentation.

# topic_id        = "your-topic-id"# subscription_id = "your-subscription-id"pubsub=Google::Cloud::PubSub.newsubscription_admin=pubsub.subscription_adminsubscription=subscription_admin.create_subscription\name:pubsub.subscription_path(subscription_id),topic:pubsub.topic_path(topic_id),enable_message_ordering:trueputs"Pull subscription#{subscription_id} created with message ordering."

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.