Subscriber Overview

This document gives an overview of how subscriptions work in Google Cloud Pub/Sub. For details on pull and push delivery subscriptions, see the Pull Subscriber Guide and the Push Subscriber Guide.

To receive messages published to a topic, you must create a subscription to that topic. The subscription connects the topic to a subscriber application that receives and processes messages published to the topic. A topic can have multiple subscriptions, but a given subscription belongs to a single topic.

At-Least-Once Delivery

Google Cloud Pub/Sub offers an "at-least-once delivery" guarantee: each published message is delivered to a subscriber at least once for every subscription.

The at-least-once delivery guarantee is not absolute: each subscription has a configurable maximum retention time for a message. A message that could not be delivered within that time is deleted and is no longer accessible. This typically happens when subscribers do not keep up with the flow of messages. A message published before a given subscription was created will usually not be delivered. Thus, messages published to a topic with no subscription cannot be retrieved until at least one subscription is created.

Once a message is sent to a subscriber, the subscriber must either acknowledge or drop the message. A message is considered outstanding once it has been sent out for delivery and before a subscriber acknowledges it. Google Cloud Pub/Sub will repeatedly attempt to deliver any message that has not been acknowledged or that is not outstanding. Google Cloud Pub/Sub usually does not redeliver acknowledged messages. A subscriber has a configurable, limited amount of time, or ackDeadline, to acknowledge the message. Once the deadline has passed, an outstanding message becomes unacknowledged.

Typically, Pub/Sub delivers each message once and in the order in which it was published. However, messages may sometimes be delivered out of order or more than once. Accommodating more than one delivery requires your subscriber to be idempotent when processing messages. If ordering is important, we recommend that the publisher of the topic to which you subscribe include a sequence token in the message. See Message Ordering for more information.

Push and Pull Delivery

A subscription can use either the push or pull mechanism for message delivery. You can change or configure the mechanism at any time. In push delivery, Pub/Sub initiates requests to your subscriber application to deliver messages. In pull delivery, your subscriber application initiates requests to the Pub/Sub server to retrieve messages.

For a push subscription, the Pub/Sub server sends each message as an HTTPs request to the subscriber application at a pre-configured endpoint. The endpoint acknowledges the message by returning an HTTP success status code. This indicates that the message has been successfully processed and the Pub/Sub system can delete it from the subscription. A non-success response indicates that the message should be resent. Pub/Sub dynamically adjusts the rate of push requests, based on the rate at which it receives success responses.

In a pull subscription, the subscribing application explicitly calls the pull method, which requests delivery of a message in the subscription queue. The Pub/Sub server responds with the message (or an error if the queue is empty), and an ack ID. The subscriber then explicitly calls the acknowledge method, using the returned ack ID, to acknowledge receipt.

The following table offers some guidance in choosing the appropriate delivery mechanism for your application:

Pull Push
  • Large volume of messages (many more than 1/second).
  • Efficiency and throughput of message processing is critical.
  • Public HTTPs endpoint, with non-self-signed SSL certificate, is not feasible to set up.
  • Subscribers with low traffic (less than 10,000/second).
  • Legacy push webhooks.
  • App Engine subscribers.

The following table compares pull and push delivery:

  Pull Push
Endpoints Any device on the internet is +able to call the Pub/Sub API (and in possession of authorized credentials). An HTTPS server with non-self-signed certificate accessible on the public web. The receiving endpoint may be decoupled from the Pub/Sub subscription, so that messages from multiple subscriptions may be sent to a single endpoint.
Load balancing Multiple subscribers can make pull calls to the same "shared" subscription. Each subscriber will receive a subset of the messages. The push endpoint can be a load balancer.
Configuration No configuration is necessary. No configuration is necessary for App Engine apps in the same project as the subscriber.
Configuration (and verification) of push endpoints is required in the Google Cloud Platform Console for all other endpoints. Endpoints must be reachable via DNS names and have SSL certificates installed.
Latency Delays will occur between message publication and delivery. Delivery is immediate (except when delivery is being rate-limited to avoid overwhelming the endpoint). There is no added latency from pull requests.
Message handling and flow control Message acknowledgment is explicit. The subscriber client controls the rate of delivery. The subscriber can dynamically modify the ack deadline, allowing message processing to be arbitrarily long. The Pub/Sub server automatically implements flow control. There is no need to handle message flow at the client side (although it is possible to indicate that the client cannot handle the current message load by passing back an HTTP error).
Efficiency and throughput Achieves high throughput at low CPU and bandwidth by allowing batched delivery and acknowledgments as well as massively parallel consumption. May be inefficient if aggressive polling is used to minimize message delivery time. Delivers one message per request and limits maximum number of outstanding messages.

Configuring Subscriptions

