# Kafka proxy and governance Source: https://docs.conduktor.io/gateway Conduktor Gateway is a transparent Kafka proxy that enforces encryption, governance policies, traffic control, data masking, and multi-tenancy. Conduktor Gateway is a network proxy for Apache Kafka, complete with an extensible and dynamic plugin mechanism that can be used to add technical and business logic on top of your existing Kafka deployment. **Learn more:** [Conduktor Gateway](https://www.conduktor.io/gateway) The product overview: what Gateway does and the problems it solves. ## Gateway benefits This can be used to provide functionality that is not available in Kafka natively, such as: * **Centrally configure encryption** at the field-level or full payload. * **Mask sensitive data** at the proxy layer. * **Enforce governance and traffic control policies** — rate limits, data quality rules, topic creation constraints. * **Leverage multi-tenancy** with Virtual Clusters and topic concentration. * **Empower development teams** with self-service governance. Supports all Kafka providers (Confluent, AWS MSK, Redpanda, Aiven, Apache Kafka). Gateway is one of the main [Conduktor components](/guide/conduktor-in-production/deploy-artifacts) and together with [Console](/guide/conduktor-in-production/deploy-artifacts/deploy-console) make up the Conduktor platform: Conduktor overview ## How it works Gateway acts as a Kafka-compliant middle layer between clients and Kafka clusters. Conduktor Gateway ### Authentication Supports multiple security protocols: * PLAINTEXT * SSL * SASL SSL * mTLS ### Interceptors Use Interceptors to add logic like encryption or filtering. [Find out about Interceptors](/guide/conduktor-concepts/interceptors). ## Related resources * [Deploy Gateway](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway) * [Gateway resource reference](/guide/reference/gateway-reference) * [Gateway API](https://developers.conduktor.io/?product=gateway) * [Give us feedback/request a feature](https://conduktor.io/roadmap) * [Arrange a technical demo](https://www.conduktor.io/contact/demo) # Kafka cost allocation and chargeback Source: https://docs.conduktor.io/guide/conduktor-concepts/chargeback Track and allocate Kafka costs to teams with Conduktor Chargeback. Measure storage, partitions, ingress and egress per cluster, application or label. Chargeback is a cost allocation feature that helps you track, visualize and attribute Kafka infrastructure costs to clusters, teams or applications. By measuring resource use over time, Chargeback gives you visibility into Kafka spending, supports cost accountability and helps you make informed decisions about resource optimization. Conduktor measures five cost axes — **storage**, **partitions**, **ingress**, **egress** and **Kafka Connect** — and presents costs through three views: by cluster, by application or by label. From Console v1.45.0, Chargeback unifies the previous **with Gateway** and **without Gateway** experiences into a single page. The previous V1 and V2 endpoints are deprecated but still respond to existing API clients. **From our blog:** [Chargeback: attribute and map Kafka costs to your business](https://conduktor.io/blog/chargeback-attribute-map-kafka-costs-to-your-business) Practical strategies to tag, trace, and report Kafka spending by team and application. ## Cost axes Each cluster has its own configurable unit costs across five axes. Set the costs that match your provider pricing or your internal infrastructure model. | Cost axis | Unit | What it measures | | ----------------- | ----------------- | -------------------------------------------- | | **Storage** | \$/GB/hour | Bytes retained on disk per topic | | **Partitions** | \$/partition/hour | Number of partitions per topic | | **Ingress** | \$/GB | Bytes produced into Kafka | | **Egress** | \$/GB | Bytes consumed from Kafka | | **Kafka Connect** | \$/task/hour | Hours that Kafka Connect connector tasks run | A cluster only needs the axes that match its pricing model. For an on-premises cluster, you might only set storage and partitions; for a Confluent Cloud cluster, you can set all five. Kafka Connect costs use a default per-task-hour rate for the cluster. You can also set per-connector-class overrides — for example, a higher rate for an S3 sink connector than for a JDBC source connector. Costs are calculated at query time, so updating a unit cost takes effect immediately across historical data. ## What you can measure per cluster type Chargeback collects metrics from four sources: Console's metadata indexer for storage and partition counts, the Confluent Cloud Metrics API for Confluent Cloud throughput, the observability Interceptor for Gateway throughput, and Console's Kafka Connect integration for connector task hours. | Cluster type | Storage | Partitions | Ingress / egress per topic | Ingress / egress per service account | Kafka Connect | | --------------- | :-----: | :--------: | :------------------------: | :----------------------------------: | :-----------: | | Vanilla Kafka | ✓ | ✓ | – | – | ✓ | | Confluent Cloud | ✓ | ✓ | ✓ | ✓ (no topic breakdown) | ✓ | | Gateway | ✓ | ✓ | ✓ | ✓ | ✓ | Kafka Connect costs apply to any cluster type, but only when the cluster has one or more Kafka Connect clusters configured in Console. Clusters without Kafka Connect don't show Connect costs. Storage and partition metrics are bucketed by UTC day. Confluent Cloud throughput is collected hourly. Gateway throughput is streamed continuously through the observability Interceptor and flushed at a configurable interval. ## Views Chargeback presents data through three top-level views, each with the same cost columns and the ability to drill down into topics, service accounts and connectors. * **Cluster view**: costs grouped by Kafka cluster * **Application view**: costs grouped by application, with drill-down into application instances * **Label view**: costs grouped by the values of a label key (for example, `env=production` or `team=payments`) Label-based grouping requires the label key to first be selected as a Chargeback Label by an administrator. ## Chargeback Labels Not every label attached to a topic or service account is meaningful for cost attribution. Administrators select a subset of label keys to expose in Chargeback. Once a label key is enabled, you can group costs by its values. Topics or service accounts without that label are excluded from the grouping. Chargeback Labels are global — the same set of label keys applies across all clusters. ## Permissions Access to Chargeback comes at two levels: platform-wide and per application. ### Platform-wide access Two platform-level permissions grant access to every application's costs: * **Can view Chargeback** (`PlatformChargebackView`): view cost metrics across all views and drill-downs * **Can manage Chargeback** (`PlatformChargebackManage`): set per-cluster unit costs and select Chargeback Labels By default, platform admins have both permissions. Console shows cost attribution for all clusters regardless of the cluster-level permissions assigned to the user. ### Per-application access Application owners can see the costs of their own applications without platform-wide access. Assign the `applicationInstanceChargebackView` instance permission through an [ApplicationGroup](/guide/reference/self-service-reference#instance-permissions-reference) — Chargeback then appears for those members, scoped to the applications they hold the permission on. This permission isn't granted by default, including to groups with full access on their application instances. Assign it explicitly to opt an application into cost visibility. Because application teams manage their own ApplicationGroups, a team can assign this permission to itself. To keep cost data centralized, platform teams can block it with a ResourcePolicy — see [keeping Chargeback data centralized](/guide/reference/self-service-reference#keeping-chargeback-data-centralized). ## Related resources * [Use Chargeback](/guide/use-cases/chargeback) * [Configure Chargeback](/guide/tutorials/configure-chargeback) * [Give us feedback/request a feature](https://conduktor.io/roadmap) # Kafka data products and governance Source: https://docs.conduktor.io/guide/conduktor-concepts/data-products Build governed Kafka data products with Conduktor: combine self-service ownership, schema enforcement, topic policies, and resource metadata. ## Overview Conduktor allows you to effectively *create* data products by combining multiple features and functionality. **From our blog:** [Stop calling your Kafka topics data products](https://conduktor.io/blog/kafka-data-products) Why a raw topic is shared mutable state, and what it takes to wrap one into a real data product. ## Ownership and governance [Self-service](/guide/conduktor-concepts/self-service) provides the foundation: * Applications define ownership and business context * Application Instances manage resources (topics, consumer groups, subjects) across environments * Topic policies enforce configuration standards (retention, partitions) * Resource labels add business metadata (data-criticality, descriptions, documentation URLs) ## Discovery Topic Catalog and Application Catalog enable discovery: * Search topics by name, labels or owning application * View topic metadata and business context * Find applications and their owned resources * Request access to topics owned by other teams ## Quality and validation [Data quality policies](/guide/conduktor-concepts/data-quality-policies) ensure data meets standards: * CEL (Common Expression Language) expression rules for business logic validation * JSON schema validation * Built-in rules (for example, EnforceAvro for schema registry integration) * Policy violations are tracked and can block or mark non-compliant data ## Access control and sharing Control who can access your data products: * Application Instance Permissions enable controlled sharing between internal teams * [Partner Zones](/guide/conduktor-concepts/partner-zones) enable secure external data sharing with third parties * Service accounts and ACLs (Access Control Lists) enforce access at the Kafka level * RBAC (Role-Based Access Control) in Console controls who can manage resources ## Related resources * [Use Self-service](/guide/use-cases/self-service) * [Share data externally](/guide/use-cases/third-party-data) * [Enforce data quality](/guide/use-cases/enforce-data-quality) # Kafka data quality — validation rules and policies Source: https://docs.conduktor.io/guide/conduktor-concepts/data-quality-policies Define Kafka data quality rules using CEL expressions or JSON Schema. Attach policies to topics to observe violations or enforce blocking with Conduktor. Conduktor helps you detect and enforce data quality standards for messages flowing through Kafka. ## How it works You create **Rules** that define the expected format and content of messages, then attach them to **Policies** that target specific Kafka topics or topic prefixes. Conduktor evaluates these Rules against every message produced on targeted topics after Policy creation and tracks the count of violating messages as well as the total number of messages evaluated. ## Observe vs enforce The capabilities depend on whether you're using Gateway: **Without Gateway (observe only)** * Records are verified **after** they have been produced * Track violations and monitor data quality issues * No impact on message flow **With Gateway (observe and enforce)** * Records are verified **before** production * See which service accounts produced the faulty records * Take action on faulty records: * **Block**: reject the message (and the entire record batch). The producer receives a non-retriable error. [Find out about handling blocked batches](/guide/conduktor-in-production/admin/gateway-policies#handle-blocked-batches) * **Mark**: add a header to the record containing all violated rules for every Policy using the mark action * Prevent bad data from entering your topics ### Key constraints * Policies cannot mix different target cluster types (Gateway vs. non-Gateway) * You can't target a Gateway-backing cluster directly to avoid validation conflicts **From our blog:** [Kafka data contracts: a schema is not a contract](https://conduktor.io/blog/kafka-data-contracts) Why a schema alone won't stop a producer from breaking consumers, and where to enforce the contract. ## Data quality metrics The quality overview dashboard provides a summary of your data quality governance across the entire ecosystem. Use it to: * **Track progress**: monitor how many topics are protected by Policies * **Identify gaps**: find high-volume topics without coverage * **Measure health**: see which producers need attention and how well your Policies are performing. The health score is calculated based on the number of topics that have Policies assigned, with a modifier that determines how effectively they're enforced (for example, whether violations are blocked). * **Take action**: click through to add topics to Policies or investigate violations In Console, access the overview by going to **Trust > Data quality overview**. You can export all data quality metrics to CSV for offline analysis or reporting. Data Quality Overview To see metrics, you need to have at least one topic with a Policy assigned to it. ### Coverage The coverage metrics show how many topics are protected by Policies. * **Topics with at least one Policy**: percentage of topics with Policy coverage * **Topics with multiple Policies**: percentage of topics with layered validation * **VIP topics at risk**: highly utilized topics with no Policy coverage that should be prioritized. VIP topics are those with activity within the last 24 hours, containing over 500 messages or topics that have more than 3 consumers. Higher coverage means more of your data is being validated. Aim for 100% coverage of VIP topics first. To take action and add a Policy to a topic at risk, click **Add to Policy** next to the topic name and select an existing Policy. Metrics are updated every 5 minutes by default and changes may not be reflected immediately. ### Health The health metrics show how effectively your Rules are being enforced. * **Health score**: overall data quality based on coverage and enforcement * **Action distribution**: breakdown of no action, mark and block actions over time * **Top violating producers**: producers with the highest violation rates to help prioritize remediation Mark and block actions and producer identification require Gateway. Without Gateway, violations are reported but not enforced and you will not see information about the producer of violations on non-Gateway topics. ## Related resources * [Observe data quality](/guide/use-cases/observe-data-quality) * [Enforce data quality](/guide/use-cases/enforce-data-quality) * [Give us feedback/request a feature](https://conduktor.io/roadmap) # Gateway authentication and authorization Source: https://docs.conduktor.io/guide/conduktor-concepts/gateway-authentication-authorization Configure Kafka client authentication in Conduktor Gateway: Gateway-managed mode with local service accounts and Kafka-managed mode with delegated auth. Conduktor Gateway provides flexible authentication and authorization for Kafka clients, allowing you to choose where and how clients are authenticated and what permissions they have. ## Two authentication modes Gateway offers two distinct modes for managing client authentication and authorization: **Gateway-managed mode** * Gateway handles all authentication and authorization * Service accounts and ACLs defined in Gateway * Supports both local and external service accounts * Local service accounts authenticate with `PLAIN` (token) or, with the service accounts feature flag enabled, `SCRAM-SHA-512` / `SCRAM-SHA-256` credentials managed by Gateway * Full control over client access without touching Kafka configuration * Enables Virtual Clusters and other Gateway-specific features * Enables efficient connection pooling ([`GATEWAY_UPSTREAM_CONNECTION_POOL_TYPE=ROUND_ROBIN`](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables)) to multiplex client connections onto a small pool of connections per broker, cutting connection overhead on Kafka as the number of clients grows **Kafka-managed mode** * Authentication and authorization delegated to the backing Kafka cluster * Existing Kafka service accounts and ACLs continue to work * Useful for gradual migration to Gateway * External service accounts can still be mapped for friendly names in Gateway * Virtual resources (Virtual Clusters, alias topics) not available * Connection pooling not available (each client authenticates on its own connection) ## Key decisions When configuring Gateway authentication, you need to decide: * **Where to authenticate**: at Gateway or delegate to Kafka * **Authentication method**: SASL (PLAIN, SCRAM, OAUTHBEARER), mTLS, or anonymous * **Service account type**: local (Gateway-managed) or external (identity provider) * **Authorization location**: Gateway ACLs or Kafka ACLs ## Benefits * **Gradual adoption**: start with Kafka-managed mode and migrate to Gateway-managed * **Unified access control**: manage authentication across multiple clusters from one place * **Flexible identity integration**: work with existing identity providers or use Gateway's built-in authentication * **Enhanced security**: add Gateway policies and Interceptors without changing Kafka security ## Related resources * [View supported authentication methods table](/guide/reference/gateway-reference#supported-authentication-methods) * [Gateway service accounts](/guide/conduktor-concepts/gateway-service-accounts) * [Manage service accounts using Gateway](/guide/tutorials/manage-gateway-service-accounts) * [Manage service accounts and ACLs using Console](/guide/manage-kafka/kafka-resources/service-accounts-acls) * [Give us feedback/request a feature](https://conduktor.io/roadmap) # Gateway service accounts Source: https://docs.conduktor.io/guide/conduktor-concepts/gateway-service-accounts Manage Kafka client identities in Conduktor Gateway. Use local service accounts for isolated access or external accounts from OIDC, mTLS. Gateway service accounts are identities used to authenticate clients connecting to Conduktor Gateway. ## Two types of service accounts Gateway supports two types of service accounts, each suited for different use cases: **Local service accounts** * Created and managed entirely within Gateway using the admin API * No external identity provider required * Gateway generates credentials with configurable time-to-live * Can also hold long-lived SCRAM credentials for `SCRAM-SHA-512` / `SCRAM-SHA-256` authentication when the service accounts feature flag is enabled * Ideal for sharing data with external partners without managing a separate identity provider * Only available in Gateway-managed authentication mode **External service accounts** * Managed by external identity providers (OIDC, mTLS certificates) * Can be mapped to friendly names in Gateway for better readability * Original identity from provider (like Azure UUID) is preserved but aliased * Used when integrating with existing enterprise identity systems * Works in both Gateway-managed and Kafka-managed modes * In Kafka-managed mode, external service accounts can rename identities and be referenced in Interceptors ## Benefits * **Flexible identity management**: choose between self-managed or provider-managed identities * **Simplified access control**: apply ACLs and Interceptors using friendly names * **Audit trail**: all service account activity logged in Gateway audit logs * **Virtual Cluster association**: link service accounts to specific Virtual Clusters for multi-tenancy ## Related resources * [View Gateway service account reference](/guide/reference/gateway-reference#gatewayserviceaccount) * [Manage service accounts and ACLs using Console](/guide/manage-kafka/kafka-resources/service-accounts-acls) * [Manage service accounts using Gateway](/guide/tutorials/manage-gateway-service-accounts) * [Gateway authentication and authorization](/guide/conduktor-concepts/gateway-authentication-authorization) * [Give us feedback/request a feature](https://conduktor.io/roadmap) # Indexing Source: https://docs.conduktor.io/guide/conduktor-concepts/indexing Console Indexing collects Kafka metadata every 30 seconds into internal tables for topic sorting, filtering, and labelling. In Console, many of the list pages (e.g. Topics, Consumer Groups, Schema Registry, Kafka Connect) are served from an **internal table** instead of making *AdminClient* calls to Kafka. These tables are updated by a background process we call Indexing. The Indexing process collects changes to your Kafka every 30 seconds and stores that metadata in internal tables. Indexing explained Detail pages are not using Indexing. As soon as you're on a page for a specific topic or consumer group, the data is fetched directly from the Kafka cluster. ## Benefits Indexing improves user experience and provides functionality that's not available with out-of-the-box Kafka resources, such as: * smart tables with **sorting and filtering** capabilities, allowing you to get message count, size and much more * **search** and **labelling** that allows you to organize and find required resources ## Examples These are just some examples of how Indexing can help you: * identify **idle topics**: which topics (that have no active consumers and producers) haven't published data for more than a week? * are there any **over-partitioned topics** - topics that have a large number of partitions while the biggest consumer group only has a few members consuming in parallel? * prioritize **data at risk topics**: which topics are at risk of losing data, because of the replication factor or the min ISR being incorrect? * find **outliers topics**: which topics contain bad or overridden configurations that they shouldn't have? * remove **over-replicated applications**: which consumer groups have idle members? Typically, this is because the number of consumers exceeded the number of total partitions. ## Circuit breaker configuration Each indexed task in Console includes configurable circuit breaker behavior that provides fine-grained control over indexing resilience and recovery. This configuration helps prevent prolonged indexing outages and gives administrators better control over system behavior. ### Configuration parameters **`sequentialFailureThreshold`** * Controls how many consecutive failures have to occur before the circuit breaker activates * When the threshold is reached, the indexing task will temporarily stop attempting to collect data * Prevents resource exhaustion during extended connectivity or permissions issues **`blockingDuration`** * Defines how long the circuit breaker remains active before attempting to resume indexing * Provides a controlled recovery mechanism with predictable timing * Ensures predictable recovery intervals for indexing operations ### Benefits With these circuit breaker settings, you can: * Adjust failure detection sensitivity based on your environment's reliability * Control recovery timing to balance system stability with data freshness * Maintain predictable indexing behavior even during temporary infrastructure issues * Prevent resource exhaustion during extended connectivity problems Circuit breaker configuration is applied per indexed tasks (e.g., topic metadata polling, consumer group indexing). For guidance on optimal settings for your specific deployment scenario, [contact support](https://support.conduktor.io/hc/en-gb/requests/new) . ## Troubleshoot Topics created 'now' would not be indexed until the next Indexing cycle. This means they wouldn't appear in Console for up to 30 seconds. To mitigate this, we've come up with a counter-measure: any user request to the topic list will ALWAYS make one *AdminClient* call to Kafka: `listTopics`. It’s cheap, simple and will only return the topic names. So, when topics are listed in Console, 99% of the time Indexing will serve all the topics with all the columns (name, partitions, count, size, etc.) and 1% of the time Indexing will serve most topics except for one or two **not-indexed yet** where only the name will be available. # Kafka interceptors — Gateway plugins for security and governance Source: https://docs.conduktor.io/guide/conduktor-concepts/interceptors Conduktor Gateway interceptors enforce Kafka encryption, data quality, access control, and traffic control without changing client code. Interceptors are Gateway plugins that intercept and modify Kafka requests and responses in real time. They help enforce policies, protect data, and add functionality without changing your applications or Kafka configuration. **Learn more:** [Conduktor Gateway](https://www.conduktor.io/gateway) How Gateway and its Interceptors add encryption, governance, and traffic control to Kafka. ## What Interceptors do Interceptors can: * Encrypt and decrypt message fields or entire payloads * Block or skip records that don't meet data quality rules * Enforce producer settings like acks or compression * Control topic creation parameters like replication factor or partition count * Transform message content or headers ## How they work Each Interceptor has a `priority` field — a number where lowest runs first. The same numeric order applies on both produce and consume; ordering doesn't reverse between directions. Priorities are typically spaced apart (for example, `100`, `200`, `300`) so you can insert Interceptors between existing ones without renumbering. Interceptors fire on different paths depending on what they do: * **Produce-only** — for example, `EncryptPlugin` runs as records flow from client to broker. * **Consume-only** — for example, `DecryptPlugin` runs as records flow from broker to client. * **Both paths** — for example, `LargeMessageHandlingPlugin` runs as records flow from client to broker and broker to client. For example, an `EncryptPlugin`, `LargeMessageHandlingPlugin`, and `DecryptPlugin` configured on the same topic share one priority order across both paths: ```yaml theme={null} # Priority 100: encrypt on produce apiVersion: gateway/v2 kind: Interceptor metadata: name: myEncryptPlugin scope: vCluster: passthrough spec: pluginClass: io.conduktor.gateway.interceptor.EncryptPlugin priority: 100 config: topic: "topic.*" kmsConfig: vault: uri: http://vault:8200 token: ${VAULT_TOKEN} recordValue: payload: keySecretId: vault-kms://vault:8200/transit/keys/payload-key algorithm: AES128_GCM --- # Priority 200: offload large messages to cloud storage apiVersion: gateway/v2 kind: Interceptor metadata: name: myLargeMessageHandlingPlugin scope: vCluster: passthrough spec: pluginClass: io.conduktor.gateway.interceptor.LargeMessageHandlingPlugin priority: 200 config: topic: "topic.*" minimumSizeInBytes: 1024 localDiskDirectory: myStorage/ s3Config: bucketName: myBucketName uri: http://myexampleuri region: us-east-1 --- # Priority 300: decrypt on consume apiVersion: gateway/v2 kind: Interceptor metadata: name: myDecryptPlugin scope: vCluster: passthrough spec: pluginClass: io.conduktor.gateway.interceptor.DecryptPlugin priority: 300 config: topic: "topic.*" kmsConfig: vault: uri: http://vault:8200 token: ${VAULT_TOKEN} ``` For why this ordering matters when offloading encrypted records to cloud storage, see [Combine with encryption](/guide/use-cases/manage-large-messages#combine-with-encryption). Interceptors can also be: * **Scoped** — apply to specific service accounts, groups or Virtual Clusters * **Overridden** — more specific scopes take precedence over broader ones Gateway applies Interceptors dynamically based on which client connects, so different teams can have different policies without separate clusters. ## Related resources * [Interceptor reference](/guide/reference/interceptor-reference) * [Configure data quality policies](/guide/use-cases/enforce-data-quality) * [Apply traffic control policies](/guide/use-cases/apply-traffic-control-policies) # Logical topics Source: https://docs.conduktor.io/guide/conduktor-concepts/logical-topics Create logical Kafka topics in Conduktor Gateway: alias topics for renaming, concentrated topics to reduce partition costs, and SQL or CEL filter topics. Conduktor logical topics are abstractions of real Kafka topics that provide additional functionality that's not available by default. We offer the following types of logical topics: 1. [Alias topics](#alias-topics) are topics that can be accessed with a name (alias), but point to another, *real* topic behind the scenes. Alias topics can be very useful when you want to share topics but have sensitive naming conventions; or in scenarios where underlying topics might be frequently renamed. 2. [Concentrated topics](#concentrated-topics) transparently co-locate multiple topics in the same physical topic behind the scenes, acting as pointers to reduce costs on low-volume topics with large partition counts. They are completely transparent to consumers and producers and allow you to emulate different partition counts irrespective of the backing physical topic's partition count. 3. [Topic views](#topic-views) filter records from physical topics using SQL WHERE clauses. This is the recommended approach for filtering JSON data. 4. [SQL topics](#sql-topics) **DEPRECATED** use SQL language to query and filter an existing topic. 5. [CEL topics](#filter-topics-with-cel) **DEPRECATED** another way to filter an existing topic using CEL expressions instead of SQL. ## Alias topics Alias topics act as pointers that target a specific physical topic, defined with the [AliasTopic resource](/guide/reference/gateway-reference#aliastopic). One of Kafka's limitations is that you can't rename topics - an issue that is solved with alias topics. You can have a number of alias topics pointing to the same physical topic. ### Use Gateway manages an alias topic mapping in its internal configuration by registering a target physical topic. This topic will be presented to Kafka clients like a regular topic. However, all requests for this topic will be forwarded to the physical topic. This means that consumer groups, fetch and produce are shared. Also, the alias topic does not replace the original one. For example, if you create an alias topic `applicationB_orders` that's pointing to a physical topic `orders`, a client that can access the physical topic would be able to see both topics. ### Limitations * ACLs using delegated Kafka security SASL delegated security protocols aren't supported. * Alias topics can't reference another alias topic. ## Concentrated topics Occasionally, topics have to be created for logical, rather than technical reasons (e.g. to differentiate between business units) which can result in considerable overuse of Kafka resources. Conduktor's topic concentration allows data from a set of topics to be represented on a single underlying topic. Clients connecting through Conduktor Gateway can use concentrated topics as usual without any additional configuration. For example, let's say we have the following topics: * us\_east\_orders - 100 partitions * us\_west\_orders - 100 partitions * emea\_orders - 100 partitions * latam\_orders - 100 partitions The total Kafka resource requirement is 400 partitions. With topic concentration, all of these topics can be concentrated to a single topic, using only 1/4 of resources: * concentrated\_orders - 100 partitions ### Configuration Configure concentrated topics with a `ConcentrationRule`. For all available fields, see the [ConcentrationRule resource reference](/guide/reference/gateway-reference#concentrationrule). To create concentrated topics, first deploy `ConcentrationRule`: ```yaml theme={null} --- kind: ConcentrationRule metadata: name: concentration1 spec: pattern: concentrated.* physicalTopics: delete: physical.topic ``` Then topics that match the *ConcentrationRule* `spec.pattern`: ```bash theme={null} kafka-topics \ --bootstrap-server conduktor-gateway:6969 \ --topic concentrated.topicA \ --partitions 3 kafka-topics \ --bootstrap-server conduktor-gateway:6969 \ --topic concentrated.topicB \ --partitions 4 ``` Topic Concentration We now have two concentrated topics (`concentrated.topicA` and `concentrated.topicB`) with partition counts of 3 and 4 respectively, mapped to a single physical topic (`physical.topic`) with three partitions. To ensure that consumers don't consume messages from other partitions or from other concentrated topics, we store the concentrated partition and the concentrated topic name in the record headers. Gateway will automatically filter the messages that should be returned to the consumer. ```bash theme={null} curl -X PUT "http://conduktor-gateway:8888/gateway/v2/concentration-rule" \ -H "Content-Type: application/json" \ -u "admin:conduktor" \ -d '{ "kind": "ConcentrationRule", "apiVersion": "gateway/v2", "metadata": { "name": "concentration1" }, "spec": { "pattern": "concentrated.*", "physicalTopics": { "delete": "physical.topic" } } }' ``` ### Limitations #### Consumer offsets When consuming from a concentrated topic, messages and ordering is always preserved but any metadata calculations (primarily lag and message count) are unlikely to be as expected. This is because the associated metadata is from the backing Kafka topic, rather than the concentrated topic seen from the perspective of the consumer. This is a known limitation. #### Compact and delete+compact topics You can create concentrated topics with any *cleanup.policy*, but your `ConcentrationRule` has to have a backing topic for each of them, otherwise it won't let you create the topic. ```yaml theme={null} --- kind: ConcentrationRule metadata: name: concentration1 spec: pattern: concentrated.* physicalTopics: delete: physical.topic-delete compact: physical.topic-compact # deleteCompact: physical.topic-deletecompact ``` In this example, since the config for `spec.deleteCompact` is commented out, trying to create this topic will fail: ```bash theme={null} kafka-topics --create --bootstrap-server conduktor-gateway:6969 \ --topic \ --partitions 3 \ --config cleanup.policy=compact,delete Error while executing topic command : Cleanup Policy is invalid ``` Backing topic cleanup policies are checked when you deploy a new `ConcentrationRule`. This prevents you from declaring a backing topic with a *cleanup.policy* of delete on the *ConcentrationRule* `spec.physicalTopic.compact` field. #### Restricted topic configurations The following list of topic properties are the only allowed properties for concentrated topics: * `partitions` * `cleanup.policy` * `retention.ms` * `retention.bytes` * `delete.retention.ms` If any other configuration than the above is set, the topic creation will fail with an error. `retention.ms` and `retention.bytes` can be set to values lower or equal to the backing topic. If a user tries to create a topic with a higher value, topic creation will fail with an error: ``` kafka-topics --create --bootstrap-server conduktor-gateway:6969 \ --topic \ --partitions 3 \ --config retention.ms=704800000 Error while executing topic command : Value '704800000' for configuration 'retention.ms' is incompatible with physical topic value '604800000'. ``` This behavior can be altered with the flag `spec.autoManaged`. With concentrated topics, the enforced retention policy is the physical topic's retention policy, and not the policy requested at the concentrated topic creation time. The `retention.ms` and `retention.bytes` are not cleanup but retention guarantees. #### Auto-managed backing topics When `autoManaged` is enabled: * backing topics are automatically created with the default cluster configuration and partition count. * concentrated topics created with higher `retention.ms` and `retention.bytes` are allowed. This automatically extends the configuration of the backing topic. ```yaml theme={null} --- kind: ConcentrationRule metadata: name: concentration1 spec: pattern: concentrated.* physicalTopics: delete: physical.topic autoManaged: true ``` Let's check the backing topic retention on the physical cluster: ```bash theme={null} kafka-configs --bootstrap-server kafka:9092 \ --entity-type topics --entity-name physical.topic \ --describe Configs for topic 'physical.topic' are: cleanup.policy=delete retention.ms=604800000 retention.bytes=-1 ``` Let's try to create a concentrated topic with a higher retention on Gateway: ```bash theme={null} kafka-topics --create --bootstrap-server conduktor-gateway:6969 \ --topic \ --partitions 3 \ --config retention.ms=704800000 ``` Let's review the backing topic again: ```bash theme={null} kafka-configs --bootstrap-server kafka:9092 \ --entity-type topics --entity-name physical.topic \ --describe Configs for topic 'physical.topic' are: cleanup.policy=delete retention.ms=704800000 retention.bytes=-1 ``` As we can see, the retention has been updated. If one user requests a topic with infinite retention (`retention.ms = -1`), **all the topics** with the same cleanup policy associated with the rule **will also inherit** this extended configuration and have infinite retention. #### Message count, lag and offset (in)correctness By default, concentrated topic reports the offsets of their backing topics. This impacts the calculations of **Lag** and **Message Count** that relies on partition **EndOffset** and group **CommittedOffset**. Offset Incorrectness Any tooling will currently display the message count, and the lag relative to the `EndOffset` of the physical topic. This can create confusion for customers and applications that will see incorrect metrics. Gateway has an `offsetCorrectness` setting on `ConcentrationRule` that makes concentrated topics report virtual offsets, so that lag and message count read correctly. It is deprecated, and we don't recommend enabling it. `spec.offsetCorrectness` is deprecated as of v3.21.0 and is planned for removal in v3.24.0. Existing rules keep working, but Gateway now logs a single deprecation warning at startup listing the affected concentrated topics. Because of the limitations listed below, treat the physical-topic offsets described above as the supported behavior. If you already have it enabled, the setting looks like this: ```yaml theme={null} --- kind: ConcentrationRule metadata: name: concentration1 spec: pattern: concentrated.* physicalTopics: delete: physical.topic offsetCorrectness: true ``` * `spec.offsetCorrectness` only applies to concentrated topics with the `cleanup.policy=delete` * `spec.offsetCorrectness` is not retroactive on previously created concentrated topics #### Stop using offset correction If you have `offsetCorrectness` enabled in production, [get in touch for support with this migration](https://support.conduktor.io/hc/en-gb/requests/new?ticket_form_id=17438363566609). #### Known issues with offset correctness There are three known issues with the offset correctness in concentrated topics: **1. Performance** On startup, Gateway has to read the concentrated topic entirely before it's available to consumers. The end-to-end latency is increased by up to 500 ms (or `fetch.max.wait.ms`, if non-default). **2. Memory** Gateway consumes about \~250MB of heap memory per million records it's read in concentrated topics. This value is not bound, so we don't recommend offset correctness on high-volume topics, and recommend to size your JVM accordingly. **3. Unsupported Kafka API** * `DeleteRecords` is not supported * Transactions are not supported * Only `IsolationLevel.READ_UNCOMMITTED` is supported (using `IsolationLevel.READ_COMMITTED` is undefined behavior) * Partition truncation (upon `unclean.leader.election=true`) may not be detected by consumers **Very slow consumer group edge case** Do not enable offset correctness when your topic has extended periods of inactivity. When using topic concentration with `offsetCorrectness` enabled, there's currently a limitation for consumer groups where the data in the topics is slow moving, and/or the consumer groups are not committing their offsets frequently. If a consumer group with a committed offset waits for the backing physical topic longer than the retention time (without committing a new offset), there's a possibility for that consumer group to become blocked. In this scenario, a consumer group whose last committed offset has been removed from the topic, the group becomes blocked only if Gateway restarted before the next offset commit. If this limitation happens, the offsets for the affected consumer group will need to be manually reset for it to continue. ## Topic views Topic views provide non-materialized views of physical Kafka topics, similar to database views. They apply transformations to records as they're consumed, without modifying the underlying data. Topic views support SQL-based filtering and projection on schema-less JSON, and SQL-based filtering on Avro, Protobuf and JSON-Schema records read through a [schema registry connection](#read-schema-encoded-topics). Support for additional transformations, for example CEL, is planned. See a topic view give one team a filtered, projected read of a topic: