Cloud Pub/Sub options#

Every option the Pub/Sub sink and source take, and the ones the shared dead-letter queue takes. What each one is for is on the Cloud Pub/Sub connector page, linked from each section; the three forms of the Default column are explained here.

The WITH options of the pubsub table connector are a separate surface, documented on the Pub/Sub SQL connector page.

PubSubSink.builder()#

OptionDefaultWhat it does
topicrequired, unless destinationResolver is setPublishes every record to one fixed topic
destinationResolver—Resolves the topic per record
serializerrequiredConverts each record into a PubsubMessage, or into null to skip it. payload(...) wraps a payload-only schema; withAttributes(...) and withOrderingKey(...) layer onto any of them
createDispositionCREATE_IF_NEEDEDWhether a missing topic is created or fails the job
topicCreateOptionsPub/Sub’s own defaultsSettings for topics the sink creates. Rejected with CREATE_NEVER
publisherOptionsdefaultsPublisher and writer tuning
failedMessageHandlerFailureHandler.failJob()What happens to a message that terminally fails — fail, drop, or dead-letter. Under enableMessageOrdering(true), dropping a keyed message leaves a gap in that key’s stream
serviceAccountKeyFileunset ⇒ application-default credentialsReads a service-account JSON key on each TaskManager when the writer starts. Every eligible TaskManager must see the same path. Rejected beside emulatorEndpoint; see the deployment note
emulatorEndpoint—Points the sink at an emulator over a plaintext channel with no credentials. Never production. Given as host:port, and rejected at the setter if it is not

PubSubPublisherOptions#

Set through publisherOptions(...). The batching and retry knobs are handed to the SDK publisher and left unset by default, so defaults() is equivalent to passing no options at all; the in-flight caps and the recovery budget are the connector’s own. See Publisher options for why the SDK’s flow controller is deliberately not exposed, and Backpressure for how the caps are sized.

SDK batching.

OptionDefaultWhat it does
batchElementCountThresholdunset ⇒ SDK default (100)Messages batched into one publish request
batchRequestByteThresholdunset ⇒ SDK default (1000 B)Bytes batched into one publish request. Keep below maxInFlightBytes
batchDelayThresholdunset ⇒ SDK default (1 ms)How long a publisher waits for a batch to fill

SDK publish retries.

OptionDefaultWhat it does
retryTotalTimeoutunset ⇒ SDK default (600 s)Total budget for a publish including retries; 0 is gax’s own value for “bound retries by the attempt count instead”
retryInitialDelayunset ⇒ SDK default (100 ms)Delay before the first retry; 0 (gax’s own default) means none
retryDelayMultiplierunset ⇒ SDK default (×4)Factor the retry delay grows by
retryMaxDelayunset ⇒ SDK default (60 s)Cap on the delay between retries; 0 clamps every delay to none
retryInitialRpcTimeoutunset ⇒ SDK defaultTimeout of the first publish RPC attempt; 0 is gax’s own value for “let the call run indefinitely”
retryRpcTimeoutMultiplierunset ⇒ SDK defaultFactor the per-RPC timeout grows by
retryMaxRpcTimeoutunset ⇒ SDK defaultCap on a publish RPC attempt’s timeout; 0 lets every call run indefinitely
retryMaxAttemptsunset ⇒ SDK defaultCap on publish attempts

retryTotalTimeout and retryMaxAttempts are rejected beside enableMessageOrdering(true), rather than silently ignored: an ordering-enabled publisher retries without limit, so neither an attempt cap nor a total timeout can bound a publish there — for unkeyed messages too. The other six retry knobs are unaffected and combine with ordering freely. A program that toggles ordering must therefore set these two only on the branch that leaves it off, rather than once for both. The mechanism is on the Publisher lifecycle page, where it also explains why the shutdown budget exists.

Ordering, in-flight caps and the republish recovery, all the connector’s own.

