> ## 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.

# MSK (Kafka)

> MSK (Kafka) APIs with Cloud Adapter.

This page describes how MSK (Kafka) maps to services in the environment where the application runs, including backend choices, supported operations and service-specific behavior.

## Supported environments

* Akamai
* Azure
* DigitalOcean
* Google Cloud
* OCI
* Private Kubernetes
* Scaleway

Check the operation and capability tables for the behavior your application depends on. A supported environment does not imply that every operation of the origin service is available.

## How the backends compare

Each row compares a capability of MSK (Kafka) with its adaptation on each backend.
A dash means this profile does not state the capability for that backend.

### Cloud Adapter

| Capability | MSK (Kafka) | Akamai, DigitalOcean, Google Cloud, Private Kubernetes, and Scaleway · Strimzi Kafka | Akamai, Google Cloud, Private Kubernetes, and Scaleway · Bitnami Kafka | Akamai, Private Kubernetes, and Scaleway · Apache Kafka | Azure | DigitalOcean · DigitalOcean Managed Kafka | Google Cloud · Managed Service for Apache Kafka | OCI | Scaleway · Scaleway Clusters for Apache Kafka |
| - | - | - | - | - | - | - | - | - | - |
| Kafka wire protocol | Apache Kafka | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged | native: producer/consumer unchanged |
| Durability / replication / HA · who operates the broker | AWS-managed (MSK) | you (self-managed on the cluster) | you (self-managed on the cluster) | you (self-managed on the cluster) | Microsoft (managed Event Hubs) | DigitalOcean (managed Kafka, currently 3.8) | Google (managed Apache Kafka) | Oracle (OCI-managed stream pool) | Scaleway (Clusters for Apache Kafka, a real Apache Kafka engine) |
| Authentication · broker auth | SASL/SCRAM, mTLS, IAM | SASL/SCRAM + mTLS (MSK IAM has no analog) | SASL/SCRAM + mTLS (MSK IAM has no analog) | SASL/SCRAM + mTLS (MSK IAM has no analog) | Shared Access Signatures / Microsoft Entra (not Kafka SASL or MSK IAM) | DigitalOcean-issued SASL/TLS (MSK IAM has no analog) | Google Cloud IAM over SASL\_SSL/OAUTHBEARER (MSK IAM, SASL/SCRAM and mTLS have no analog) | OCI auth tokens (not MSK SASL/SCRAM/mTLS/IAM) | Scaleway-issued username/password on the cluster (MSK's SASL/IAM has no analog) |
| Retention / storage | broker log + tiered storage | the broker's own local storage (no tiered storage) | the broker's own local storage (no tiered storage) | the broker's own local storage (no tiered storage) | Event Hubs managed retention (capacity sized in throughput/processing units, separate from the partition count) | the managed broker's own storage | the managed broker's own storage, tuned per topic | the stream pool's managed storage, under OCI quotas | the managed broker's own storage, allocated in 5 GB steps from a 10 GB floor |
| Encryption in transit | Yes | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS | Yes - client-broker TLS terminates on the target listener's TLS |
| Encryption at rest | KMS key ARN | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) | the backend's own storage / managed encryption (the KMS key ARN has no equivalent) |
| API coverage | full | high | high | high | partial | high | high | partial | high |
| SASL/IAM clients need a client-side change · a mechanism, not a credential | AWS\_MSK\_IAM via aws-msk-iam-auth | - | - | - | - | - | - | - | SASL/PLAIN or SASL/SCRAM with Scaleway's credentials |
| The Kafka version is chosen, not copied · and this is why | your cluster's kafka\_version | - | - | - | - | - | - | - | 4.1.1, the newest Scaleway offers |
| Every broker size is marked beta · Scaleway's own flag, not ours | the MSK broker instance type you chose | - | - | - | - | - | - | - | brokernode-shared-2c-8g (2 vCPU / 8 GB) |
| The same stack references work on either cloud · a deliberate constraint | bootstrap\_brokers\_tls, bootstrap\_brokers\_sasl\_scram, … | - | - | - | - | - | - | - | the identical set on Scaleway and DigitalOcean |

## On Akamai, DigitalOcean, Google Cloud, Private Kubernetes, and Scaleway

### Strimzi Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | the backend broker natively accepts custom broker config (via the Strimzi or Bitnami chart's config values, or the broker's own config for a raw Apache deployment); MSK's custom broker-config revision has no counterpart, so broker config is set on the backend directly |
| Partition semantics | Admin | Supported | Most usage | partitions are the real broker's own; set and grow them via the AdminClient as on Kafka |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to the real broker: create/delete topics, alter configs, and manage partitions natively |
| ACLs / SASL auth | Auth | Partial | Full surface | SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and configure access-control lists on the broker. |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the broker's own \_\_consumer\_offsets, exactly as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence, and transactions are the real broker's own, with full exactly-once semantics |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Supported | Most usage | the MSK broker instance type is normalized to CPU/memory and emitted as the broker pod's resource requests/limits (kafka.m5.large → 2 vCPU / 8 GiB), and the storage volume size becomes the broker's persistent-volume size, so sizing follows through to a broker you own |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to Apache Kafka on Kubernetes cluster (via the Strimzi operator) over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and manage the broker's access-control lists. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** You configure the replication factor and minimum in-sync replicas (ISR), monitor replica health, and operate storage, recovery and upgrades. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on Apache Kafka on Kubernetes cluster (via the Strimzi operator), and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On Akamai, Google Cloud, Private Kubernetes, and Scaleway

### Bitnami Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | the backend broker natively accepts custom broker config (via the Strimzi or Bitnami chart's config values, or the broker's own config for a raw Apache deployment); MSK's custom broker-config revision has no counterpart, so broker config is set on the backend directly |
| Partition semantics | Admin | Supported | Most usage | partitions are the real broker's own; set and grow them via the AdminClient as on Kafka |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to the real broker: create/delete topics, alter configs, and manage partitions natively |
| ACLs / SASL auth | Auth | Partial | Full surface | SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and configure access-control lists on the broker. |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the broker's own \_\_consumer\_offsets, exactly as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence, and transactions are the real broker's own, with full exactly-once semantics |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Supported | Most usage | the MSK broker instance type is normalized to CPU/memory and emitted as the broker pod's resource requests/limits (kafka.m5.large → 2 vCPU / 8 GiB), and the storage volume size becomes the broker's persistent-volume size, so sizing follows through to a broker you own |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to Apache Kafka on Kubernetes cluster (via the Bitnami Kafka chart) over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and manage the broker's access-control lists. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** You configure the replication factor and minimum in-sync replicas (ISR), monitor replica health, and operate storage, recovery and upgrades. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on Apache Kafka on Kubernetes cluster (via the Bitnami Kafka chart), and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On Akamai, Private Kubernetes, and Scaleway

### Apache Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | the backend broker natively accepts custom broker config (via the Strimzi or Bitnami chart's config values, or the broker's own config for a raw Apache deployment); MSK's custom broker-config revision has no counterpart, so broker config is set on the backend directly |
| Partition semantics | Admin | Supported | Most usage | partitions are the real broker's own; set and grow them via the AdminClient as on Kafka |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to the real broker: create/delete topics, alter configs, and manage partitions natively |
| ACLs / SASL auth | Auth | Partial | Full surface | SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and configure access-control lists on the broker. |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the broker's own \_\_consumer\_offsets, exactly as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence, and transactions are the real broker's own, with full exactly-once semantics |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Supported | Most usage | the MSK broker instance type is normalized to CPU/memory and emitted as the broker pod's resource requests/limits (kafka.m5.large → 2 vCPU / 8 GiB), and the storage volume size becomes the broker's persistent-volume size, so sizing follows through to a broker you own |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to Apache Kafka on Kubernetes cluster (as a raw Apache Kafka deployment) over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: SASL/SCRAM and mutual TLS are supported. Replace MSK IAM authentication and manage the broker's access-control lists. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** You configure the replication factor and minimum in-sync replicas (ISR), monitor replica health, and operate storage, recovery and upgrades. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on Apache Kafka on Kubernetes cluster (as a raw Apache Kafka deployment), and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On Azure

### Azure Event Hubs

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Out of scope | Most usage | Event Hubs does not expose Kafka broker config, so MSK's custom broker-config revision has no analog |
| Partition semantics | Admin | Partial | Most usage | on Standard the partition count is set at creation and cannot be changed; Premium and Dedicated allow increasing (but not decreasing) it after creation, as Kafka itself allows; capacity is sized on a separate axis (throughput units on Standard, processing units on Premium), independent of the partition count |
| Topic admin (create / delete / configs) | Admin | Partial | Most usage | topics are Event Hubs, created up front; the Kafka broker-admin/ACL surface differs, so it is not full AdminClient parity |
| ACLs / SASL auth | Auth | Partial | Full surface | authentication is Shared Access Signatures or Microsoft Entra, not Kafka SASL/SCRAM or MSK IAM; your Kafka clients configure the Event Hubs connection string instead |
| Offset commit (\_\_consumer\_offsets) | Consume | Partial | Most usage | Event Hubs keeps its own consumer-group offset store; the semantics differ slightly from Kafka's \_\_consumer\_offsets |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Partial | Most usage | produce over the Kafka wire is unchanged; full transactions/idempotence are not complete on the Event Hubs Kafka surface |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Partial | Most usage | capacity is throughput units (Standard) or processing units (Premium), sized on a separate axis from the MSK broker instance type; the partition count is fixed at creation on Standard, while Premium and Dedicated allow increasing it |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your Kafka client connects directly to Azure Event Hubs at `<namespace>.servicebus.windows.net:9093`, the Kafka endpoint of the Standard and Premium tiers. Produce and consume code stay the same; you change the bootstrap address and credentials. Tensor9 does not sit in these connections.

Event Hubs differs from Kafka in administration, transactions, authentication and capacity. Review the differences below before you choose this backend.

![On AWS, your application's Kafka client connects to the MSK brokers. On Azure, the same client connects with the same Kafka protocol to an Event Hubs namespace's Kafka endpoint on port 9093, with no Tensor9 adapter in between.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBV1MsIHlvdXIgYXBwbGljYXRpb24ncyBLYWZrYSBjbGllbnQgY29ubmVjdHMgdG8gdGhlIE1TSyBicm9rZXJzLiBPbiBBenVyZSwgdGhlIHNhbWUgY2xpZW50IGNvbm5lY3RzIHdpdGggdGhlIHNhbWUgS2Fma2EgcHJvdG9jb2wgdG8gYW4gRXZlbnQgSHVicyBuYW1lc3BhY2UncyBLYWZrYSBlbmRwb2ludCBvbiBwb3J0IDkwOTMsIHdpdGggbm8gVGVuc29yOSBhZGFwdGVyIGluIGJldHdlZW4uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojMzM0MTU1fTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImVoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojOTRhM2I4Ii8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDQiIHdpZHRoPSIzODQiIGhlaWdodD0iMTM4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiNmOGZhZmM7c3Ryb2tlOiNjYmQ1ZTEiLz4KPHRleHQgeD0iMzAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojOTRhM2I4Ij5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4NCIgd2lkdGg9IjExNiIgaGVpZ2h0PSI2OCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI4OCIgeT0iMTE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4OCIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzY0NzQ4YiI+S2Fma2EgY2xpZW50PC90ZXh0Pgo8bGluZSB4MT0iMTQ2IiB5MT0iMTE4IiB4Mj0iMjIyIiB5Mj0iMTE4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZWgxKSIgc3R5bGU9InN0cm9rZTojOTRhM2I4Ii8+Cjx0ZXh0IHg9IjE4NCIgeT0iMTA5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzY0NzQ4YjsgZm9udC1zaXplOjguNXB4Ij5LYWZrYSB3aXJlPC90ZXh0Pgo8cmVjdCB4PSIyMjYiIHk9IjgyIiB3aWR0aD0iMTYwIiBoZWlnaHQ9IjcyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZTojY2JkNWUxIi8+CjxzdmcgeD0iMjM2IiB5PSI5NCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMzA0IDE4MiIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCIgc3R5bGU9ImRpc3BsYXk6IGlubGluZSI+PGc+IDxwYXRoIGQ9Ik04Ni40LDY2LjRjMCwzLjcsMC40LDYuNywxLjEsOC45YzAuOCwyLjIsMS44LDQuNiwzLjIsNy4yYzAuNSwwLjgsMC43LDEuNiwwLjcsMi4zYzAsMS0wLjYsMi0xLjksM2wtNi4zLDQuMiBjLTAuOSwwLjYtMS44LDAuOS0yLjYsMC45Yy0xLDAtMi0wLjUtMy0xLjRDNzYuMiw5MCw3NSw4OC40LDc0LDg2LjhjLTEtMS43LTItMy42LTMuMS01LjljLTcuOCw5LjItMTcuNiwxMy44LTI5LjQsMTMuOCBjLTguNCwwLTE1LjEtMi40LTIwLTcuMmMtNC45LTQuOC03LjQtMTEuMi03LjQtMTkuMmMwLTguNSwzLTE1LjQsOS4xLTIwLjZjNi4xLTUuMiwxNC4yLTcuOCwyNC41LTcuOGMzLjQsMCw2LjksMC4zLDEwLjYsMC44IGMzLjcsMC41LDcuNSwxLjMsMTEuNSwyLjJ2LTcuM2MwLTcuNi0xLjYtMTIuOS00LjctMTZjLTMuMi0zLjEtOC42LTQuNi0xNi4zLTQuNmMtMy41LDAtNy4xLDAuNC0xMC44LDEuM2MtMy43LDAuOS03LjMsMi0xMC44LDMuNCBjLTEuNiwwLjctMi44LDEuMS0zLjUsMS4zYy0wLjcsMC4yLTEuMiwwLjMtMS42LDAuM2MtMS40LDAtMi4xLTEtMi4xLTMuMXYtNC45YzAtMS42LDAuMi0yLjgsMC43LTMuNWMwLjUtMC43LDEuNC0xLjQsMi44LTIuMSBjMy41LTEuOCw3LjctMy4zLDEyLjYtNC41YzQuOS0xLjMsMTAuMS0xLjksMTUuNi0xLjljMTEuOSwwLDIwLjYsMi43LDI2LjIsOC4xYzUuNSw1LjQsOC4zLDEzLjYsOC4zLDI0LjZWNjYuNHogTTQ1LjgsODEuNiBjMy4zLDAsNi43LTAuNiwxMC4zLTEuOGMzLjYtMS4yLDYuOC0zLjQsOS41LTYuNGMxLjYtMS45LDIuOC00LDMuNC02LjRjMC42LTIuNCwxLTUuMywxLTguN3YtNC4yYy0yLjktMC43LTYtMS4zLTkuMi0xLjcgYy0zLjItMC40LTYuMy0wLjYtOS40LTAuNmMtNi43LDAtMTEuNiwxLjMtMTQuOSw0Yy0zLjMsMi43LTQuOSw2LjUtNC45LDExLjVjMCw0LjcsMS4yLDguMiwzLjcsMTAuNiBDMzcuNyw4MC40LDQxLjIsODEuNiw0NS44LDgxLjZ6IE0xMjYuMSw5Mi40Yy0xLjgsMC0zLTAuMy0zLjgtMWMtMC44LTAuNi0xLjUtMi0yLjEtMy45TDk2LjcsMTAuMmMtMC42LTItMC45LTMuMy0wLjktNCBjMC0xLjYsMC44LTIuNSwyLjQtMi41aDkuOGMxLjksMCwzLjIsMC4zLDMuOSwxYzAuOCwwLjYsMS40LDIsMiwzLjlsMTYuOCw2Ni4ybDE1LjYtNjYuMmMwLjUtMiwxLjEtMy4zLDEuOS0zLjljMC44LTAuNiwyLjItMSw0LTEgaDhjMS45LDAsMy4yLDAuMyw0LDFjMC44LDAuNiwxLjUsMiwxLjksMy45bDE1LjgsNjdsMTcuMy02N2MwLjYtMiwxLjMtMy4zLDItMy45YzAuOC0wLjYsMi4xLTEsMy45LTFoOS4zYzEuNiwwLDIuNSwwLjgsMi41LDIuNSBjMCwwLjUtMC4xLDEtMC4yLDEuNmMtMC4xLDAuNi0wLjMsMS40LTAuNywyLjVsLTI0LjEsNzcuM2MtMC42LDItMS4zLDMuMy0yLjEsMy45Yy0wLjgsMC42LTIuMSwxLTMuOCwxaC04LjZjLTEuOSwwLTMuMi0wLjMtNC0xIGMtMC44LTAuNy0xLjUtMi0xLjktNEwxNTYsMjNsLTE1LjQsNjQuNGMtMC41LDItMS4xLDMuMy0xLjksNGMtMC44LDAuNy0yLjIsMS00LDFIMTI2LjF6IE0yNTQuNiw5NS4xYy01LjIsMC0xMC40LTAuNi0xNS40LTEuOCBjLTUtMS4yLTguOS0yLjUtMTEuNS00Yy0xLjYtMC45LTIuNy0xLjktMy4xLTIuOGMtMC40LTAuOS0wLjYtMS45LTAuNi0yLjh2LTUuMWMwLTIuMSwwLjgtMy4xLDIuMy0zLjFjMC42LDAsMS4yLDAuMSwxLjgsMC4zIGMwLjYsMC4yLDEuNSwwLjYsMi41LDFjMy40LDEuNSw3LjEsMi43LDExLDMuNWM0LDAuOCw3LjksMS4yLDExLjksMS4yYzYuMywwLDExLjItMS4xLDE0LjYtMy4zYzMuNC0yLjIsNS4yLTUuNCw1LjItOS41IGMwLTIuOC0wLjktNS4xLTIuNy03Yy0xLjgtMS45LTUuMi0zLjYtMTAuMS01LjJMMjQ2LDUyYy03LjMtMi4zLTEyLjctNS43LTE2LTEwLjJjLTMuMy00LjQtNS05LjMtNS0xNC41YzAtNC4yLDAuOS03LjksMi43LTExLjEgYzEuOC0zLjIsNC4yLTYsNy4yLTguMmMzLTIuMyw2LjQtNCwxMC40LTUuMmM0LTEuMiw4LjItMS43LDEyLjYtMS43YzIuMiwwLDQuNSwwLjEsNi43LDAuNGMyLjMsMC4zLDQuNCwwLjcsNi41LDEuMSBjMiwwLjUsMy45LDEsNS43LDEuNmMxLjgsMC42LDMuMiwxLjIsNC4yLDEuOGMxLjQsMC44LDIuNCwxLjYsMywyLjVjMC42LDAuOCwwLjksMS45LDAuOSwzLjN2NC43YzAsMi4xLTAuOCwzLjItMi4zLDMuMiBjLTAuOCwwLTIuMS0wLjQtMy44LTEuMmMtNS43LTIuNi0xMi4xLTMuOS0xOS4yLTMuOWMtNS43LDAtMTAuMiwwLjktMTMuMywyLjhjLTMuMSwxLjktNC43LDQuOC00LjcsOC45YzAsMi44LDEsNS4yLDMsNy4xIGMyLDEuOSw1LjcsMy44LDExLDUuNWwxNC4yLDQuNWM3LjIsMi4zLDEyLjQsNS41LDE1LjUsOS42YzMuMSw0LjEsNC42LDguOCw0LjYsMTRjMCw0LjMtMC45LDguMi0yLjYsMTEuNiBjLTEuOCwzLjQtNC4yLDYuNC03LjMsOC44Yy0zLjEsMi41LTYuOCw0LjMtMTEuMSw1LjZDMjY0LjQsOTQuNCwyNTkuNyw5NS4xLDI1NC42LDk1LjF6IiBzdHlsZT0iZmlsbDojMjUyRjNFIi8+IDxnPiA8cGF0aCBkPSJNMjczLjUsMTQzLjdjLTMyLjksMjQuMy04MC43LDM3LjItMTIxLjgsMzcuMmMtNTcuNiwwLTEwOS41LTIxLjMtMTQ4LjctNTYuN2MtMy4xLTIuOC0wLjMtNi42LDMuNC00LjQgYzQyLjQsMjQuNiw5NC43LDM5LjUsMTQ4LjgsMzkuNWMzNi41LDAsNzYuNi03LjYsMTEzLjUtMjMuMkMyNzQuMiwxMzMuNiwyNzguOSwxMzkuNywyNzMuNSwxNDMuN3oiIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRjk5MDAiLz4gPHBhdGggZD0iTTI4Ny4yLDEyOC4xYy00LjItNS40LTI3LjgtMi42LTM4LjUtMS4zYy0zLjIsMC40LTMuNy0yLjQtMC44LTQuNWMxOC44LTEzLjIsNDkuNy05LjQsNTMuMy01IGMzLjYsNC41LTEsMzUuNC0xOC42LDUwLjJjLTIuNywyLjMtNS4zLDEuMS00LjEtMS45QzI4Mi41LDE1NS43LDI5MS40LDEzMy40LDI4Ny4yLDEyOC4xeiIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO2ZpbGw6I0ZGOTkwMCIvPiA8L2c+IDwvZz48L3N2Zz48c3ZnIHg9IjIzNiIgeT0iOTQiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDMwNCAxODIiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiIHN0eWxlPSJkaXNwbGF5OiBub25lIj48Zz4gPHBhdGggZD0iTTg2LjQsNjYuNGMwLDMuNywwLjQsNi43LDEuMSw4LjljMC44LDIuMiwxLjgsNC42LDMuMiw3LjJjMC41LDAuOCwwLjcsMS42LDAuNywyLjNjMCwxLTAuNiwyLTEuOSwzbC02LjMsNC4yIGMtMC45LDAuNi0xLjgsMC45LTIuNiwwLjljLTEsMC0yLTAuNS0zLTEuNEM3Ni4yLDkwLDc1LDg4LjQsNzQsODYuOGMtMS0xLjctMi0zLjYtMy4xLTUuOWMtNy44LDkuMi0xNy42LDEzLjgtMjkuNCwxMy44IGMtOC40LDAtMTUuMS0yLjQtMjAtNy4yYy00LjktNC44LTcuNC0xMS4yLTcuNC0xOS4yYzAtOC41LDMtMTUuNCw5LjEtMjAuNmM2LjEtNS4yLDE0LjItNy44LDI0LjUtNy44YzMuNCwwLDYuOSwwLjMsMTAuNiwwLjggYzMuNywwLjUsNy41LDEuMywxMS41LDIuMnYtNy4zYzAtNy42LTEuNi0xMi45LTQuNy0xNmMtMy4yLTMuMS04LjYtNC42LTE2LjMtNC42Yy0zLjUsMC03LjEsMC40LTEwLjgsMS4zYy0zLjcsMC45LTcuMywyLTEwLjgsMy40IGMtMS42LDAuNy0yLjgsMS4xLTMuNSwxLjNjLTAuNywwLjItMS4yLDAuMy0xLjYsMC4zYy0xLjQsMC0yLjEtMS0yLjEtMy4xdi00LjljMC0xLjYsMC4yLTIuOCwwLjctMy41YzAuNS0wLjcsMS40LTEuNCwyLjgtMi4xIGMzLjUtMS44LDcuNy0zLjMsMTIuNi00LjVjNC45LTEuMywxMC4xLTEuOSwxNS42LTEuOWMxMS45LDAsMjAuNiwyLjcsMjYuMiw4LjFjNS41LDUuNCw4LjMsMTMuNiw4LjMsMjQuNlY2Ni40eiBNNDUuOCw4MS42IGMzLjMsMCw2LjctMC42LDEwLjMtMS44YzMuNi0xLjIsNi44LTMuNCw5LjUtNi40YzEuNi0xLjksMi44LTQsMy40LTYuNGMwLjYtMi40LDEtNS4zLDEtOC43di00LjJjLTIuOS0wLjctNi0xLjMtOS4yLTEuNyBjLTMuMi0wLjQtNi4zLTAuNi05LjQtMC42Yy02LjcsMC0xMS42LDEuMy0xNC45LDRjLTMuMywyLjctNC45LDYuNS00LjksMTEuNWMwLDQuNywxLjIsOC4yLDMuNywxMC42IEMzNy43LDgwLjQsNDEuMiw4MS42LDQ1LjgsODEuNnogTTEyNi4xLDkyLjRjLTEuOCwwLTMtMC4zLTMuOC0xYy0wLjgtMC42LTEuNS0yLTIuMS0zLjlMOTYuNywxMC4yYy0wLjYtMi0wLjktMy4zLTAuOS00IGMwLTEuNiwwLjgtMi41LDIuNC0yLjVoOS44YzEuOSwwLDMuMiwwLjMsMy45LDFjMC44LDAuNiwxLjQsMiwyLDMuOWwxNi44LDY2LjJsMTUuNi02Ni4yYzAuNS0yLDEuMS0zLjMsMS45LTMuOWMwLjgtMC42LDIuMi0xLDQtMSBoOGMxLjksMCwzLjIsMC4zLDQsMWMwLjgsMC42LDEuNSwyLDEuOSwzLjlsMTUuOCw2N2wxNy4zLTY3YzAuNi0yLDEuMy0zLjMsMi0zLjljMC44LTAuNiwyLjEtMSwzLjktMWg5LjNjMS42LDAsMi41LDAuOCwyLjUsMi41IGMwLDAuNS0wLjEsMS0wLjIsMS42Yy0wLjEsMC42LTAuMywxLjQtMC43LDIuNWwtMjQuMSw3Ny4zYy0wLjYsMi0xLjMsMy4zLTIuMSwzLjljLTAuOCwwLjYtMi4xLDEtMy44LDFoLTguNmMtMS45LDAtMy4yLTAuMy00LTEgYy0wLjgtMC43LTEuNS0yLTEuOS00TDE1NiwyM2wtMTUuNCw2NC40Yy0wLjUsMi0xLjEsMy4zLTEuOSw0Yy0wLjgsMC43LTIuMiwxLTQsMUgxMjYuMXogTTI1NC42LDk1LjFjLTUuMiwwLTEwLjQtMC42LTE1LjQtMS44IGMtNS0xLjItOC45LTIuNS0xMS41LTRjLTEuNi0wLjktMi43LTEuOS0zLjEtMi44Yy0wLjQtMC45LTAuNi0xLjktMC42LTIuOHYtNS4xYzAtMi4xLDAuOC0zLjEsMi4zLTMuMWMwLjYsMCwxLjIsMC4xLDEuOCwwLjMgYzAuNiwwLjIsMS41LDAuNiwyLjUsMWMzLjQsMS41LDcuMSwyLjcsMTEsMy41YzQsMC44LDcuOSwxLjIsMTEuOSwxLjJjNi4zLDAsMTEuMi0xLjEsMTQuNi0zLjNjMy40LTIuMiw1LjItNS40LDUuMi05LjUgYzAtMi44LTAuOS01LjEtMi43LTdjLTEuOC0xLjktNS4yLTMuNi0xMC4xLTUuMkwyNDYsNTJjLTcuMy0yLjMtMTIuNy01LjctMTYtMTAuMmMtMy4zLTQuNC01LTkuMy01LTE0LjVjMC00LjIsMC45LTcuOSwyLjctMTEuMSBjMS44LTMuMiw0LjItNiw3LjItOC4yYzMtMi4zLDYuNC00LDEwLjQtNS4yYzQtMS4yLDguMi0xLjcsMTIuNi0xLjdjMi4yLDAsNC41LDAuMSw2LjcsMC40YzIuMywwLjMsNC40LDAuNyw2LjUsMS4xIGMyLDAuNSwzLjksMSw1LjcsMS42YzEuOCwwLjYsMy4yLDEuMiw0LjIsMS44YzEuNCwwLjgsMi40LDEuNiwzLDIuNWMwLjYsMC44LDAuOSwxLjksMC45LDMuM3Y0LjdjMCwyLjEtMC44LDMuMi0yLjMsMy4yIGMtMC44LDAtMi4xLTAuNC0zLjgtMS4yYy01LjctMi42LTEyLjEtMy45LTE5LjItMy45Yy01LjcsMC0xMC4yLDAuOS0xMy4zLDIuOGMtMy4xLDEuOS00LjcsNC44LTQuNyw4LjljMCwyLjgsMSw1LjIsMyw3LjEgYzIsMS45LDUuNywzLjgsMTEsNS41bDE0LjIsNC41YzcuMiwyLjMsMTIuNCw1LjUsMTUuNSw5LjZjMy4xLDQuMSw0LjYsOC44LDQuNiwxNGMwLDQuMy0wLjksOC4yLTIuNiwxMS42IGMtMS44LDMuNC00LjIsNi40LTcuMyw4LjhjLTMuMSwyLjUtNi44LDQuMy0xMS4xLDUuNkMyNjQuNCw5NC40LDI1OS43LDk1LjEsMjU0LjYsOTUuMXoiIHN0eWxlPSJmaWxsOiNGRkZGRkYiLz4gPGc+IDxwYXRoIGQ9Ik0yNzMuNSwxNDMuN2MtMzIuOSwyNC4zLTgwLjcsMzcuMi0xMjEuOCwzNy4yYy01Ny42LDAtMTA5LjUtMjEuMy0xNDguNy01Ni43Yy0zLjEtMi44LTAuMy02LjYsMy40LTQuNCBjNDIuNCwyNC42LDk0LjcsMzkuNSwxNDguOCwzOS41YzM2LjUsMCw3Ni42LTcuNiwxMTMuNS0yMy4yQzI3NC4yLDEzMy42LDI3OC45LDEzOS43LDI3My41LDE0My43eiIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO2ZpbGw6I0ZGOTkwMCIvPiA8cGF0aCBkPSJNMjg3LjIsMTI4LjFjLTQuMi01LjQtMjcuOC0yLjYtMzguNS0xLjNjLTMuMiwwLjQtMy43LTIuNC0wLjgtNC41YzE4LjgtMTMuMiw0OS43LTkuNCw1My4zLTUgYzMuNiw0LjUtMSwzNS40LTE4LjYsNTAuMmMtMi43LDIuMy01LjMsMS4xLTQuMS0xLjlDMjgyLjUsMTU1LjcsMjkxLjQsMTMzLjQsMjg3LjIsMTI4LjF6IiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkY5OTAwIi8+IDwvZz4gPC9nPjwvc3ZnPgo8dGV4dCB4PSIzMDYiIHk9IjEwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gTVNLPC90ZXh0Pgo8dGV4dCB4PSIzMDYiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmJyb2tlciBjb3VudDwvdGV4dD4KPHRleHQgeD0iMzA2IiB5PSIxMzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5pbnN0YW5jZSBzaXplPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNzIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiNjYmQ1ZTEiLz4KPHJlY3QgeD0iNDM2IiB5PSI0NCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMzgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6I2Y4ZmFmYztzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI0NTAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzk0YTNiODsgZmlsbDojMDQ3ODU3Ij5PTiBBWlVSRTwvdGV4dD4KPHJlY3QgeD0iNDUwIiB5PSI4NCIgd2lkdGg9IjExNiIgaGVpZ2h0PSI2OCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI1MDgiIHk9IjExNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICMwZjE3MmE7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTA4IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNjQ3NDhiIj5zYW1lIGNsaWVudDwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExOCIgeDI9IjY0MiIgeTI9IjExOCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2VoMSkiIHN0eWxlPSJzdHJva2U6IzA0Nzg1NyIvPgo8dGV4dCB4PSI2MDQiIHk9IjEwOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM2NDc0OGI7IGZvbnQtc2l6ZTo4LjVweCI+S2Fma2Egd2lyZTwvdGV4dD4KPHJlY3QgeD0iNjQ2IiB5PSI3OCIgd2lkdGg9IjE2MCIgaGVpZ2h0PSI4MCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2U6I2NiZDVlMSIvPgo8dGV4dCB4PSI3MjYiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzBmMTcyYTsgZm9udC1zaXplOjEycHgiPkV2ZW50IEh1YnMgbmFtZXNwYWNlPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjExNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPkthZmthIGVuZHBvaW50IDo5MDkzPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM2NDc0OGIiPmNhcGFjaXR5IHVuaXRzPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjE0NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjMDQ3ODU3OyBmaWxsOiMwNDc4NTciPm5vIGFkYXB0ZXIgaW4gdGhlIHBhdGg8L3RleHQ+Cjwvc3ZnPg==)

