Publishing
Create topics and publish over KubeMQ — single and batch Publish, server-assigned ids and publish time, ordering keys, and the publish-once-fan-out model.
This guide covers the publish surface end to end: topic lifecycle, a single publish, batch publish
(≤ 1000 messages), the atomic batch-validation rule, ordering keys, and message attributes.
Every topic is a native KubeMQ Events Store log gcp.{topic} (see
Channel mapping).
Topic lifecycle
The Publisher surface ships 9 RPCs (see
Capabilities):
CreateTopic— validates the name;kms_key_nameis accepted-and-ignored; ingestion configs are rejected (INVALID_ARGUMENT); requested retention is clamped to the broker ceiling.GetTopic— returns the requested (un-clamped) retention.ListTopics— opaque page token.UpdateTopic— aFieldMaskoverlabels,message_retention_duration,schema_settings.DeleteTopic— a tombstone: the record is retained so existing subscriptions survive, and re-creating the topic reuses the same log.ListTopicSubscriptions,ListTopicSnapshots,DetachSubscription, andPublish(below).
Topic ids may not start with sub.. That prefix is the reserved broker namespace for
subscription queues (gcp.sub.{s}). Resource ids must be 3..255 chars, start with a letter, use
the charset [A-Za-z0-9._~%+-], and carry no goog prefix. See
Limits & rules.
A single publish
Publish returns a server-assigned message id. The connector writes the message once to
the Events Store log gcp.{topic} — the authoritative, cross-protocol, replayable copy and the
source for Seek — then fans out one queue copy per subscription, applying each subscription's
filter:
- The SDK sends a
PubsubMessage { data, attributes, ordering_key }. - The connector assigns a message id and a publish time and returns the id.
- The message lands in
gcp.{topic}via the Events Store send, then is fanned out to each subscription's queuegcp.sub.{s}.
A filtered-out message is never enqueued for that subscription (it is effectively auto-acked); detached subscriptions are skipped.
A publish writes once to the topic log, then fans out per subscription. The single write to
gcp.{topic} is the source of truth; the per-subscription copies on gcp.sub.{s} are derived from
it. A native KubeMQ consumer of gcp.{topic} therefore sees every published message regardless of
which subscriptions exist. See
Architecture.
Batch publish
Publish accepts a batch of 1..1000 messages. Server-assigned ids are returned in request
order, so a client can correlate each id with its input message.
Atomic batch validation
The whole batch is validated before anything is enqueued. If any message fails validation, the
entire batch is rejected with INVALID_ARGUMENT and nothing is published — there is no
partial publish.
Per-message validation rules:
| Rule | Limit |
|---|---|
| Batch size | 1..1000 messages |
| Total message size | ≤ 10 MiB |
| Attributes | ≤ 100 per message |
| Attribute key | ≤ 256 B, no goog prefix |
| Attribute value | ≤ 1024 B |
| Ordering key | ≤ 1024 B |
| Body | data or attributes must be non-empty |
If the topic has a schema (see Schema validation), every message is also validated against it and the whole batch is rejected on the first non-conforming message. The full limit table is in Limits & rules.
A batch publish that prints its server-assigned ids in order:
from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient() # honours PUBSUB_EMULATOR_HOST
topic_path = publisher.topic_path("my-project", "events")
futures = [publisher.publish(topic_path, f"event-{i}".encode()) for i in range(5)]
for fut in futures: # ids returned in request order
print(fut.result())Ordering keys
Set a per-message ordering_key and enable ordering on the subscription
(enable_message_ordering). Messages sharing an ordering_key are then delivered in publish
order, with at most one in flight per key — the head of a key blocks until it is acked or
redelivered, and redelivery is in order. A round-robin cursor spreads delivery fairly across
contended keys; keyless messages are delivered unordered.
Ordering is opt-in on the subscriber side. Publishing with an ordering_key is necessary but
not sufficient — the subscription must set enable_message_ordering for ordered delivery. The
ordering key travels as the reserved tag _pubsub_ordering_key. See
Ordered delivery.
Message attributes
A PubsubMessage's attributes map (string → string) round-trips as KubeMQ message tags. On
top of the user attributes the connector carries three reserved tags across the wire:
_pubsub_message_id— the server-assigned id;_pubsub_publish_time— the publish timestamp;_pubsub_ordering_key— the ordering key (if any).
Reserved tags are visible to native consumers, hidden from Pub/Sub clients. A native KubeMQ
consumer of gcp.{topic} sees all three reserved tags plus the user attributes; when the connector
delivers the message back to a Pub/Sub client, the reserved tags are stripped from
attributes. See Channel mapping.
Attribute constraints (enforced in the atomic validation above): ≤ 100 attributes; key ≤ 256 B with
no goog prefix; value ≤ 1024 B.
Error quick reference
| Trigger | Result |
|---|---|
| Batch > 1000 messages, or any message > 10 MiB / > 100 attributes / oversize key/value | INVALID_ARGUMENT — whole batch rejected |
data and attributes both empty | INVALID_ARGUMENT |
Topic id starts with sub., bad charset, or goog prefix | INVALID_ARGUMENT on CreateTopic |
Ingestion config on CreateTopic | INVALID_ARGUMENT |
| Message fails the topic's schema | INVALID_ARGUMENT — whole batch rejected on first non-conforming message |
Related
Subscribing
Pull vs StreamingPull, the ack-deadline lease, flow control, and exactly-once delivery.
Message filtering
The CEL-subset attribute filter applied at publish fan-out, and the fan-out pattern it enables.
Limits & rules
The full numeric-limit and validation-rule table — batch size, message size, attributes, and more.
Was this page helpful?
Publish & Subscribe
Create a topic and a subscription, publish a message, then pull and acknowledge it over KubeMQ — the core Pub/Sub round-trip on gcp.{topic} channels.
Push Delivery
Push subscriptions over KubeMQ — the per-subscription delivery worker, wrapped JSON envelope vs no_wrapper, 2xx-acks, retry with backoff, and dead-letter.