OptionDefaultWhat it does
enableMessageOrderingfalseHonours ordering keys. Without it, a message carrying one is rejected with an error naming this option. With it, a dropping failedMessageHandler leaves a gap in the dropped message’s key, and retryTotalTimeout/retryMaxAttempts may not be set (see above)
maxInFlightMessages1000Caps the writer’s unacknowledged publishes. A write at the cap yields to the mailbox, asks the publishers to send what they are still batching, and is bounded by publishProgressTimeout
maxInFlightBytes64 MiBCaps their total serialized size. Long.MAX_VALUE bounds by count only
maxActivePublishers100Caps the publishers retained by one writer subtask. A new destination releases the least-recently-used clean publisher; if none is clean, the write drains and repairs all publishers before releasing one. The replacement opens only after bounded shutdown succeeds; an overrun fails the write rather than accumulating abandoned publisher resources
destinationIdleTimeout1 hReleases a clean publisher after its destination has been unused for strictly longer than this timeout at a successful non-terminal checkpoint flush. A later record recreates it
publishProgressTimeout600 sHow long the sink may wait with no publish completing before it fails the job. The budget restarts at every completion, so a topic that keeps answering never spends it however slow it is; one that has stopped answering spends it once. Covers the admission gate and drains for checkpoints, capacity eviction, failure repair, and per-message isolation. With enableMessageOrdering nothing inside the sink ends an outage but this. See What a running job can spend
recoveryInitialBackoff500 msFirst backoff of a republish — after creating a missing topic, or after resuming an ordering key
recoveryMaxBackoff10 sCap of that backoff, before ±25% jitter
recoveryMaxAttempts10Republish attempts per destination and incident. Bounds a repair making no progress, not the length of a rejected run (see Ordering and a dropping policy)
maxConsecutiveRejections100Fails the job once this many confirmed rejections arrive in a row with no successful publish between them — the guardrail on a dropping policy’s isolation cost. Any success resets the count; -1 removes the bound

Shutdown.

OptionDefaultWhat it does
shutdownTimeout30 sHow long one sink publisher release waits. Capacity eviction can spend it in write, idle eviction in a successful non-terminal flush, and final teardown in close; each release asks every selected publisher to stop before waiting, so it costs this once however many publishers it covers. For running eviction this is the maximum task-thread stall from one release, and an overrun fails the task before a replacement opens. Keep it under Flink’s task.cancellation.timeout (180 s by default) for final close. It bounds the sink’s own publishers — a sendToDeadLetterQueue(...) handler spends a second close budget of the same shape on top. See Publisher lifecycle

Metrics.

OptionDefaultWhat it does
perDestinationMetricsfalseRegisters per-topic recordsSend and sendErrors counters beside the writer’s totals. Off by default: Flink cannot unregister a metric, so with dynamic destinations every topic the job writes to keeps a row in the registry for the task’s lifetime. See Sink metrics

TopicCreateOptions#

Applied to topics the sink creates. Creation only — an existing topic keeps its own settings, and these are neither applied to it nor compared against it. One options object serves every topic the sink creates. See Topic creation settings.

OptionDefaultWhat it does
messageRetentionunset ⇒ no topic-level retentionKeeps messages on the topic itself, acknowledged or not — what makes a later subscription or a backwards seek able to reach them
kmsKeyNameunset ⇒ Google-managed encryptionEncrypts with a customer-managed Cloud KMS key
allowedPersistenceRegionsunset ⇒ whatever org policy allowsRestricts where messages may be persisted
enforceInTransitfalseAlso rejects publishes travelling outside those regions. Requires the regions

PubSubSource.builder()#

OptionDefaultWhat it does
subscription / subscriptionsrequired, at least oneThe subscriptions to consume. The two-argument subscription(...) also authorises creating it
deserializerrequiredConverts each PubsubMessage into zero or more non-null records. Emit synchronously during the call; do not retain the collector
orderingModeNONEPER_KEY preserves per-ordering-key order, at the cost of one subtask per subscription and one pull connection
subscriberOptionsdefaultsSubscriber and reader tuning
deserializationFailurePolicyFAILWhat happens to a message the schema cannot convert — fail, drop, or nack
startPositioncontinueFromSubscription()Where the source begins. Any other value issues a seek, once, at first start
serviceAccountKeyFileunset ⇒ application-default credentialsReads a service-account JSON key when the JobManager’s enumerator or a TaskManager’s reader starts. Every eligible process must see the same path. Rejected beside emulatorEndpoint; see the deployment note
emulatorEndpoint—Points the source at an emulator over a plaintext channel with no credentials. PUBSUB_EMULATOR_HOST is deliberately ignored. Given as host:port, and rejected at the setter if it is not

PubSubSubscriberOptions#

Set through subscriberOptions(...). The flow-control, connection-count and ack-extension knobs go to the SDK subscriber and are unset by default; the reader-wide and paused-split bounds and the last three are the source’s own. Google publishes no recommended flow-control values, so the SDK defaults stand — see Tuning for the one sizing rule that is specific to this source, that acknowledgement waits for a checkpoint.