A subscription is created for a single topic. It has several properties that can be set at creation time or updated later, including:

  • Delivery method: By default, Pub/Sub subscriptions use the pull method. You can switch to push delivery by specifying a non-empty, valid HTTPs push endpoint URL. You can switch back to pull delivery by specifying an empty URL.
  • An acknowledgment deadline: If your code doesn't acknowledge the message before the deadline, the message is sent again. The default is 10 seconds. The maximum custom deadline you can specify is 600 seconds (10 minutes).
  • Maximum message retention duration: The maximum amount of time for which Google Cloud Pub/Sub will retain and attempt to deliver a message. Default and maximum values are seven days. Ten minutes is the minimum.

You can create a subscription using the Google Cloud Platform Console UI or the gcloud command-line tool, as described in the Quickstart. See also the gcloud reference for subscriber commands.

A complete set of HTTP, RPC, and client library APIs is also available for automation.

Here is some sample code to create a subscription:

Protocol

Request:

PUT https://pubsub.googleapis.com/v1/projects/myproject/subscriptions/mysubscription
{
  "topic": "projects/someproject/topics/sometopic"
  // Only needed if you are using push delivery
  "pushConfig": {
    "pushEndpoint": "https://myproject.appspot.com/myhandler"
  }
}

Response:

200 OK
{
  "name": "projects/myproject/subscriptions/mysubscription",
  "topic": "projects/someproject/topics/sometopic",
  "pushConfig": {
    "pushEndpoint": "https://myproject.appspot.com/myhandler"
  },
  "ackDeadlineSeconds": 10
}

C#

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

TopicName topicName = new TopicName(_projectId, topicId);
SubscriptionName subscriptionName = new SubscriptionName(_projectId,
    subscriptionId);
try
{
    Subscription subscription = subscriber.CreateSubscription(
        subscriptionName, topicName, pushConfig: null,
        ackDeadlineSeconds: 60);
}
catch (RpcException e)
when (e.Status.StatusCode == StatusCode.AlreadyExists)
{
    // Already exists.  That's fine.
}

Go

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

sub, err := client.CreateSubscription(ctx, name, topic, 20*time.Second, nil)
if err != nil {
	return err
}
fmt.Printf("Created subscription: %v\n", sub)

Java

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
  // eg. projectId = "my-test-project", topicId = "my-test-topic"
  TopicName topicName = TopicName.create(projectId, topicId);
  // eg. subscriptionId = "my-test-subscription"
  SubscriptionName subscriptionName =
      SubscriptionName.create(projectId, subscriptionId);
  // create a pull subscription with default acknowledgement deadline
  Subscription subscription =
      subscriptionAdminClient.createSubscription(
          subscriptionName, topicName, PushConfig.getDefaultInstance(), 0);
  return subscription;
}

Node.js

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

function createSubscription (topicName, subscriptionName) {
  // Instantiates a client
  const pubsub = PubSub();

  // References an existing topic, e.g. "my-topic"
  const topic = pubsub.topic(topicName);

  // Creates a new subscription, e.g. "my-new-subscription"
  return topic.subscribe(subscriptionName)
    .then((results) => {
      const subscription = results[0];

      console.log(`Subscription ${subscription.name} created.`);

      return subscription;
    });
}

PHP

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

use Google\Cloud\PubSub\PubSubClient;

/**
 * Creates a Pub/Sub subscription.
 *
 * @param string $projectId  The Google project ID.
 * @param string $topicName  The Pub/Sub topic name.
 * @param string $subscriptionName  The Pub/Sub subscription name.
 */
function create_subscription($projectId, $topicName, $subscriptionName)
{
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $subscription = $topic->subscription($subscriptionName);
    $subscription->create();

    printf('Subscription created: %s' . PHP_EOL, $subscription->name());
}

Python

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

def create_subscription(topic_name, subscription_name):
    """Create a new pull subscription on the given topic."""
    pubsub_client = pubsub.Client()
    topic = pubsub_client.topic(topic_name)

    subscription = topic.subscription(subscription_name)
    subscription.create()

    print('Subscription {} created on topic {}.'.format(
        subscription.name, topic.name))

Ruby

For more on installing and creating a Cloud Pub/Sub client, refer to Cloud Pub/Sub Client Libraries.

pubsub = Google::Cloud::Pubsub.new project: "my-gcp-project-id"
topic  = pubsub.topic "my-topic"

subscription = topic.subscribe "my-subscription"

puts "Subscription created #{subscription.name}"

Lifecycle of a Subscription

Subscriptions with no activity (push successes or pull requests) for 31 days may be deleted automatically. You can also delete a subscription manually. Although you can create a new subscription with the same name as a deleted one, the delivery guarantee applies to each subscription independent of its name. In other words, the new subscription has no relation to the old one, even though they have the same name. Therefore, the new subscription has no backlog at the time it is created (no messages waiting for delivery), even if the deleted subscription had a large number of unacknowledged messages.

Send feedback about...

Cloud Pub/Sub