Pulsar’s multi-tenancy isn’t just about grouping topics; it’s about fundamentally isolating resources to prevent noisy neighbors and enforce strict access control across your entire messaging infrastructure.
Let’s see it in action. Imagine we have two distinct teams, "marketing" and "engineering," and we want to ensure their messaging traffic and configurations are completely separate.
# Create the 'marketing' tenant
kubectl exec -it pulsar-admin-xxxxxxxxxx -- bin/pulsar-admin tenants create marketing \
--admin-roles admin_marketing \
--allowed-domains marketing.example.com
# Create a namespace for marketing's campaigns
kubectl exec -it pulsar-admin-xxxxxxxxxx -- bin/pulsar-admin namespaces create marketing/campaigns \
--replication-clusters us-west1 \
--backlog-quota 10G \
--message-ttl 7d
# Create the 'engineering' tenant
kubectl exec -it pulsar-admin-xxxxxxxxxx -- bin/pulsar-admin tenants create engineering \
--admin-roles admin_engineering \
--allowed-domains engineering.example.com
# Create a namespace for engineering's services
kubectl exec -it pulsar-admin-xxxxxxxxxx -- bin/pulsar-admin namespaces create engineering/services \
--replication-clusters us-east1 \
--backlog-quota 5G \
--message-ttl 24h
Here, pulsar-admin is our primary tool for managing these multi-tenancy constructs. A tenant is the highest level of isolation, representing an organization or a major department. It has its own set of administrators and can be restricted by allowed domains for authentication. Within a tenant, we have namespaces. Namespaces provide a logical grouping of topics and are where most of the resource isolation and policy enforcement happens.
When you create a namespace like marketing/campaigns, you’re defining:
- Replication Clusters:
us-west1means topics in this namespace will be replicated across brokers in theus-west1cluster. This is crucial for availability and disaster recovery. - Backlog Quota:
10Gsets a hard limit on how much unacknowledged message data can accumulate for any topic within this namespace. If this limit is hit, new messages will be rejected until consumers catch up. This prevents a single runaway producer from consuming all disk space. - Message TTL:
7d(7 days) automatically deletes messages older than a week, managing storage and preventing infinite growth of topic data.
This separation means that if the "marketing" team suddenly experiences a massive surge in campaign events, their marketing/campaigns namespace will enforce its 10G backlog quota, potentially rejecting new messages for them, but it won’t impact the "engineering" team’s engineering/services namespace, which has its own independent quota of 5G. Similarly, the message TTL for marketing’s campaigns is distinct from engineering’s services.
The isolation extends to authentication and authorization. By assigning --admin-roles to tenants, you delegate administrative control over that tenant’s resources. When clients connect, they specify their tenant and namespace, and Pulsar uses this information, often in conjunction with configured authentication providers (like Kerberos or JWT), to determine if they have permission to publish or subscribe to topics within that specific isolation boundary.
The most surprising thing about Pulsar’s multi-tenancy is that it actually enforces isolation at the storage layer per namespace, not just at the broker level. Each namespace is configured with its own BookKeeper ledger allocation and retention policies independent of other namespaces, even within the same tenant or cluster. This means a heavy write load on one namespace won’t directly contend for BookKeeper’s underlying journal or disk IO with another namespace.
The next step is understanding how to configure specific access policies for individual users or service accounts within a namespace, or how to set up geo-replication for your tenants.