![On AWS, your application's Kafka client connects to the MSK brokers. On Azure, the same client connects with the same Kafka protocol to an Event Hubs namespace's Kafka endpoint on port 9093, with no Tensor9 adapter in between.](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4MzYiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgODM2IDIwMCIgcm9sZT0iaW1nIiBhcmlhLWxhYmVsPSJPbiBBV1MsIHlvdXIgYXBwbGljYXRpb24ncyBLYWZrYSBjbGllbnQgY29ubmVjdHMgdG8gdGhlIE1TSyBicm9rZXJzLiBPbiBBenVyZSwgdGhlIHNhbWUgY2xpZW50IGNvbm5lY3RzIHdpdGggdGhlIHNhbWUgS2Fma2EgcHJvdG9jb2wgdG8gYW4gRXZlbnQgSHVicyBuYW1lc3BhY2UncyBLYWZrYSBlbmRwb2ludCBvbiBwb3J0IDkwOTMsIHdpdGggbm8gVGVuc29yOSBhZGFwdGVyIGluIGJldHdlZW4uIj48c3R5bGU+dGV4dHtmb250LWZhbWlseTpJbnRlciwtYXBwbGUtc3lzdGVtLEJsaW5rTWFjU3lzdGVtRm9udCwnU2Vnb2UgVUknLFJvYm90bywnSGVsdmV0aWNhIE5ldWUnLEFyaWFsLHNhbnMtc2VyaWY7ZmlsbDojY2JkNWUxfTwvc3R5bGU+CjxkZWZzPjxtYXJrZXIgaWQ9ImVoMSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI4IiByZWZZPSI1IiBtYXJrZXJXaWR0aD0iNyIgbWFya2VySGVpZ2h0PSI3IiBvcmllbnQ9ImF1dG8tc3RhcnQtcmV2ZXJzZSI+PHBhdGggZD0iTTAsMCBMMTAsNSBMMCwxMCB6IiBzdHlsZT0iZmlsbDojNjQ3NDhiIi8+PC9tYXJrZXI+PC9kZWZzPgo8cmVjdCB4PSIxNiIgeT0iNDQiIHdpZHRoPSIzODQiIGhlaWdodD0iMTM4IiByeD0iMTQiIHN0cm9rZS13aWR0aD0iMS40IiBzdHJva2UtZGFzaGFycmF5PSI1IDUiIHN0eWxlPSJmaWxsOiMwZjE3MmE7c3Ryb2tlOiM0NzU1NjkiLz4KPHRleHQgeD0iMzAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNjQ3NDhiIj5PTiBBV1MgVE9EQVk8L3RleHQ+CjxyZWN0IHg9IjMwIiB5PSI4NCIgd2lkdGg9IjExNiIgaGVpZ2h0PSI2OCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI4OCIgeT0iMTE1IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPllvdXIgYXBwPC90ZXh0Pgo8dGV4dCB4PSI4OCIgeT0iMTMxIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTFweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogIzk0YTNiOCI+S2Fma2EgY2xpZW50PC90ZXh0Pgo8bGluZSB4MT0iMTQ2IiB5MT0iMTE4IiB4Mj0iMjIyIiB5Mj0iMTE4IiBzdHJva2Utd2lkdGg9IjIiIG1hcmtlci1lbmQ9InVybCgjZWgxKSIgc3R5bGU9InN0cm9rZTojNjQ3NDhiIi8+Cjx0ZXh0IHg9IjE4NCIgeT0iMTA5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogMTBweCAnU0YgTW9ubycsIHVpLW1vbm9zcGFjZSwgJ0pldEJyYWlucyBNb25vJywgTWVubG8sIG1vbm9zcGFjZTsgZmlsbDogIzk0YTNiODsgZm9udC1zaXplOjguNXB4Ij5LYWZrYSB3aXJlPC90ZXh0Pgo8cmVjdCB4PSIyMjYiIHk9IjgyIiB3aWR0aD0iMTYwIiBoZWlnaHQ9IjcyIiByeD0iMTEiIHN0cm9rZS13aWR0aD0iMS41IiBzdHlsZT0iZmlsbDojMWUyOTNiO3N0cm9rZTojNDc1NTY5Ii8+CjxzdmcgeD0iMjM2IiB5PSI5NCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMzA0IDE4MiIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCIgc3R5bGU9ImRpc3BsYXk6IG5vbmUiPjxnPiA8cGF0aCBkPSJNODYuNCw2Ni40YzAsMy43LDAuNCw2LjcsMS4xLDguOWMwLjgsMi4yLDEuOCw0LjYsMy4yLDcuMmMwLjUsMC44LDAuNywxLjYsMC43LDIuM2MwLDEtMC42LDItMS45LDNsLTYuMyw0LjIgYy0wLjksMC42LTEuOCwwLjktMi42LDAuOWMtMSwwLTItMC41LTMtMS40Qzc2LjIsOTAsNzUsODguNCw3NCw4Ni44Yy0xLTEuNy0yLTMuNi0zLjEtNS45Yy03LjgsOS4yLTE3LjYsMTMuOC0yOS40LDEzLjggYy04LjQsMC0xNS4xLTIuNC0yMC03LjJjLTQuOS00LjgtNy40LTExLjItNy40LTE5LjJjMC04LjUsMy0xNS40LDkuMS0yMC42YzYuMS01LjIsMTQuMi03LjgsMjQuNS03LjhjMy40LDAsNi45LDAuMywxMC42LDAuOCBjMy43LDAuNSw3LjUsMS4zLDExLjUsMi4ydi03LjNjMC03LjYtMS42LTEyLjktNC43LTE2Yy0zLjItMy4xLTguNi00LjYtMTYuMy00LjZjLTMuNSwwLTcuMSwwLjQtMTAuOCwxLjNjLTMuNywwLjktNy4zLDItMTAuOCwzLjQgYy0xLjYsMC43LTIuOCwxLjEtMy41LDEuM2MtMC43LDAuMi0xLjIsMC4zLTEuNiwwLjNjLTEuNCwwLTIuMS0xLTIuMS0zLjF2LTQuOWMwLTEuNiwwLjItMi44LDAuNy0zLjVjMC41LTAuNywxLjQtMS40LDIuOC0yLjEgYzMuNS0xLjgsNy43LTMuMywxMi42LTQuNWM0LjktMS4zLDEwLjEtMS45LDE1LjYtMS45YzExLjksMCwyMC42LDIuNywyNi4yLDguMWM1LjUsNS40LDguMywxMy42LDguMywyNC42VjY2LjR6IE00NS44LDgxLjYgYzMuMywwLDYuNy0wLjYsMTAuMy0xLjhjMy42LTEuMiw2LjgtMy40LDkuNS02LjRjMS42LTEuOSwyLjgtNCwzLjQtNi40YzAuNi0yLjQsMS01LjMsMS04Ljd2LTQuMmMtMi45LTAuNy02LTEuMy05LjItMS43IGMtMy4yLTAuNC02LjMtMC42LTkuNC0wLjZjLTYuNywwLTExLjYsMS4zLTE0LjksNGMtMy4zLDIuNy00LjksNi41LTQuOSwxMS41YzAsNC43LDEuMiw4LjIsMy43LDEwLjYgQzM3LjcsODAuNCw0MS4yLDgxLjYsNDUuOCw4MS42eiBNMTI2LjEsOTIuNGMtMS44LDAtMy0wLjMtMy44LTFjLTAuOC0wLjYtMS41LTItMi4xLTMuOUw5Ni43LDEwLjJjLTAuNi0yLTAuOS0zLjMtMC45LTQgYzAtMS42LDAuOC0yLjUsMi40LTIuNWg5LjhjMS45LDAsMy4yLDAuMywzLjksMWMwLjgsMC42LDEuNCwyLDIsMy45bDE2LjgsNjYuMmwxNS42LTY2LjJjMC41LTIsMS4xLTMuMywxLjktMy45YzAuOC0wLjYsMi4yLTEsNC0xIGg4YzEuOSwwLDMuMiwwLjMsNCwxYzAuOCwwLjYsMS41LDIsMS45LDMuOWwxNS44LDY3bDE3LjMtNjdjMC42LTIsMS4zLTMuMywyLTMuOWMwLjgtMC42LDIuMS0xLDMuOS0xaDkuM2MxLjYsMCwyLjUsMC44LDIuNSwyLjUgYzAsMC41LTAuMSwxLTAuMiwxLjZjLTAuMSwwLjYtMC4zLDEuNC0wLjcsMi41bC0yNC4xLDc3LjNjLTAuNiwyLTEuMywzLjMtMi4xLDMuOWMtMC44LDAuNi0yLjEsMS0zLjgsMWgtOC42Yy0xLjksMC0zLjItMC4zLTQtMSBjLTAuOC0wLjctMS41LTItMS45LTRMMTU2LDIzbC0xNS40LDY0LjRjLTAuNSwyLTEuMSwzLjMtMS45LDRjLTAuOCwwLjctMi4yLDEtNCwxSDEyNi4xeiBNMjU0LjYsOTUuMWMtNS4yLDAtMTAuNC0wLjYtMTUuNC0xLjggYy01LTEuMi04LjktMi41LTExLjUtNGMtMS42LTAuOS0yLjctMS45LTMuMS0yLjhjLTAuNC0wLjktMC42LTEuOS0wLjYtMi44di01LjFjMC0yLjEsMC44LTMuMSwyLjMtMy4xYzAuNiwwLDEuMiwwLjEsMS44LDAuMyBjMC42LDAuMiwxLjUsMC42LDIuNSwxYzMuNCwxLjUsNy4xLDIuNywxMSwzLjVjNCwwLjgsNy45LDEuMiwxMS45LDEuMmM2LjMsMCwxMS4yLTEuMSwxNC42LTMuM2MzLjQtMi4yLDUuMi01LjQsNS4yLTkuNSBjMC0yLjgtMC45LTUuMS0yLjctN2MtMS44LTEuOS01LjItMy42LTEwLjEtNS4yTDI0Niw1MmMtNy4zLTIuMy0xMi43LTUuNy0xNi0xMC4yYy0zLjMtNC40LTUtOS4zLTUtMTQuNWMwLTQuMiwwLjktNy45LDIuNy0xMS4xIGMxLjgtMy4yLDQuMi02LDcuMi04LjJjMy0yLjMsNi40LTQsMTAuNC01LjJjNC0xLjIsOC4yLTEuNywxMi42LTEuN2MyLjIsMCw0LjUsMC4xLDYuNywwLjRjMi4zLDAuMyw0LjQsMC43LDYuNSwxLjEgYzIsMC41LDMuOSwxLDUuNywxLjZjMS44LDAuNiwzLjIsMS4yLDQuMiwxLjhjMS40LDAuOCwyLjQsMS42LDMsMi41YzAuNiwwLjgsMC45LDEuOSwwLjksMy4zdjQuN2MwLDIuMS0wLjgsMy4yLTIuMywzLjIgYy0wLjgsMC0yLjEtMC40LTMuOC0xLjJjLTUuNy0yLjYtMTIuMS0zLjktMTkuMi0zLjljLTUuNywwLTEwLjIsMC45LTEzLjMsMi44Yy0zLjEsMS45LTQuNyw0LjgtNC43LDguOWMwLDIuOCwxLDUuMiwzLDcuMSBjMiwxLjksNS43LDMuOCwxMSw1LjVsMTQuMiw0LjVjNy4yLDIuMywxMi40LDUuNSwxNS41LDkuNmMzLjEsNC4xLDQuNiw4LjgsNC42LDE0YzAsNC4zLTAuOSw4LjItMi42LDExLjYgYy0xLjgsMy40LTQuMiw2LjQtNy4zLDguOGMtMy4xLDIuNS02LjgsNC4zLTExLjEsNS42QzI2NC40LDk0LjQsMjU5LjcsOTUuMSwyNTQuNiw5NS4xeiIgc3R5bGU9ImZpbGw6IzI1MkYzRSIvPiA8Zz4gPHBhdGggZD0iTTI3My41LDE0My43Yy0zMi45LDI0LjMtODAuNywzNy4yLTEyMS44LDM3LjJjLTU3LjYsMC0xMDkuNS0yMS4zLTE0OC43LTU2LjdjLTMuMS0yLjgtMC4zLTYuNiwzLjQtNC40IGM0Mi40LDI0LjYsOTQuNywzOS41LDE0OC44LDM5LjVjMzYuNSwwLDc2LjYtNy42LDExMy41LTIzLjJDMjc0LjIsMTMzLjYsMjc4LjksMTM5LjcsMjczLjUsMTQzLjd6IiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkY5OTAwIi8+IDxwYXRoIGQ9Ik0yODcuMiwxMjguMWMtNC4yLTUuNC0yNy44LTIuNi0zOC41LTEuM2MtMy4yLDAuNC0zLjctMi40LTAuOC00LjVjMTguOC0xMy4yLDQ5LjctOS40LDUzLjMtNSBjMy42LDQuNS0xLDM1LjQtMTguNiw1MC4yYy0yLjcsMi4zLTUuMywxLjEtNC4xLTEuOUMyODIuNSwxNTUuNywyOTEuNCwxMzMuNCwyODcuMiwxMjguMXoiIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRjk5MDAiLz4gPC9nPiA8L2c+PC9zdmc+PHN2ZyB4PSIyMzYiIHk9Ijk0IiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAzMDQgMTgyIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0IiBzdHlsZT0iZGlzcGxheTogaW5saW5lIj48Zz4gPHBhdGggZD0iTTg2LjQsNjYuNGMwLDMuNywwLjQsNi43LDEuMSw4LjljMC44LDIuMiwxLjgsNC42LDMuMiw3LjJjMC41LDAuOCwwLjcsMS42LDAuNywyLjNjMCwxLTAuNiwyLTEuOSwzbC02LjMsNC4yIGMtMC45LDAuNi0xLjgsMC45LTIuNiwwLjljLTEsMC0yLTAuNS0zLTEuNEM3Ni4yLDkwLDc1LDg4LjQsNzQsODYuOGMtMS0xLjctMi0zLjYtMy4xLTUuOWMtNy44LDkuMi0xNy42LDEzLjgtMjkuNCwxMy44IGMtOC40LDAtMTUuMS0yLjQtMjAtNy4yYy00LjktNC44LTcuNC0xMS4yLTcuNC0xOS4yYzAtOC41LDMtMTUuNCw5LjEtMjAuNmM2LjEtNS4yLDE0LjItNy44LDI0LjUtNy44YzMuNCwwLDYuOSwwLjMsMTAuNiwwLjggYzMuNywwLjUsNy41LDEuMywxMS41LDIuMnYtNy4zYzAtNy42LTEuNi0xMi45LTQuNy0xNmMtMy4yLTMuMS04LjYtNC42LTE2LjMtNC42Yy0zLjUsMC03LjEsMC40LTEwLjgsMS4zYy0zLjcsMC45LTcuMywyLTEwLjgsMy40IGMtMS42LDAuNy0yLjgsMS4xLTMuNSwxLjNjLTAuNywwLjItMS4yLDAuMy0xLjYsMC4zYy0xLjQsMC0yLjEtMS0yLjEtMy4xdi00LjljMC0xLjYsMC4yLTIuOCwwLjctMy41YzAuNS0wLjcsMS40LTEuNCwyLjgtMi4xIGMzLjUtMS44LDcuNy0zLjMsMTIuNi00LjVjNC45LTEuMywxMC4xLTEuOSwxNS42LTEuOWMxMS45LDAsMjAuNiwyLjcsMjYuMiw4LjFjNS41LDUuNCw4LjMsMTMuNiw4LjMsMjQuNlY2Ni40eiBNNDUuOCw4MS42IGMzLjMsMCw2LjctMC42LDEwLjMtMS44YzMuNi0xLjIsNi44LTMuNCw5LjUtNi40YzEuNi0xLjksMi44LTQsMy40LTYuNGMwLjYtMi40LDEtNS4zLDEtOC43di00LjJjLTIuOS0wLjctNi0xLjMtOS4yLTEuNyBjLTMuMi0wLjQtNi4zLTAuNi05LjQtMC42Yy02LjcsMC0xMS42LDEuMy0xNC45LDRjLTMuMywyLjctNC45LDYuNS00LjksMTEuNWMwLDQuNywxLjIsOC4yLDMuNywxMC42IEMzNy43LDgwLjQsNDEuMiw4MS42LDQ1LjgsODEuNnogTTEyNi4xLDkyLjRjLTEuOCwwLTMtMC4zLTMuOC0xYy0wLjgtMC42LTEuNS0yLTIuMS0zLjlMOTYuNywxMC4yYy0wLjYtMi0wLjktMy4zLTAuOS00IGMwLTEuNiwwLjgtMi41LDIuNC0yLjVoOS44YzEuOSwwLDMuMiwwLjMsMy45LDFjMC44LDAuNiwxLjQsMiwyLDMuOWwxNi44LDY2LjJsMTUuNi02Ni4yYzAuNS0yLDEuMS0zLjMsMS45LTMuOWMwLjgtMC42LDIuMi0xLDQtMSBoOGMxLjksMCwzLjIsMC4zLDQsMWMwLjgsMC42LDEuNSwyLDEuOSwzLjlsMTUuOCw2N2wxNy4zLTY3YzAuNi0yLDEuMy0zLjMsMi0zLjljMC44LTAuNiwyLjEtMSwzLjktMWg5LjNjMS42LDAsMi41LDAuOCwyLjUsMi41IGMwLDAuNS0wLjEsMS0wLjIsMS42Yy0wLjEsMC42LTAuMywxLjQtMC43LDIuNWwtMjQuMSw3Ny4zYy0wLjYsMi0xLjMsMy4zLTIuMSwzLjljLTAuOCwwLjYtMi4xLDEtMy44LDFoLTguNmMtMS45LDAtMy4yLTAuMy00LTEgYy0wLjgtMC43LTEuNS0yLTEuOS00TDE1NiwyM2wtMTUuNCw2NC40Yy0wLjUsMi0xLjEsMy4zLTEuOSw0Yy0wLjgsMC43LTIuMiwxLTQsMUgxMjYuMXogTTI1NC42LDk1LjFjLTUuMiwwLTEwLjQtMC42LTE1LjQtMS44IGMtNS0xLjItOC45LTIuNS0xMS41LTRjLTEuNi0wLjktMi43LTEuOS0zLjEtMi44Yy0wLjQtMC45LTAuNi0xLjktMC42LTIuOHYtNS4xYzAtMi4xLDAuOC0zLjEsMi4zLTMuMWMwLjYsMCwxLjIsMC4xLDEuOCwwLjMgYzAuNiwwLjIsMS41LDAuNiwyLjUsMWMzLjQsMS41LDcuMSwyLjcsMTEsMy41YzQsMC44LDcuOSwxLjIsMTEuOSwxLjJjNi4zLDAsMTEuMi0xLjEsMTQuNi0zLjNjMy40LTIuMiw1LjItNS40LDUuMi05LjUgYzAtMi44LTAuOS01LjEtMi43LTdjLTEuOC0xLjktNS4yLTMuNi0xMC4xLTUuMkwyNDYsNTJjLTcuMy0yLjMtMTIuNy01LjctMTYtMTAuMmMtMy4zLTQuNC01LTkuMy01LTE0LjVjMC00LjIsMC45LTcuOSwyLjctMTEuMSBjMS44LTMuMiw0LjItNiw3LjItOC4yYzMtMi4zLDYuNC00LDEwLjQtNS4yYzQtMS4yLDguMi0xLjcsMTIuNi0xLjdjMi4yLDAsNC41LDAuMSw2LjcsMC40YzIuMywwLjMsNC40LDAuNyw2LjUsMS4xIGMyLDAuNSwzLjksMSw1LjcsMS42YzEuOCwwLjYsMy4yLDEuMiw0LjIsMS44YzEuNCwwLjgsMi40LDEuNiwzLDIuNWMwLjYsMC44LDAuOSwxLjksMC45LDMuM3Y0LjdjMCwyLjEtMC44LDMuMi0yLjMsMy4yIGMtMC44LDAtMi4xLTAuNC0zLjgtMS4yYy01LjctMi42LTEyLjEtMy45LTE5LjItMy45Yy01LjcsMC0xMC4yLDAuOS0xMy4zLDIuOGMtMy4xLDEuOS00LjcsNC44LTQuNyw4LjljMCwyLjgsMSw1LjIsMyw3LjEgYzIsMS45LDUuNywzLjgsMTEsNS41bDE0LjIsNC41YzcuMiwyLjMsMTIuNCw1LjUsMTUuNSw5LjZjMy4xLDQuMSw0LjYsOC44LDQuNiwxNGMwLDQuMy0wLjksOC4yLTIuNiwxMS42IGMtMS44LDMuNC00LjIsNi40LTcuMyw4LjhjLTMuMSwyLjUtNi44LDQuMy0xMS4xLDUuNkMyNjQuNCw5NC40LDI1OS43LDk1LjEsMjU0LjYsOTUuMXoiIHN0eWxlPSJmaWxsOiNGRkZGRkYiLz4gPGc+IDxwYXRoIGQ9Ik0yNzMuNSwxNDMuN2MtMzIuOSwyNC4zLTgwLjcsMzcuMi0xMjEuOCwzNy4yYy01Ny42LDAtMTA5LjUtMjEuMy0xNDguNy01Ni43Yy0zLjEtMi44LTAuMy02LjYsMy40LTQuNCBjNDIuNCwyNC42LDk0LjcsMzkuNSwxNDguOCwzOS41YzM2LjUsMCw3Ni42LTcuNiwxMTMuNS0yMy4yQzI3NC4yLDEzMy42LDI3OC45LDEzOS43LDI3My41LDE0My43eiIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO2ZpbGw6I0ZGOTkwMCIvPiA8cGF0aCBkPSJNMjg3LjIsMTI4LjFjLTQuMi01LjQtMjcuOC0yLjYtMzguNS0xLjNjLTMuMiwwLjQtMy43LTIuNC0wLjgtNC41YzE4LjgtMTMuMiw0OS43LTkuNCw1My4zLTUgYzMuNiw0LjUtMSwzNS40LTE4LjYsNTAuMmMtMi43LDIuMy01LjMsMS4xLTQuMS0xLjlDMjgyLjUsMTU1LjcsMjkxLjQsMTMzLjQsMjg3LjIsMTI4LjF6IiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkY5OTAwIi8+IDwvZz4gPC9nPjwvc3ZnPgo8dGV4dCB4PSIzMDYiIHk9IjEwNyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5BbWF6b24gTVNLPC90ZXh0Pgo8dGV4dCB4PSIzMDYiIHk9IjEyMyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmJyb2tlciBjb3VudDwvdGV4dD4KPHRleHQgeD0iMzA2IiB5PSIxMzkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5pbnN0YW5jZSBzaXplPC90ZXh0Pgo8bGluZSB4MT0iNDE4IiB5MT0iNDAiIHgyPSI0MTgiIHkyPSIxNzIiIHN0cm9rZS13aWR0aD0iMS40IiBzdHlsZT0ic3Ryb2tlOiM0NzU1NjkiLz4KPHJlY3QgeD0iNDM2IiB5PSI0NCIgd2lkdGg9IjM4NCIgaGVpZ2h0PSIxMzgiIHJ4PSIxNCIgc3Ryb2tlLXdpZHRoPSIxLjQiIHN0cm9rZS1kYXNoYXJyYXk9IjUgNSIgc3R5bGU9ImZpbGw6IzBmMTcyYTtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI0NTAiIHk9IjYyIiBzdHlsZT0iZm9udDogNzAwIDEwcHggSW50ZXIsIHNhbnMtc2VyaWY7IGxldHRlci1zcGFjaW5nOiAxLjNweDsgZmlsbDogIzY0NzQ4YjsgZmlsbDojNmVlN2I3Ij5PTiBBWlVSRTwvdGV4dD4KPHJlY3QgeD0iNDUwIiB5PSI4NCIgd2lkdGg9IjExNiIgaGVpZ2h0PSI2OCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI1MDgiIHk9IjExNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDY1MCAxMy41cHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICNmMWY1Zjk7IGZvbnQtc2l6ZToxMnB4Ij5Zb3VyIGFwcDwvdGV4dD4KPHRleHQgeD0iNTA4IiB5PSIxMzEiIHRleHQtYW5jaG9yPSJtaWRkbGUiIHN0eWxlPSJmb250OiAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjOTRhM2I4Ij5zYW1lIGNsaWVudDwvdGV4dD4KPGxpbmUgeDE9IjU2NiIgeTE9IjExOCIgeDI9IjY0MiIgeTI9IjExOCIgc3Ryb2tlLXdpZHRoPSIyIiBtYXJrZXItZW5kPSJ1cmwoI2VoMSkiIHN0eWxlPSJzdHJva2U6IzZlZTdiNyIvPgo8dGV4dCB4PSI2MDQiIHk9IjEwOSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDEwcHggJ1NGIE1vbm8nLCB1aS1tb25vc3BhY2UsICdKZXRCcmFpbnMgTW9ubycsIE1lbmxvLCBtb25vc3BhY2U7IGZpbGw6ICM5NGEzYjg7IGZvbnQtc2l6ZTo4LjVweCI+S2Fma2Egd2lyZTwvdGV4dD4KPHJlY3QgeD0iNjQ2IiB5PSI3OCIgd2lkdGg9IjE2MCIgaGVpZ2h0PSI4MCIgcng9IjExIiBzdHJva2Utd2lkdGg9IjEuNSIgc3R5bGU9ImZpbGw6IzFlMjkzYjtzdHJva2U6IzQ3NTU2OSIvPgo8dGV4dCB4PSI3MjYiIHk9Ijk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBzdHlsZT0iZm9udDogNjUwIDEzLjVweCBJbnRlciwgc2Fucy1zZXJpZjsgZmlsbDogI2YxZjVmOTsgZm9udC1zaXplOjEycHgiPkV2ZW50IEh1YnMgbmFtZXNwYWNlPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjExNSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPkthZmthIGVuZHBvaW50IDo5MDkzPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjEzMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDExcHggSW50ZXIsIHNhbnMtc2VyaWY7IGZpbGw6ICM5NGEzYjgiPmNhcGFjaXR5IHVuaXRzPC90ZXh0Pgo8dGV4dCB4PSI3MjYiIHk9IjE0NyIgdGV4dC1hbmNob3I9Im1pZGRsZSIgc3R5bGU9ImZvbnQ6IDYwMCAxMXB4IEludGVyLCBzYW5zLXNlcmlmOyBmaWxsOiAjNmVlN2I3OyBmaWxsOiM2ZWU3YjciPm5vIGFkYXB0ZXIgaW4gdGhlIHBhdGg8L3RleHQ+Cjwvc3ZnPg==)