OptionDefaultWhat it does
flowControlMaxOutstandingElementCountunset ⇒ SDK default (1000)Messages one subscriber holds outstanding before it stops pulling, for as long as it is extending their leases
flowControlMaxOutstandingRequestBytesunset ⇒ SDK default (100 MB)The same in bytes
subscriberBufferMaxMessages10000Hard aggregate cap on messages retained in all subscriber buffers of one source reader
subscriberBufferMaxBytes64 MiBHard aggregate cap on serialized bytes retained in all subscriber buffers of one source reader; whichever hard cap would be crossed first controls the response
pausedSplitBufferMaxMessagesunset ⇒ twice the effective flowControlMaxOutstandingElementCount (so 2000 by default)Messages a split paused by watermark alignment may buffer before its subscriber is stopped and reopened on resume
pausedSplitBufferMaxBytesunset ⇒ twice the effective flowControlMaxOutstandingRequestBytes (so 200 MB by default)The same in bytes; whichever bound is exceeded first stops the subscriber
parallelPullCountunset ⇒ SDK default (1)Streaming-pull connections per subscriber. Rejected under orderingMode(PER_KEY)
maxAckExtensionPeriodunset ⇒ SDK default (1 h)How long the client library keeps extending a message’s deadline. Must exceed the checkpoint interval comfortably; 0 is the client library’s own value for “disable auto deadline extension”
minDurationPerAckExtensionunset ⇒ SDK default (adaptive)Smallest extension requested at a time
maxDurationPerAckExtensionunset ⇒ SDK default (adaptive)Largest extension requested at a time
awaitAckConfirmationunset ⇒ acknowledgement is fire-and-forgetMakes each completed checkpoint wait for the server’s confirmation, failing the job on timeout
shutdownTimeout5 sHow long a reader’s close waits for its subscribers. Keep under source.reader.close.timeout
maxRecordsPerFetch1000How much one fetch drains from one split. Not a memory bound
firstCheckpointTimeout10 minHow long a reader holding unacknowledged messages waits for its first checkpoint before failing the job. Duration.ZERO disables the detector

SubscriptionCreateOptions#

Passing these is what authorises creating the subscription — there is no disposition, and a subscription added without them must already exist. They are per subscription because they carry the topic binding. Creation only, never an update. See Subscription auto-creation.

OptionDefaultWhat it does
topicrequiredThe topic to bind the subscription to
ackDeadlineunset ⇒ Pub/Sub default (10 s)How long a consumer has to acknowledge before redelivery
enableMessageOrderingunset ⇒ offRequired by orderingMode(PER_KEY), and fixed at creation
messageRetentionunset ⇒ Pub/Sub default (7 days)How long unacknowledged messages are retained
retainAckedMessagesunset ⇒ offKeeps acknowledged messages so a backwards seek can replay them
expirationTtlunset ⇒ Pub/Sub default (31 days)How long the subscription may sit inactive before deletion
neverExpireunset ⇒ the TTL above appliesCreates a subscription that never expires
deadLetterPolicyunset ⇒ no dead letteringForwards a message after N delivery attempts. Required by deserializationFailurePolicy(NACK)
filterunset ⇒ every message deliveredDelivers only matching messages, acknowledging the rest

enableExactlyOnceDelivery is deliberately absent: the source’s startup check rejects such a subscription, so offering it would only let you create one the source then refuses.

PubSubDeadLetterQueue.builder()#

Experimental (#211). The class is Pub/Sub’s, but one instance serves every connector in this repository — it is what FailureHandler.sendToDeadLetterQueue(...) takes on a BigQuery, Cloud Tasks or Bigtable sink too, which is why those pages send you here. What each option is for, and how to size the two budgets against a checkpoint interval, is under Dead-lettering to a Pub/Sub topic.

OptionDefaultWhat it does
topicrequiredPublishes every dead letter to one topic, which must already exist — this queue never creates one
serviceAccountKeyFileunset ⇒ application-default credentialsReads a service-account JSON key when each host sink writer opens the queue. Every eligible TaskManager must see the same path. Independent of the host connector’s credentials and rejected beside emulatorEndpoint; see the deployment note
maxInFlightMessages1000How many publishes may be in flight before an offer waits for them. WRITE_THROUGH (0) publishes each element synchronously, the narrowest loss window at one round trip per element; UNBOUNDED (-1) buffers until the flush
flushTimeout60 sHow long one wait for in-flight publishes may take — the wait in flush(), and the one an offer makes when the bound above is full. One deadline per wait rather than per publish, and there is no unbounded setting. Expiry throws, failing the checkpoint or the task
shutdownTimeout30 sHow long the queue’s own close waits for its publisher. Spent after the sink’s own shutdownTimeout, so keep the sum under Flink’s task.cancellation.timeout (180 s by default)
emulatorEndpoint—Points the queue at an emulator over a plaintext channel with no credentials. Never production. Given as host:port, and rejected at the setter if it is not