> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensor9.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SNS

> AWS SNS. Publish-subscribe messaging where one topic fans a message out to many subscribers: queues, Lambda functions, HTTP endpoints, email and SMS.

**On this page**

* [Coverage by target cloud](#coverage-by-target-cloud)
* [How the targets compare](#how-the-targets-compare)
  * [Max adaptation](#max-adaptation)
* [On Google Cloud](#on-google-cloud)
* [On Azure, OCI, and Private Kubernetes](#on-azure-oci-and-private-kubernetes)
  * [Via CloudNativePG](#via-cloudnativepg)
* [On Azure](#on-azure)
  * [Via Azure Service Bus](#via-azure-service-bus)
  * [Via PostgreSQL Flexible Server](#via-postgresql-flexible-server)

## Coverage by target cloud

| Target             | Available |
| ------------------ | --------- |
| Google Cloud       | ✓         |
| Azure              | ✓         |
| OCI                | ✓         |
| Private Kubernetes | ✓         |

## How the targets compare

Each row compares a capability of SNS with its adaptation on each target.
A dash means this row is not stated for that target.

### Max adaptation

| Capability                                         | SNS                                               | Google Cloud                                                                                                                              | Azure, OCI, and Private Kubernetes · CloudNativePG                                                                                        | Azure · Azure Service Bus                                                                                                                 | Azure · PostgreSQL Flexible Server                                                                                                        |
| -------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Delivery guarantee                                 | at-least-once                                     | at-least-once (native Pub/Sub delivery; a delivery worker forwards to each endpoint)                                                      | at-least-once (durable outbox; bounded retries, with terminal failures recorded)                                                          | at-least-once (native Service Bus delivery)                                                                                               | at-least-once (durable outbox; bounded retries, with terminal failures recorded)                                                          |
| Topic fan-out · one Publish → every subscription   | native                                            | native: a real Google Pub/Sub topic fans out to its subscriptions                                                                         | a durable outbox row per subscription, written in the publish transaction                                                                 | native: a Service Bus topic fans out to its subscriptions                                                                                 | a durable outbox row per subscription, written in the publish transaction                                                                 |
| Delivery protocols · subscription endpoints        | SQS / HTTP-S / SMS / email / Lambda / application | SQS, HTTP/S, SMS (an email / Lambda / application subscription is omitted with a deployment notice; the topic still fans out to the rest) | SQS, HTTP/S, SMS (an email / Lambda / application subscription is omitted with a deployment notice; the topic still fans out to the rest) | SQS, HTTP/S, SMS (an email / Lambda / application subscription is omitted with a deployment notice; the topic still fans out to the rest) | SQS, HTTP/S, SMS (an email / Lambda / application subscription is omitted with a deployment notice; the topic still fans out to the rest) |
| Message durability                                 | managed, durable                                  | native Pub/Sub durability (Google-operated)                                                                                               | durable before Publish returns (committed to Postgres); survives a restart                                                                | native Service Bus durability (Microsoft-operated)                                                                                        | durable before Publish returns, on a Microsoft-operated server (backup + HA)                                                              |
| Delivery retry · who re-delivers a failed endpoint | SNS-owned                                         | Google Cloud Pub/Sub (the cloud's own delivery retry)                                                                                     | Tensor9's delivery layer (durable, at-least-once retry)                                                                                   | Azure Service Bus (the broker's own delivery retry)                                                                                       | Tensor9's delivery layer (durable, at-least-once retry)                                                                                   |
| API coverage                                       | full                                              | partial                                                                                                                                   | high                                                                                                                                      | partial                                                                                                                                   | high                                                                                                                                      |

## On Google Cloud

| Operation                                                          | Area          | Support      | Depth        | Notes                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------ | ------------- | ------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SetTopicAttributes (policy / delivery policy)                      | Control plane | Out of scope | Full surface | topic resource policies grant access to other identities; this target does not translate them, and deployment rejects a declared policy                                                                                                                 |
| GetTopicAttributes                                                 | Discovery     | Supported    | Most usage   | returns the topic ARN and name; policy and delivery-policy attributes are not modeled                                                                                                                                                                   |
| ListTopics                                                         | Discovery     | Supported    | Most usage   | returns the declared topics                                                                                                                                                                                                                             |
| FIFO topics (ordering + content-based dedup)                       | Ordering      | Out of scope | Full surface | FIFO ordering and content-based deduplication are not offered (a FIFO topic is caught at deploy)                                                                                                                                                        |
| Publish                                                            | Publish       | Supported    | Common       | each Publish writes to a native Google Pub/Sub topic; fan-out is the cloud's own and a delivery worker forwards each message to the subscription's HTTP/SQS/SMS endpoint                                                                                |
| PublishBatch                                                       | Publish       | Supported    | Most usage   | publishes each batch entry separately and returns its result                                                                                                                                                                                            |
| ConfirmSubscription                                                | Subscriptions | Supported    | Most usage   | the HTTP/S confirmation handshake is honored so a confirmed subscription begins receiving                                                                                                                                                               |
| Email / Lambda / application subscriptions                         | Subscriptions | Partial      | Full surface | these delivery protocols are omitted with a deployment notice; the topic and its SQS/HTTP-S/SMS subscriptions still fan out                                                                                                                             |
| SetSubscriptionAttributes (filter policy / raw delivery / redrive) | Subscriptions | Out of scope | Full surface | message filtering, raw delivery, and subscription redrive (DLQ) are not offered: a declared filter, raw-delivery, or redrive policy is caught at deploy rather than being silently ignored; failed-endpoint retry is owned by the tier's delivery layer |
| Subscribe                                                          | Subscriptions | Supported    | Common       | connects SQS, HTTP/S or SMS subscriptions to their endpoints; an SQS subscription delivers directly to the corresponding queue                                                                                                                          |
| Unsubscribe                                                        | Subscriptions | Supported    | Common       | removes the subscription                                                                                                                                                                                                                                |
| CreateTopic                                                        | Topics        | Supported    | Common       | your aws\_sns\_topic compiles to a topic on the target; the topic name must be a literal known at build time (a computed or prefixed topic name is rejected rather than guessed at)                                                                     |
| DeleteTopic                                                        | Topics        | Supported    | Common       | removes the compiled topic                                                                                                                                                                                                                              |

#### From SNS Publish to subscriber

The adapter maps an SNS topic to a Google Cloud Pub/Sub topic. Publish sends the message to Pub/Sub, which places it on the topic's subscriptions. SNS subscriber destinations are not Pub/Sub consumers by themselves: a Tensor9 delivery worker pulls each subscription and forwards the notification using the destination's HTTP/S, SQS or SMS transport.

The worker initiates its connection to Pub/Sub from the customer environment. This design does not require Pub/Sub to open an inbound connection to the private adapter. The destination still needs to be reachable from the delivery worker, and external transports need their provider setup.

#### Subscription identity and retry ownership

Topic and subscription ARNs are encoded into valid Pub/Sub resource identifiers. The durable identity excludes the advertised region. Subscription metadata records the SNS protocol and endpoint so the delivery worker can reconstruct the destination after an adapter restart.

The worker acknowledges a Pub/Sub message after delivery succeeds. A failed delivery is negatively acknowledged and Pub/Sub controls redelivery through its subscription settings. If delivery succeeds but acknowledgment is lost, the message can be delivered again. Consumers must tolerate duplicates. Review retry and dead-letter settings separately from the SNS API features this mapping supports.

#### Migration and performance scope

Provision the topic and required subscriptions before changing publishers. Existing AWS backlog does not move to Pub/Sub. Test destination access and consumer behavior, including any SNS signature or subscription-confirmation checks; message-body compatibility alone does not satisfy a signature verifier.

Google operates the broker. Tensor9 operates the service adapter and delivery worker. Monitor broker backlog and destination delivery separately: Publish latency measures acceptance by the broker, not delivery to every subscriber. The recorded Publish benchmark does not measure the complete notification path.

## On Azure, OCI, and Private Kubernetes

### Via CloudNativePG

| Operation                                                          | Area          | Support      | Depth        | Notes                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------ | ------------- | ------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SetTopicAttributes (policy / delivery policy)                      | Control plane | Out of scope | Full surface | topic resource policies grant access to other identities; this target does not translate them, and deployment rejects a declared policy                                                                                                                 |
| GetTopicAttributes                                                 | Discovery     | Supported    | Most usage   | returns the topic ARN and name; policy and delivery-policy attributes are not modeled                                                                                                                                                                   |
| ListTopics                                                         | Discovery     | Supported    | Most usage   | returns the declared topics                                                                                                                                                                                                                             |
| FIFO topics (ordering + content-based dedup)                       | Ordering      | Out of scope | Full surface | FIFO ordering and content-based deduplication are not offered (a FIFO topic is caught at deploy)                                                                                                                                                        |
| Publish                                                            | Publish       | Supported    | Common       | each Publish inserts the message and one delivery row per subscription in a single transaction, durable before the call returns; the adapter then delivers each row and owns the retry                                                                  |
| PublishBatch                                                       | Publish       | Supported    | Most usage   | publishes each batch entry separately and returns its result                                                                                                                                                                                            |
| ConfirmSubscription                                                | Subscriptions | Supported    | Most usage   | the HTTP/S confirmation handshake is honored so a confirmed subscription begins receiving                                                                                                                                                               |
| Email / Lambda / application subscriptions                         | Subscriptions | Partial      | Full surface | these delivery protocols are omitted with a deployment notice; the topic and its SQS/HTTP-S/SMS subscriptions still fan out                                                                                                                             |
| SetSubscriptionAttributes (filter policy / raw delivery / redrive) | Subscriptions | Out of scope | Full surface | message filtering, raw delivery, and subscription redrive (DLQ) are not offered: a declared filter, raw-delivery, or redrive policy is caught at deploy rather than being silently ignored; failed-endpoint retry is owned by the tier's delivery layer |
| Subscribe                                                          | Subscriptions | Supported    | Common       | connects SQS, HTTP/S or SMS subscriptions to their endpoints; an SQS subscription delivers directly to the corresponding queue                                                                                                                          |
| Unsubscribe                                                        | Subscriptions | Supported    | Common       | removes the subscription                                                                                                                                                                                                                                |
| CreateTopic                                                        | Topics        | Supported    | Common       | your aws\_sns\_topic compiles to a topic on the target; the topic name must be a literal known at build time (a computed or prefixed topic name is rejected rather than guessed at)                                                                     |
| DeleteTopic                                                        | Topics        | Supported    | Common       | removes the compiled topic                                                                                                                                                                                                                              |

#### Publishing and subscriber delivery

The application sends its SNS requests to the Tensor9 adapter. PostgreSQL stores topics, subscriptions, messages and pending deliveries. For each Publish, the adapter commits the message and one pending delivery for each current subscription in the same database transaction. A successful Publish means that work is stored; it does not mean every subscriber has received it.

Delivery workers claim pending work and send the notification to the configured subscriber. HTTP/S, SQS and SMS require different delivery transports. An SQS destination uses that queue's selected adapter; an HTTP destination must be reachable from the customer environment. Configure the required external delivery provider for SMS.

#### Retries, duplicates and terminal failures

A worker temporarily leases a delivery record. Other workers skip records already claimed, allowing several workers to process different deliveries. If a worker stops, its unfinished lease eventually expires and another worker can retry the record.

A subscriber can accept a notification just before the worker fails to record success. Retrying that delivery produces a duplicate. Consumers should recognize repeated MessageId values and make side effects safe to repeat; the database transaction does not include the subscriber's work.

Successful deliveries are recorded as delivered. Temporary failures are rescheduled with increasing delay, subject to an attempt limit. Permanent failures, exhausted attempts and deliveries whose subscription was removed become terminal records. Monitor those failures and the age of pending work; accepting a Publish is not a guarantee that an unreachable subscriber will receive it.

#### Identity, integration and operation

Stored topic identity uses the account and topic name independently of the advertised AWS region. The API reconstructs the advertised ARN. Changing presentation region therefore need not create a new topic or abandon its pending deliveries.

Notification-body compatibility and subscriber verification are separate requirements. Check any consumer that validates SNS signatures, certificate URLs or subscription confirmation; a JSON document with familiar fields is not sufficient to satisfy those checks.

The platform team operates the PostgreSQL service and its backups in a self-managed deployment; Tensor9 operates the adapter and delivery workers. Provision subscriptions and test each delivery path before switching producers. Existing AWS notifications are not copied into this outbox. Review the profile's filtering, FIFO, raw-delivery and redrive limitations for the workload.

## On Azure

### Via Azure Service Bus

| Operation                                                              | Area          | Support      | Depth        | Notes                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------------- | ------------- | ------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SetSubscriptionAttributes (filter / raw) / SetTopicAttributes (policy) | Control plane | Out of scope | Full surface | message filtering, raw delivery, and topic resource policies are not offered (they are caught at deploy); topic access policies require role-based access control (RBAC) and Shared Access Signatures (SAS), which this deployment does not configure |
| GetTopicAttributes                                                     | Discovery     | Supported    | Most usage   | returns the topic name                                                                                                                                                                                                                                |
| ListTopics                                                             | Discovery     | Supported    | Most usage   | returns the declared topics                                                                                                                                                                                                                           |
| FIFO topics (ordering + dedup)                                         | Ordering      | Out of scope | Full surface | FIFO topics need Service Bus sessions for ordered delivery; not offered (a FIFO topic is caught at deploy)                                                                                                                                            |
| Publish                                                                | Publish       | Supported    | Common       | the adapter publishes the SNS message in an envelope to a Service Bus topic, which sends a copy to every subscription                                                                                                                                 |
| PublishBatch                                                           | Publish       | Supported    | Most usage   | publishes each batch entry separately and returns its result                                                                                                                                                                                          |
| ConfirmSubscription                                                    | Subscriptions | Supported    | Most usage   | the HTTP/S confirmation handshake is honored so a confirmed subscription begins receiving                                                                                                                                                             |
| Email / Lambda / application subscriptions                             | Subscriptions | Partial      | Full surface | these delivery protocols are omitted with a deployment notice; the topic still fans out to its SQS/HTTP-S/SMS subscriptions                                                                                                                           |
| SetSubscriptionAttributes (redrive policy)                             | Subscriptions | Out of scope | Full surface | a subscription redrive (DLQ) policy is not offered: a declared redrive policy is caught at deploy rather than being silently ignored; failed-endpoint retry is Azure Service Bus's own                                                                |
| Subscribe                                                              | Subscriptions | Supported    | Common       | each subscription maps to a Service Bus subscription on the topic, and the adapter delivers to its endpoint over the SQS, HTTP/S, or SMS protocol                                                                                                     |
| Unsubscribe                                                            | Subscriptions | Supported    | Common       | removes the Service Bus subscription                                                                                                                                                                                                                  |
| CreateTopic                                                            | Topics        | Supported    | Common       | your aws\_sns\_topic compiles to an azurerm\_servicebus\_topic on a shared Standard namespace; the topic name must be a literal known at build time                                                                                                   |
| DeleteTopic                                                            | Topics        | Supported    | Common       | removes the compiled Service Bus topic                                                                                                                                                                                                                |

#### How it works

An Azure Service Bus topic sends each published message to every subscription. The Tensor9 adapter accepts your application's SNS API calls, publishes the message to Service Bus, then delivers each subscription's notification to its endpoint in the SNS format.

Service Bus manages message storage and retry. The adapter handles delivery over HTTP/S, SQS and SMS; Service Bus does not send those notifications itself. Both Azure targets use runtime adaptation for the SNS API and notification delivery. Email, Lambda and application subscriptions are dropped with a deployment notice, as listed in the support table.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE2IiB2aWV3Qm94PSIwIDAgODM2IDIxNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyBhIHB1Ymxpc2hlciBjYWxscyBTTlMgUHVibGlzaCBhbmQgU05TIGZhbnMgb3V0IGFuZCBkZWxpdmVycyB0byBlYWNoIHN1YnNjcmlwdGlvbiBvdmVyIEhUVFBTLCBlbWFpbCwgU01TIG9yIFNRUy4gQWZ0ZXI6IG9uIEF6dXJlIHRoZSBwdWJsaXNoZXIncyBTTlMgY2FsbCBpcyBzZXJ2ZWQgYnkgYSBUZW5zb3I5IGFkYXB0ZXIgb3ZlciBsb29wYmFjaywgYSBTZXJ2aWNlIEJ1cyB0b3BpYyBwZXJmb3JtcyB0aGUgZmFuLW91dCBuYXRpdmVseSwgYW5kIHRoZSBhZGFwdGVyIHJlLWVtaXRzIGVhY2ggc3Vic2NyaXB0aW9uJ3MgZGVsaXZlcnkgaW4gU05TJ3Mgc2hhcGUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InNiMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDQiIHdpZHRoPSIzODQiIGhlaWdodD0iMTU0IiByeD0iMTQiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIvPgo8dGV4dCB4PSIzMCIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiM5NGEzYjgiPk9OIEFXUyBUT0RBWTwvdGV4dD4KPHJlY3QgeD0iMzAiIHk9IjkyIiB3aWR0aD0iMTA0IiBoZWlnaHQ9IjYyIiByeD0iMTEiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2UyZThmMCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iODIiIHk9IjEyMCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5QdWJsaXNoZXI8L3RleHQ+Cjx0ZXh0IHg9IjgyIiB5PSIxMzYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5TTlMgU0RLPC90ZXh0Pgo8bGluZSB4MT0iMTM0IiB5MT0iMTIzIiB4Mj0iMTk2IiB5Mj0iMTIzIiBzdHJva2U9IiM5NGEzYjgiIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNzYjEpIi8+Cjx0ZXh0IHg9IjE2NSIgeT0iMTE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjhweCI+UHVibGlzaDwvdGV4dD4KPHJlY3QgeD0iMjAwIiB5PSI4NCIgd2lkdGg9IjE4NiIgaGVpZ2h0PSI3OCIgcng9IjExIiBmaWxsPSIjZmZmIiBzdHJva2U9IiNlMmU4ZjAiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9IjI5MyIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPkFtYXpvbiBTTlM8L3RleHQ+Cjx0ZXh0IHg9IjI5MyIgeT0iMTI4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZmFuLW91dCBhbmQgZGVsaXZlcnk8L3RleHQ+Cjx0ZXh0IHg9IjI5MyIgeT0iMTQ0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNTk2Njk7IGZpbGw6I2I0NTMwOSI+SFRUUFMgwrcgZW1haWwgwrcgU01TIMK3IFNRUzwvdGV4dD4KPGxpbmUgeDE9IjQxOCIgeTE9IjQwIiB4Mj0iNDE4IiB5Mj0iMTg4IiBzdHJva2U9IiNlMmU4ZjAiIHN0cm9rZS13aWR0aD0iMS40Ii8+CjxyZWN0IHg9IjQzNiIgeT0iNDQiIHdpZHRoPSIzODQiIGhlaWdodD0iMTU0IiByeD0iMTQiIGZpbGw9IiNmOGZhZmMiIHN0cm9rZT0iI2NiZDVlMSIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIvPgo8dGV4dCB4PSI0NTAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBBWlVSRTwvdGV4dD4KPHJlY3QgeD0iNDUwIiB5PSI5MiIgd2lkdGg9Ijk2IiBoZWlnaHQ9IjYyIiByeD0iMTEiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2UyZThmMCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iNDk4IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+UHVibGlzaGVyPC90ZXh0Pgo8dGV4dCB4PSI0OTgiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTQ2IiB5MT0iMTIzIiB4Mj0iNTkyIiB5Mj0iMTIzIiBzdHJva2U9IiMwNDc4NTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNzYjEpIi8+CjxyZWN0IHg9IjU5NiIgeT0iODgiIHdpZHRoPSI5NiIgaGVpZ2h0PSI3MCIgcng9IjExIiBmaWxsPSIjZmZmIiBzdHJva2U9IiNlMmU4ZjAiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9IjY0NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iNjQ0IiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5zZXJ2ZXMgU05TPC90ZXh0Pgo8dGV4dCB4PSI2NDQiIHk9IjE0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDU5NjY5OyBmaWxsOiNiNDUzMDkiPnNlcnZlcyBkZWxpdmVyeTwvdGV4dD4KPGxpbmUgeDE9IjY5MiIgeTE9IjEyMyIgeDI9IjcyNiIgeTI9IjEyMyIgc3Ryb2tlPSIjMDQ3ODU3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2IxKSIvPgo8cmVjdCB4PSI3MzAiIHk9Ijg4IiB3aWR0aD0iNzYiIGhlaWdodD0iNzAiIHJ4PSIxMSIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZTJlOGYwIiBzdHJva2Utd2lkdGg9IjEuNSIvPgo8dGV4dCB4PSI3NjgiIHk9IjEwNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Ub3BpYzwvdGV4dD4KPHRleHQgeD0iNzY4IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5uYXRpdmU8L3RleHQ+Cjx0ZXh0IHg9Ijc2OCIgeT0iMTM2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZmFuLW91dDwvdGV4dD4KPHRleHQgeD0iNzY4IiB5PSIxNTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2MDAgMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzA1OTY2OTsgZmlsbDojMDQ3ODU3Ij48L3RleHQ+Cjwvc3ZnPg==" alt="Before: on AWS a publisher calls SNS Publish and SNS fans out and delivers to each subscription over HTTPS, email, SMS or SQS. After: on Azure the publisher's SNS call is served by a Tensor9 adapter over loopback, a Service Bus topic performs the fan-out natively, and the adapter re-emits each subscription's delivery in SNS's shape." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjE2IiB2aWV3Qm94PSIwIDAgODM2IDIxNiIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJCZWZvcmU6IG9uIEFXUyBhIHB1Ymxpc2hlciBjYWxscyBTTlMgUHVibGlzaCBhbmQgU05TIGZhbnMgb3V0IGFuZCBkZWxpdmVycyB0byBlYWNoIHN1YnNjcmlwdGlvbiBvdmVyIEhUVFBTLCBlbWFpbCwgU01TIG9yIFNRUy4gQWZ0ZXI6IG9uIEF6dXJlIHRoZSBwdWJsaXNoZXIncyBTTlMgY2FsbCBpcyBzZXJ2ZWQgYnkgYSBUZW5zb3I5IGFkYXB0ZXIgb3ZlciBsb29wYmFjaywgYSBTZXJ2aWNlIEJ1cyB0b3BpYyBwZXJmb3JtcyB0aGUgZmFuLW91dCBuYXRpdmVseSwgYW5kIHRoZSBhZGFwdGVyIHJlLWVtaXRzIGVhY2ggc3Vic2NyaXB0aW9uJ3MgZGVsaXZlcnkgaW4gU05TJ3Mgc2hhcGUuIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9InNiMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBmaWxsPSIjOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDQiIHdpZHRoPSIzODQiIGhlaWdodD0iMTU0IiByeD0iMTQiIGZpbGw9IiMxYTI2MzEiIHN0cm9rZT0iIzNkNGY2NiIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIvPgo8dGV4dCB4PSIzMCIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiAjOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI5MiIgd2lkdGg9IjEwNCIgaGVpZ2h0PSI2MiIgcng9IjExIiBmaWxsPSIjMjYyNjI2IiBzdHJva2U9IiMzZDRlNjYiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9IjgyIiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZWQ4OyBmb250LXNpemU6MTJweCI+UHVibGlzaGVyPC90ZXh0Pgo8dGV4dCB4PSI4MiIgeT0iMTM2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2M5Y2ZkOCI+U05TIFNESzwvdGV4dD4KPGxpbmUgeDE9IjEzNCIgeTE9IjEyMyIgeDI9IjE5NiIgeTI9IjEyMyIgc3Ryb2tlPSIjNDE0ZTYyIiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjc2IxKSIvPgo8dGV4dCB4PSIxNjUiIHk9IjExNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICNjOWNmZDg7IGZvbnQtc2l6ZTo4cHgiPlB1Ymxpc2g8L3RleHQ+CjxyZWN0IHg9IjIwMCIgeT0iODQiIHdpZHRoPSIxODYiIGhlaWdodD0iNzgiIHJ4PSIxMSIgZmlsbD0iIzI2MjYyNiIgc3Ryb2tlPSIjM2Q0ZTY2IiBzdHJva2Utd2lkdGg9IjEuNSIvPgo8dGV4dCB4PSIyOTMiIHk9IjExMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNlZDg7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gU05TPC90ZXh0Pgo8dGV4dCB4PSIyOTMiIHk9IjEyOCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPmZhbi1vdXQgYW5kIGRlbGl2ZXJ5PC90ZXh0Pgo8dGV4dCB4PSIyOTMiIHk9IjE0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTBkZWM2OyBmaWxsOiAjZGViMjkwIj5IVFRQUyDCtyBlbWFpbCDCtyBTTVMgwrcgU1FTPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxODgiIHN0cm9rZT0iIzNkNGU2NiIgc3Ryb2tlLXdpZHRoPSIxLjQiLz4KPHJlY3QgeD0iNDM2IiB5PSI0NCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxNTQiIHJ4PSIxNCIgZmlsbD0iIzFhMjYzMSIgc3Ryb2tlPSIjM2Q0ZjY2IiBzdHJva2Utd2lkdGg9IjEuNCIgc3Ryb2tlLWRhc2hhcnJheT0iNSA1Ii8+Cjx0ZXh0IHg9IjQ1MCIgeT0iNjIiIHN0eWxlPSJmb250OiA3MDAgMTBweCBJbnRlciwgc2Fucy1zZXJpZjsgbGV0dGVyLXNwYWNpbmc6IDEuM3B4OyBmaWxsOiAjOTRhM2I4OyBmaWxsOiAjOTBkZWM4Ij5PTiBBWlVSRTwvdGV4dD4KPHJlY3QgeD0iNDUwIiB5PSI5MiIgd2lkdGg9Ijk2IiBoZWlnaHQ9IjYyIiByeD0iMTEiIGZpbGw9IiMyNjI2MjYiIHN0cm9rZT0iIzNkNGU2NiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iNDk4IiB5PSIxMjAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZWQ4OyBmb250LXNpemU6MTJweCI+UHVibGlzaGVyPC90ZXh0Pgo8dGV4dCB4PSI0OTgiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPnNhbWUgU0RLPC90ZXh0Pgo8bGluZSB4MT0iNTQ2IiB5MT0iMTIzIiB4Mj0iNTkyIiB5Mj0iMTIzIiBzdHJva2U9IiMwNDc4NTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNzYjEpIi8+CjxyZWN0IHg9IjU5NiIgeT0iODgiIHdpZHRoPSI5NiIgaGVpZ2h0PSI3MCIgcng9IjExIiBmaWxsPSIjMjYyNjI2IiBzdHJva2U9IiMzZDRlNjYiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9IjY0NCIgeT0iMTEyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2M5Y2VkODsgZm9udC1zaXplOjEycHgiPlRlbnNvcjkgYWRhcHRlcjwvdGV4dD4KPHRleHQgeD0iNjQ0IiB5PSIxMjgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZmQ4Ij5zZXJ2ZXMgU05TPC90ZXh0Pgo8dGV4dCB4PSI2NDQiIHk9IjE0NCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTBkZWM2OyBmaWxsOiAjZGViMjkwIj5zZXJ2ZXMgZGVsaXZlcnk8L3RleHQ+CjxsaW5lIHgxPSI2OTIiIHkxPSIxMjMiIHgyPSI3MjYiIHkyPSIxMjMiIHN0cm9rZT0iIzA0Nzg1NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI3NiMSkiLz4KPHJlY3QgeD0iNzMwIiB5PSI4OCIgd2lkdGg9Ijc2IiBoZWlnaHQ9IjcwIiByeD0iMTEiIGZpbGw9IiMyNjI2MjYiIHN0cm9rZT0iIzNkNGU2NiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iNzY4IiB5PSIxMDQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZWQ4OyBmb250LXNpemU6MTJweCI+VG9waWM8L3RleHQ+Cjx0ZXh0IHg9Ijc2OCIgeT0iMTIwIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2M5Y2ZkOCI+bmF0aXZlPC90ZXh0Pgo8dGV4dCB4PSI3NjgiIHk9IjEzNiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPmZhbi1vdXQ8L3RleHQ+Cjx0ZXh0IHg9Ijc2OCIgeT0iMTUyIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5MGRlYzY7IGZpbGw6ICM5MGRlYzgiPjwvdGV4dD4KPC9zdmc+" alt="Before: on AWS a publisher calls SNS Publish and SNS fans out and delivers to each subscription over HTTPS, email, SMS or SQS. After: on Azure the publisher's SNS call is served by a Tensor9 adapter over loopback, a Service Bus topic performs the fan-out natively, and the adapter re-emits each subscription's delivery in SNS's shape." />
</div>

#### One namespace, shared with your queues

The generated Terraform creates a **Standard Service Bus namespace** and one topic per SNS topic. Standard is required because Basic does not support topics. If your stack also has SQS queues, they share the same namespace with the topics, regardless of which service is compiled first.

Plan capacity and monitor quotas for that shared namespace. The generated Terraform contains no Service Bus connection string; the adapter obtains credentials at runtime, keeping them out of Terraform plans and state.

#### Declarations that cannot compile

Two declarations stop compilation:

* **Terraform subscriptions.** An `aws_sns_topic_subscription` is rejected because this target does not translate the declared endpoint and topic reference into the delivery configuration the adapter needs. Topics without Terraform subscriptions compile; applications can register subscriptions at runtime.
* **FIFO topics.** Service Bus sessions would be needed to preserve their ordering, and this adapter does not use sessions. A topic with `fifo_topic = true` is marked incompatible.

#### Limitations

△ Service Bus limitations

* **Delivery protocols are served by the adapter, not by Azure.** HTTP/S, SQS and SMS notifications are sent by the Tensor9 adapter. Service Bus manages message storage and retry; it does not deliver to these endpoints itself.
* **Existing-topic lookups are rejected.** A `data.aws_sns_topic` cannot compile: there is no customer-side SNS topic to read on Azure. Stacks that look up a topic they did not create need that reference resolved another way.
* **The namespace is shared, so its limits are shared.** Queues and topics from the whole stack live in one namespace. Namespace-level quotas and throughput are therefore a shared resource across everything messaging in the appliance, rather than isolated per topic the way separate SNS topics are.

#### Other considerations

* **Your publisher does not change.** The application keeps its SNS SDK and its Publish calls; the adapter serves that API inside the customer environment. Review your topic and subscription declarations before migrating.
* **Plan publisher cutover and subscription confirmation.** Create the namespace, topics and runtime subscriptions before switching publishers. Complete subscription confirmation and let pending AWS deliveries finish; those deliveries are not copied to Service Bus.
* **Size the shared namespace.** If your stack has queues as well as topics, both land in the same namespace. Size and monitor it as a single shared resource, and remember that its tier is what makes topics available at all.

### Via PostgreSQL Flexible Server

| Operation                                                          | Area          | Support      | Depth        | Notes                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------ | ------------- | ------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SetTopicAttributes (policy / delivery policy)                      | Control plane | Out of scope | Full surface | topic resource policies grant access to other identities; this target does not translate them, and deployment rejects a declared policy                                                                                                                 |
| GetTopicAttributes                                                 | Discovery     | Supported    | Most usage   | returns the topic ARN and name; policy and delivery-policy attributes are not modeled                                                                                                                                                                   |
| ListTopics                                                         | Discovery     | Supported    | Most usage   | returns the declared topics                                                                                                                                                                                                                             |
| FIFO topics (ordering + content-based dedup)                       | Ordering      | Out of scope | Full surface | FIFO ordering and content-based deduplication are not offered (a FIFO topic is caught at deploy)                                                                                                                                                        |
| Publish                                                            | Publish       | Supported    | Common       | each Publish inserts the message and one delivery row per subscription in a single transaction, durable before the call returns; the adapter then delivers each row and owns the retry                                                                  |
| PublishBatch                                                       | Publish       | Supported    | Most usage   | publishes each batch entry separately and returns its result                                                                                                                                                                                            |
| ConfirmSubscription                                                | Subscriptions | Supported    | Most usage   | the HTTP/S confirmation handshake is honored so a confirmed subscription begins receiving                                                                                                                                                               |
| Email / Lambda / application subscriptions                         | Subscriptions | Partial      | Full surface | these delivery protocols are omitted with a deployment notice; the topic and its SQS/HTTP-S/SMS subscriptions still fan out                                                                                                                             |
| SetSubscriptionAttributes (filter policy / raw delivery / redrive) | Subscriptions | Out of scope | Full surface | message filtering, raw delivery, and subscription redrive (DLQ) are not offered: a declared filter, raw-delivery, or redrive policy is caught at deploy rather than being silently ignored; failed-endpoint retry is owned by the tier's delivery layer |
| Subscribe                                                          | Subscriptions | Supported    | Common       | connects SQS, HTTP/S or SMS subscriptions to their endpoints; an SQS subscription delivers directly to the corresponding queue                                                                                                                          |
| Unsubscribe                                                        | Subscriptions | Supported    | Common       | removes the subscription                                                                                                                                                                                                                                |
| CreateTopic                                                        | Topics        | Supported    | Common       | your aws\_sns\_topic compiles to a topic on the target; the topic name must be a literal known at build time (a computed or prefixed topic name is rejected rather than guessed at)                                                                     |
| DeleteTopic                                                        | Topics        | Supported    | Common       | removes the compiled topic                                                                                                                                                                                                                              |

#### How it works

The adapter accepts your application's SNS `Publish` calls and stores each message with one delivery row per subscription in Azure Database for PostgreSQL Flexible Server. These rows form a **durable outbox**: a record of notifications still to deliver. A delivery loop reads the outbox and sends each notification. Temporary failures retry with increasing delay up to an attempt limit; permanent failures and exhausted attempts are recorded as terminal failures.

The message and its delivery rows commit in one database transaction before `Publish` returns, so a restart does not discard pending notifications. Microsoft manages the database's backups and high availability. The adapter authenticates through Microsoft Entra using the appliance's workload identity, with no stored password. This target is preferred over in-cluster CloudNativePG on Azure because Microsoft operates the database.

<div className="t9-diagram-scroll" role="region" aria-label="Scrollable diagram" tabIndex={0}>
  <img className="t9-diagram-light" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBenVyZSB0aGUgcHVibGlzaGVyJ3MgU05TIFB1Ymxpc2ggY2FsbCBpcyBzZXJ2ZWQgYnkgYSBUZW5zb3I5IGFkYXB0ZXIgd2hpY2ggd3JpdGVzIHRoZSBmYW4tb3V0IGludG8gYSBkdXJhYmxlIG91dGJveCBvbiBhIE1pY3Jvc29mdC1vcGVyYXRlZCBGbGV4aWJsZSBQb3N0Z3JlcyBzZXJ2ZXIsIGFuZCBhIGRlbGl2ZXJ5IGxvb3AgZHJhaW5zIHRoZSBvdXRib3ggdG8gZWFjaCBzdWJzY3JpcHRpb24gd2l0aCBhdC1sZWFzdC1vbmNlIHJldHJ5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6IzMzNDE1NX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJmcDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iIzk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ0IiB3aWR0aD0iODA0IiBoZWlnaHQ9IjE1MCIgcng9IjE0IiBmaWxsPSIjZjhmYWZjIiBzdHJva2U9IiNjYmQ1ZTEiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiLz4KPHRleHQgeD0iMzAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBBWlVSRTwvdGV4dD4KPHJlY3QgeD0iMzQiIHk9IjkyIiB3aWR0aD0iMTA0IiBoZWlnaHQ9IjY0IiByeD0iMTEiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2UyZThmMCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iODYiIHk9IjEyMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5QdWJsaXNoZXI8L3RleHQ+Cjx0ZXh0IHg9Ijg2IiB5PSIxMzciIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5TTlMgU0RLPC90ZXh0Pgo8bGluZSB4MT0iMTM4IiB5MT0iMTIzIiB4Mj0iMTg0IiB5Mj0iMTIzIiBzdHJva2U9IiMwNDc4NTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmcDEpIi8+CjxyZWN0IHg9IjE4OCIgeT0iODgiIHdpZHRoPSIxMTYiIGhlaWdodD0iNzIiIHJ4PSIxMSIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZTJlOGYwIiBzdHJva2Utd2lkdGg9IjEuNSIvPgo8dGV4dCB4PSIyNDYiIHk9IjEyMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5UZW5zb3I5IGFkYXB0ZXI8L3RleHQ+Cjx0ZXh0IHg9IjI0NiIgeT0iMTM3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+c2VydmVzIFNOUzwvdGV4dD4KPGxpbmUgeDE9IjMwNCIgeTE9IjEyMyIgeDI9IjM1MCIgeTI9IjEyMyIgc3Ryb2tlPSIjMDQ3ODU3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZnAxKSIvPgo8dGV4dCB4PSIzMjciIHk9IjExNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4cHgiPnRyYW5zYWN0aW9uPC90ZXh0Pgo8cmVjdCB4PSIzNTQiIHk9Ijg0IiB3aWR0aD0iMTc4IiBoZWlnaHQ9IjgwIiByeD0iMTEiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2UyZThmMCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iNDQzIiB5PSIxMTMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+RmxleGlibGUgUG9zdGdyZXM8L3RleHQ+Cjx0ZXh0IHg9IjQ0MyIgeT0iMTI5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+ZHVyYWJsZSBvdXRib3g8L3RleHQ+Cjx0ZXh0IHg9IjQ0MyIgeT0iMTQ1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjAwIDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwNTk2Njk7IGZpbGw6IzA0Nzg1NyI+bWFuYWdlZCBiYWNrdXAgKyBIQTwvdGV4dD4KPGxpbmUgeDE9IjUzMiIgeTE9IjEyMyIgeDI9IjU4MCIgeTI9IjEyMyIgc3Ryb2tlPSIjMDQ3ODU3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZnAxKSIvPgo8dGV4dCB4PSI1NTYiIHk9IjExNCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4cHgiPmRyYWluPC90ZXh0Pgo8cmVjdCB4PSI1ODQiIHk9Ijg4IiB3aWR0aD0iMjIwIiBoZWlnaHQ9IjcyIiByeD0iMTEiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2UyZThmMCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iNjk0IiB5PSIxMTMiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMGYxNzJhOyBmb250LXNpemU6MTJweCI+U3Vic2NyaXB0aW9uczwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxMjkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5kZWxpdmVyeSBhdHRlbXB0czwvdGV4dD4KPHRleHQgeD0iNjk0IiB5PSIxNDUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5yZXRyeSBvciB0ZXJtaW5hbCBmYWlsdXJlPC90ZXh0Pgo8L3N2Zz4=" alt="On Azure the publisher's SNS Publish call is served by a Tensor9 adapter which writes the fan-out into a durable outbox on a Microsoft-operated Flexible Postgres server, and a delivery loop drains the outbox to each subscription with at-least-once retry." />

  <img className="t9-diagram-dark" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjEwIiB2aWV3Qm94PSIwIDAgODM2IDIxMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBenVyZSB0aGUgcHVibGlzaGVyJ3MgU05TIFB1Ymxpc2ggY2FsbCBpcyBzZXJ2ZWQgYnkgYSBUZW5zb3I5IGFkYXB0ZXIgd2hpY2ggd3JpdGVzIHRoZSBmYW4tb3V0IGludG8gYSBkdXJhYmxlIG91dGJveCBvbiBhIE1pY3Jvc29mdC1vcGVyYXRlZCBGbGV4aWJsZSBQb3N0Z3JlcyBzZXJ2ZXIsIGFuZCBhIGRlbGl2ZXJ5IGxvb3AgZHJhaW5zIHRoZSBvdXRib3ggdG8gZWFjaCBzdWJzY3JpcHRpb24gd2l0aCBhdC1sZWFzdC1vbmNlIHJldHJ5LiI+PHN0eWxlPnRleHR7Zm9udC1mYW1pbHk6SW50ZXIsLWFwcGxlLXN5c3RlbSxCbGlua01hY1N5c3RlbUZvbnQsJ1NlZ29lIFVJJyxSb2JvdG8sJ0hlbHZldGljYSBOZXVlJyxBcmlhbCxzYW5zLXNlcmlmO2ZpbGw6I2NiZDVlMX08L3N0eWxlPgo8ZGVmcz48bWFya2VyIGlkPSJmcDEiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOCIgcmVmWT0iNSIgbWFya2VyV2lkdGg9IjciIG1hcmtlckhlaWdodD0iNyIgb3JpZW50PSJhdXRvLXN0YXJ0LXJldmVyc2UiPjxwYXRoIGQ9Ik0wLDAgTDEwLDUgTDAsMTAgeiIgZmlsbD0iIzk0YTNiOCIvPjwvbWFya2VyPjwvZGVmcz4KPHJlY3QgeD0iMTYiIHk9IjQ0IiB3aWR0aD0iODA0IiBoZWlnaHQ9IjE1MCIgcng9IjE0IiBmaWxsPSIjMWEyNjMxIiBzdHJva2U9IiMzZDRmNjYiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiLz4KPHRleHQgeD0iMzAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDogIzkwZGVjOCI+T04gQVpVUkU8L3RleHQ+CjxyZWN0IHg9IjM0IiB5PSI5MiIgd2lkdGg9IjEwNCIgaGVpZ2h0PSI2NCIgcng9IjExIiBmaWxsPSIjMjYyNjI2IiBzdHJva2U9IiMzZDRlNjYiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9Ijg2IiB5PSIxMjEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZWQ4OyBmb250LXNpemU6MTJweCI+UHVibGlzaGVyPC90ZXh0Pgo8dGV4dCB4PSI4NiIgeT0iMTM3IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2M5Y2ZkOCI+U05TIFNESzwvdGV4dD4KPGxpbmUgeDE9IjEzOCIgeTE9IjEyMyIgeDI9IjE4NCIgeTI9IjEyMyIgc3Ryb2tlPSIjMDQ3ODU3IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZnAxKSIvPgo8cmVjdCB4PSIxODgiIHk9Ijg4IiB3aWR0aD0iMTE2IiBoZWlnaHQ9IjcyIiByeD0iMTEiIGZpbGw9IiMyNjI2MjYiIHN0cm9rZT0iIzNkNGU2NiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHRleHQgeD0iMjQ2IiB5PSIxMjEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiA2NTAgMTMuNXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjYzljZWQ4OyBmb250LXNpemU6MTJweCI+VGVuc29yOSBhZGFwdGVyPC90ZXh0Pgo8dGV4dCB4PSIyNDYiIHk9IjEzNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPnNlcnZlcyBTTlM8L3RleHQ+CjxsaW5lIHgxPSIzMDQiIHkxPSIxMjMiIHgyPSIzNTAiIHkyPSIxMjMiIHN0cm9rZT0iIzA0Nzg1NyIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2ZwMSkiLz4KPHRleHQgeD0iMzI3IiB5PSIxMTQiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMHB4ICdTRiBNb25vJywgdWktbW9ub3NwYWNlLCAnSmV0QnJhaW5zIE1vbm8nLCBNZW5sbywgbW9ub3NwYWNlOyBmaWxsOiAjYzljZmQ4OyBmb250LXNpemU6OHB4Ij50cmFuc2FjdGlvbjwvdGV4dD4KPHJlY3QgeD0iMzU0IiB5PSI4NCIgd2lkdGg9IjE3OCIgaGVpZ2h0PSI4MCIgcng9IjExIiBmaWxsPSIjMjYyNjI2IiBzdHJva2U9IiMzZDRlNjYiIHN0cm9rZS13aWR0aD0iMS41Ii8+Cjx0ZXh0IHg9IjQ0MyIgeT0iMTEzIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2M5Y2VkODsgZm9udC1zaXplOjEycHgiPkZsZXhpYmxlIFBvc3RncmVzPC90ZXh0Pgo8dGV4dCB4PSI0NDMiIHk9IjEyOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPmR1cmFibGUgb3V0Ym94PC90ZXh0Pgo8dGV4dCB4PSI0NDMiIHk9IjE0NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTBkZWM2OyBmaWxsOiAjOTBkZWM4Ij5tYW5hZ2VkIGJhY2t1cCArIEhBPC90ZXh0Pgo8bGluZSB4MT0iNTMyIiB5MT0iMTIzIiB4Mj0iNTgwIiB5Mj0iMTIzIiBzdHJva2U9IiMwNDc4NTciIHN0cm9rZS13aWR0aD0iMiIgbWFya2VyLWVuZD0idXJsKCNmcDEpIi8+Cjx0ZXh0IHg9IjU1NiIgeT0iMTE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogI2M5Y2ZkODsgZm9udC1zaXplOjhweCI+ZHJhaW48L3RleHQ+CjxyZWN0IHg9IjU4NCIgeT0iODgiIHdpZHRoPSIyMjAiIGhlaWdodD0iNzIiIHJ4PSIxMSIgZmlsbD0iIzI2MjYyNiIgc3Ryb2tlPSIjM2Q0ZTY2IiBzdHJva2Utd2lkdGg9IjEuNSIvPgo8dGV4dCB4PSI2OTQiIHk9IjExMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNlZDg7IGZvbnQtc2l6ZToxMnB4Ij5TdWJzY3JpcHRpb25zPC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjEyOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPmRlbGl2ZXJ5IGF0dGVtcHRzPC90ZXh0Pgo8dGV4dCB4PSI2OTQiIHk9IjE0NSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNjOWNmZDgiPnJldHJ5IG9yIHRlcm1pbmFsIGZhaWx1cmU8L3RleHQ+Cjwvc3ZnPg==" alt="On Azure the publisher's SNS Publish call is served by a Tensor9 adapter which writes the fan-out into a durable outbox on a Microsoft-operated Flexible Postgres server, and a delivery loop drains the outbox to each subscription with at-least-once retry." />
</div>

#### Choosing Service Bus or PostgreSQL

Both Azure SNS targets exclude filter policies, raw message delivery, FIFO topics and subscription redrive. Choose between them based on how messages are stored and retried:

* **Service Bus** stores one published message for delivery to each subscription and manages retry in the broker. Microsoft operates Service Bus; the adapter delivers notifications to subscription endpoints.
* **Flexible Postgres** commits the message and all subscription delivery rows together. Tensor9's delivery loop tracks acknowledgments, bounded retries and terminal failures, while Microsoft operates the database. You can inspect pending deliveries with SQL, and must size the database for notification traffic.

#### Limitations

△ PostgreSQL delivery limitations

* **Filter policies are out of scope.** Subscription filter policies have no counterpart. Every subscription on a topic receives every message published to it, so filtering that SNS did for you becomes filtering your subscriber has to do. This is the limitation most likely to change a design.
* **Raw message delivery is out of scope.** The raw-delivery option, which strips SNS's envelope for SQS and HTTP subscribers, is not offered. Subscribers that were written to expect raw payloads need to read the enveloped form instead.
* **FIFO topics are not offered.** Ordered SNS topics have no equivalent here. A design that depends on ordering needs that gap closed before this target is viable.
* **Subscription redrive is out of scope.** SNS subscription redrive to a configured dead-letter queue is not reproduced. The outbox records permanent failures and exhausted attempts as terminal rows; it does not retry them forever or forward them through an SNS redrive policy.
* **Delivery is at-least-once, so subscribers must be idempotent.** A retry after an unrecorded acknowledgment means a subscriber can see the same notification twice, after a delivery that succeeded but whose acknowledgement was lost, for instance. This matches SNS's at-least-once contract; subscribers must safely handle duplicate notifications.

#### Other considerations

* **Size the database for notification traffic.** Flexible Server is managed (backup, patching and HA are Microsoft's), but its size, storage and connection limits are yours. The outbox is a table, so notification volume consumes database capacity.
* **Inspect pending deliveries with SQL.** Query the outbox to count undelivered notifications and investigate subscribers whose deliveries keep failing.
* **Plan publisher cutover and subscription confirmation.** Provision the server and schema, register subscriptions and complete confirmation before repointing publishers. Allow pending AWS deliveries to finish; they are not copied into the new outbox.
* **Authentication uses workload identity.** The adapter reaches the server through Entra with the appliance's own workload identity, so no password is emitted into applied Terraform or held anywhere for this path.

[Service Catalog](/service-adapters/catalog).