#### Estimating namespace capacity

MSK capacity is declared as a broker count and instance type, with storage and placement per broker. Event Hubs capacity is set on a namespace using throughput units or processing units. Tensor9 estimates namespace capacity from broker count multiplied by vCPUs per broker.

Brokers with at least 16 vCPUs each, such as `kafka.m5.4xlarge`, select Premium processing units. Smaller brokers select Standard throughput units. Basic is excluded because it has no Kafka endpoint.

The build reports this conversion as a lossy translation, because machine size does not decide your workload's message throughput. Load-test the generated capacity and adjust it from measured traffic.

#### Provision topics as Event Hubs

The generated Terraform creates the namespace. It creates no Event Hubs because an MSK cluster resource does not declare topics: Kafka topics are created by producers or administrators at runtime. `aws_msk_configuration` contains `server.properties` settings, not a topic list.

Each Kafka topic needs an Event Hub in the namespace. Create them before producing messages; this backend does not create them on first use.

#### Configure authentication

Configure clients to use an Event Hubs Shared Access Signature (SAS) policy or Microsoft Entra identity. MSK's SASL/SCRAM, mutual TLS and IAM configurations do not transfer directly.

You configure namespace authentication separately from the generated stack. Credentials are kept in the Cloud Adapter deployment's secret store; the generated Terraform contains no SAS key or connection string.

Event Hubs requires TLS and encrypts stored data by default, so MSK's `encryption_info` is not translated. Configure a customer-managed encryption key separately on Azure if required.

#### Limitations

Where Event Hubs and MSK differ

* **Kafka transactions and exactly-once delivery are not fully supported.** Producing and consuming over the Kafka protocol work unchanged, but the Event Hubs Kafka endpoint does not offer full Kafka transaction and idempotent-producer behaviour. An application that relies on exactly-once delivery through Kafka transactions cannot use this backend as is.
* **Partition counts behave differently: on Standard they are fixed at creation.** On Standard, an Event Hub's partition count cannot change after creation; Premium and Dedicated can increase it but never decrease it, as Kafka does. Size partitions for the consumer parallelism you expect, because on Standard the only way to change it is a new Event Hub.
* **Capacity behaves differently: it is bought separately from partitions.** On Kafka, partitions set parallelism and much of your throughput headroom. On Event Hubs, throughput units (Standard) or processing units (Premium) are bought separately from partitions, so a partition count copied from MSK does not bring its throughput with it.
* **Consumer-group offsets behave differently: there is no `__consumer_offsets` topic.** Event Hubs keeps offsets in its own store. Committing and reading offsets through the Kafka client works as usual; tools that read the offsets topic directly, or depend on its retention and compaction, do not work here.
* **Runtime Kafka administration is only partly supported.** Topics are Event Hubs you create up front, and broker administration and ACLs differ from Kafka. Treat code that creates topics or manages ACLs through AdminClient at runtime as needing rework.
* **Pinning a Kafka version is not supported.** MSK's `kafka_version` has no counterpart: Event Hubs sets its own supported Kafka protocol version, and you cannot choose or freeze it.
* **Custom `server.properties` settings are not kept.** MSK's `configuration_info` (retention hours, default partition counts and the rest) has no namespace-level equivalent. The settings that exist are per Event Hub and are set after creation.
* **Placing brokers across availability zones is not supported.** An Event Hubs namespace is a regional service with no brokers, so MSK's per-broker subnets and zone placement have nothing to map to.

#### Other considerations

* **Update the client endpoint and authentication.** Repoint the bootstrap servers at the namespace's Kafka endpoint on port 9093 and switch the SASL configuration to a SAS policy or a Microsoft Entra identity. Produce and consume code, serializers and partitioning logic stay the same.
* **Moving from AWS: the namespace starts empty.** Messages still in MSK are not copied. Plan a cutover in which producers switch over and consumers drain the old cluster; Kafka's retention limits how long that can take.
* **Revisit capacity after launch.** The generated tier and capacity are estimated from your brokers, not measured from your traffic. Watch throughput-unit utilisation once real load arrives; Standard's throughput units and Premium's processing units are both adjustable.
* **Names stay the same across builds.** The namespace name comes from the stack's stored identity and the original cluster name, so the same stack always builds to the same namespace and a re-plan does not propose replacing infrastructure that has not changed.

## On DigitalOcean

### DigitalOcean Managed Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | broker-config tuning is more limited than a broker you administer directly; MSK's custom broker-config revision is not reproduced |
| Partition semantics | Admin | Supported | Most usage | partitions are a real Kafka broker's own |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to a real managed Kafka broker, so topic and partition admin work natively |
| ACLs / SASL auth | Auth | Partial | Full surface | DigitalOcean issues its own SASL/TLS credentials out of band; MSK's IAM auth has no analog, and broker-config tuning is more limited than a broker you administer directly |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the real broker's \_\_consumer\_offsets, as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence, and transactions are a real managed Kafka engine's own |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Partial | Most usage | the managed plan / node size is chosen out of band on DigitalOcean, not derived from the MSK broker instance type or storage volume size |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to DigitalOcean Managed Kafka over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: DigitalOcean issues its own SASL/TLS credentials out of band; MSK's IAM auth has no analog. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** DigitalOcean operates durability and HA; broker-config tuning is more limited than a broker you administer directly. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on DigitalOcean Managed Kafka, and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On Google Cloud

### Managed Service for Apache Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | Google manages the broker configuration; per-topic settings (retention, partition count) are yours to set, but MSK's custom broker-config revision has no equivalent |
| Partition semantics | Admin | Supported | Most usage | partitions are a real Kafka broker's own; create and grow them via the AdminClient as on Kafka |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to a real Apache Kafka broker, so topic, config, and partition admin all work natively |
| ACLs / SASL auth | Auth | Partial | Full surface | clients authenticate through Google Cloud IAM over SASL\_SSL/OAUTHBEARER with Google's login callback handler; MSK's IAM auth has no analog, and SASL/SCRAM credentials and mTLS client certificates have no equivalent, so producers and consumers swap their callback handler and credentials once |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the real broker's \_\_consumer\_offsets, exactly as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence, and transactions are a real Apache Kafka broker's own, because Google runs Kafka itself rather than a Kafka-compatible surface |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Partial | Most usage | Managed Kafka sizes the cluster (vCPU and memory across the whole fleet) rather than a per-broker instance type, so the source instance capacity is multiplied by broker count to estimate cluster capacity and the per-broker EBS volume becomes the managed per-broker disk |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to Google Managed Service for Apache Kafka over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: clients authenticate through Google Cloud IAM over SASL\_SSL/OAUTHBEARER; MSK IAM, SASL/SCRAM, and mTLS each need a one-time client-side handler and credential swap. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** Google operates durability and HA; capacity is cluster-wide vCPU/memory rather than a broker instance type you pick, and the cluster is reachable only inside your VPC. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on Google Managed Service for Apache Kafka, and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On OCI

### OCI Streaming

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Partial | Most usage | OCI exposes a subset of broker configuration settings; MSK's custom broker-config revision has no counterpart |
| Partition semantics | Admin | Partial | Most usage | partitions are the stream pool's, under OCI quotas |
| Topic admin (create / delete / configs) | Admin | Partial | Most usage | topics are created explicitly (auto-create is off); OCI exposes a subset of Kafka's broker configuration settings, not the full broker admin surface |
| ACLs / SASL auth | Auth | Partial | Full surface | authentication is OCI auth tokens at the stream-pool endpoint, not MSK's SASL/SCRAM, mTLS, or IAM; encryption and monitoring move to OCI-managed |
| Offset commit (\_\_consumer\_offsets) | Consume | Partial | Most usage | consumer-group offsets use OCI Streaming's managed offset store; the semantics track Kafka's with OCI's quotas |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Partial | Most usage | produce over the Kafka wire runs unchanged, but full idempotence/transactions are not complete on OCI Streaming's Kafka-compatible API, and acks and throughput are bounded by OCI's quotas rather than a broker you tune |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Partial | Most usage | the stream pool is not a broker you size; capacity is OCI's partitions and quotas, not an instance type or a volume you set |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

#### How it works

Your producers and consumers keep their Kafka clients and connect directly to OCI Streaming over the Kafka protocol. Tensor9 supplies the bootstrap endpoint; there is no Tensor9 proxy between client and broker. Broker metadata can return further advertised addresses, so clients need network access and TLS trust for those addresses as well as the bootstrap address.

Authentication changes with the broker: authentication is OCI auth tokens at the stream-pool endpoint, not MSK's SASL/SCRAM, mTLS, or IAM; your Kafka clients configure OCI's auth instead. Check producer acknowledgement, idempotence and transaction settings against the support table for this broker; a Kafka-compatible endpoint does not guarantee every Kafka administrative or transactional feature.

#### Limitations

* **Moving records, offsets and consumer-group state is not supported.** A new broker starts without the source records, offsets or consumer groups, and source offsets cannot be applied to a different log. If retained history must move, plan a separate replication process. - **You must replace AWS IAM authentication, MSK Connect and Glue Schema Registry separately.** Changing the bootstrap servers does not replace those dependencies.

#### Other considerations

**Who runs what.** Oracle operates durability and HA; partitions and retention live under OCI's quotas rather than a broker you tune directly. Topic partitions hold the retained log, and consumer-group offsets record progress.

**Before cutover.** Coordinate producer and consumer cutover. Review topic creation, retention, partition counts and broker configuration on OCI Streaming, and set up monitoring, backup or recovery and certificate rotation first.

**Performance.** It depends on the broker, storage and workload; this profile has no Tensor9 broker benchmark.

## On Scaleway

### Scaleway Clusters for Apache Kafka

| Operation | Area | Support | Depth | Notes |
| - | - | - | - | - |
| Monitoring / broker-log delivery / at-rest KMS / VPC placement | AWS control plane | Out of scope | Full surface | Configure backend monitoring and broker logs in place of MSK's CloudWatch, Prometheus, S3 and Firehose settings. Storage encryption uses the backend's key and storage configuration. Select target subnets and failure domains separately from the supplied bootstrap endpoint. |
| Broker config (custom broker-config revision) | Admin | Out of scope | Most usage | a custom MSK configuration (aws\_msk\_configuration server.properties - log.retention.hours, num.partitions and the rest) is NOT projected; tune the Scaleway cluster's topic and broker settings after it is provisioned |
| Partition semantics | Admin | Supported | Most usage | partitions are a real Kafka broker's own |
| Topic admin (create / delete / configs) | Admin | Supported | Most usage | the Kafka AdminClient talks to a real broker, so topic and partition admin work natively |
| ACLs / SASL auth | Auth | Partial | Full surface | Scaleway issues its OWN credentials for the cluster (the resource carries user\_name/password) rather than translating MSK's. A cluster whose clients use SASL/SCRAM or mTLS is reconfigured onto those credentials. A cluster whose clients use SASL/IAM is a HARDER change and is called out separately below - that one is a mechanism, not a credential |
| Offset commit (\_\_consumer\_offsets) | Consume | Supported | Most usage | offsets commit to the real broker's \_\_consumer\_offsets, as on Kafka |
| Glue Schema Registry | Ecosystem | Out of scope | Full surface | AWS Glue Schema Registry has no target-side analog; run a Kafka-native schema registry (Confluent/Apicurio) alongside the broker if you need one |
| MSK Connect | Ecosystem | Out of scope | Full surface | MSK Connect (managed Kafka Connect) is not provisioned; run Kafka Connect yourself against the broker if you need connectors |
| acks / idempotence / transactions | Producer semantics | Supported | Most usage | acks, idempotence and transactions are a real Kafka engine's own - Scaleway runs Apache Kafka 4.1, not a Kafka-compatible protocol layer |
| Broker sizing (MSK broker instance type → CPU / memory / storage) | Sizing | Partial | Most usage | the MSK broker instance type is not carried across: Scaleway sizes by its own node-type catalogue, and the build emits the smallest of the three it offers (brokernode-shared-2c-8g, 2 vCPU / 8 GB). Broker STORAGE does follow - a requested volume is rounded UP to Scaleway's 10 GB floor in 5 GB steps |
| Tiered storage | Storage | Out of scope | Full surface | MSK's tiered storage is not configured on the backend; a self-hosted Kafka broker has native tiered storage (KIP-405, production-ready in Kafka 3.9+) you can enable yourself with a remote-store backend, and the managed backends expose no equivalent knob; retention is the target broker's own local or managed storage |
| Consume (consumer groups) | Wire protocol | Supported | Common | your Kafka consumer and consumer-group membership run unchanged over the wire |
| Produce (Kafka wire) | Wire protocol | Supported | Common | your Kafka producer runs unchanged; the adapter supplies the backend's bootstrap-broker endpoint to your producer |

## Install and run

The documentation and SLAs are public. Downloading and running the Cloud Adapter binary requires an entitled customer account. Set `T9_API_KEY` as described in [Install and Authenticate](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/install-and-authenticate.md), then list the adapters your account may use with this origin:

```sh theme={null}
tensor9 adapt svc list \
  -origin aws::1.0.0::msk::kafka
```

The result is limited to directed mappings for this origin that your account is entitled to use. Use a returned backend identifier when configuring the adapter or investigating a request.

Request binary access from [hello@tensor9.com](mailto:hello@tensor9.com) if your account does not yet include this direction.

## Existing data and credentials

Selecting a backend does not copy existing data, credentials or access policies. Plan and verify migration separately before changing an application's endpoint. Do not assume an identifier, credential or encrypted value from the origin service works unchanged on the target.

## Configure, tune and debug

Start with [setup](https://docs.tensor9.com/cloud-adapter-early-access/getting-started/overview.md) and [configuration](https://docs.tensor9.com/cloud-adapter-early-access/configuration/overview.md). Use [tuning](https://docs.tensor9.com/cloud-adapter-early-access/tuning/overview.md) to understand supported request tags, [debugging](https://docs.tensor9.com/cloud-adapter-early-access/debugging/overview.md) to investigate a request, and [High Fidelity Cloud Emulators](https://docs.tensor9.com/cloud-adapter-early-access/local-testing/overview.md) to validate a bounded reproduction.

For requests that go through an entitled service adapter, use [tensor9 explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/explain.md) and [x-t9-explain](https://docs.tensor9.com/cloud-adapter-early-access/debugging/response-headers.md) to inspect the selected mapping.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.