Premium Tier — Private Endpoints and VNet Integration
When to Use Premium
| Consideration | Standard | Premium |
|---|---|---|
| Max message size | 256 KB | 100 MB |
| Throughput | Shared, variable | Dedicated, predictable |
| Private endpoints | ❌ | ✅ |
| VNet integration | ❌ | ✅ |
| Messaging Units | N/A | 1, 2, 4, 8, 16 (scalable) |
| Geo-disaster recovery | ❌ | ✅ |
| JMS 2.0 support | ❌ | ✅ |
Choose Premium when you need:
- Large messages (>256 KB)
- Predictable, low-latency performance
- Network isolation (private endpoints, VNet)
- Compliance requirements (no public internet exposure)
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Azure VNet │
│ │
│ ┌─────────────────┐ ┌────────────────────────────┐ │
│ │ Subnet: apps │ │ Subnet: private-endpoints │ │
│ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌──────────────────────┐ │ │
│ │ │ Function App│ │ Private │ │ Private Endpoint │ │ │
│ │ │ (VNet │─┼─────────┼─▶│ (Service Bus) │ │ │
│ │ │ integrated)│ │ Link │ └──────────┬───────────┘ │ │
│ │ └─────────────┘ │ │ │ │ │
│ │ │ └─────────────┼──────────────┘ │
│ │ ┌─────────────┐ │ │ │
│ │ │ Logic App │─┼───────────────────────┘ │
│ │ │ (Standard) │ │ │
│ │ └─────────────┘ │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────┐
│ Service Bus Premium NS │
│ (Public access disabled) │
└──────────────────────────┘
Prerequisites
- Azure subscription with permissions to create networking resources
- Azure CLI installed
- Existing VNet or permissions to create one
Step 1: Create a Premium Namespace
RESOURCE_GROUP="rg-servicebus-tutorials"
LOCATION="eastus"
NAMESPACE="sb-tutorials-premium"
# Create Premium namespace with 1 messaging unit
az servicebus namespace create \
--resource-group $RESOURCE_GROUP \
--name $NAMESPACE \
--location $LOCATION \
--sku Premium \
--capacity 1
# Create a queue
az servicebus queue create \
--resource-group $RESOURCE_GROUP \
--namespace-name $NAMESPACE \
--name "orders-queue" \
--max-size 5120

Step 2: Create VNet and Subnets
VNET_NAME="vnet-servicebus"
SUBNET_APPS="subnet-apps"
SUBNET_PE="subnet-private-endpoints"
# Create VNet
az network vnet create \
--resource-group $RESOURCE_GROUP \
--name $VNET_NAME \
--location $LOCATION \
--address-prefix 10.0.0.0/16
# Create subnet for apps (Function App / Logic App)
az network vnet subnet create \
--resource-group $RESOURCE_GROUP \
--vnet-name $VNET_NAME \
--name $SUBNET_APPS \
--address-prefix 10.0.1.0/24 \
--delegations Microsoft.Web/serverFarms
# Create subnet for private endpoints
az network vnet subnet create \
--resource-group $RESOURCE_GROUP \
--vnet-name $VNET_NAME \
--name $SUBNET_PE \
--address-prefix 10.0.2.0/24
Step 3: Configure Private Endpoint
# Get Service Bus resource ID
SB_RESOURCE_ID=$(az servicebus namespace show \
--resource-group $RESOURCE_GROUP \
--name $NAMESPACE \
--query id -o tsv)
# Create private endpoint
az network private-endpoint create \
--resource-group $RESOURCE_GROUP \
--name "pe-servicebus" \
--vnet-name $VNET_NAME \
--subnet $SUBNET_PE \
--private-connection-resource-id $SB_RESOURCE_ID \
--group-id namespace \
--connection-name "servicebus-connection" \
--location $LOCATION

Step 4: DNS Setup
Configure Private DNS Zone so resources in the VNet resolve the Service Bus FQDN to the private IP:
# Create private DNS zone
az network private-dns zone create \
--resource-group $RESOURCE_GROUP \
--name "privatelink.servicebus.windows.net"
# Link DNS zone to VNet
az network private-dns link vnet create \
--resource-group $RESOURCE_GROUP \
--zone-name "privatelink.servicebus.windows.net" \
--name "dns-link-servicebus" \
--virtual-network $VNET_NAME \
--registration-enabled false
# Create DNS zone group for automatic DNS record management
az network private-endpoint dns-zone-group create \
--resource-group $RESOURCE_GROUP \
--endpoint-name "pe-servicebus" \
--name "default" \
--private-dns-zone "privatelink.servicebus.windows.net" \
--zone-name "servicebus"
Step 5: Disable Public Access
# Disable public network access
az servicebus namespace update \
--resource-group $RESOURCE_GROUP \
--name $NAMESPACE \
--public-network-access Disabled
⚠️ After disabling public access, the namespace is only reachable via private endpoints. Ensure your apps are VNet-integrated before applying this.
Step 6: Connect from VNet-Integrated Function App
FUNCTION_APP="func-orders-processor"
# Enable VNet integration on Function App
az functionapp vnet-integration add \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP \
--vnet $VNET_NAME \
--subnet $SUBNET_APPS
# Route all traffic through VNet
az functionapp config appsettings set \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP \
--settings "WEBSITE_VNET_ROUTE_ALL=1"
Code to connect (uses private endpoint transparently):
using Azure.Identity;
using Azure.Messaging.ServiceBus;
// Same FQDN — DNS resolves to private IP inside VNet
var ns = "sb-tutorials-premium.servicebus.windows.net";
var credential = new DefaultAzureCredential();
await using var client = new ServiceBusClient(ns, credential);
await using var sender = client.CreateSender("orders-queue");
await sender.SendMessageAsync(new ServiceBusMessage("Private endpoint test"));
Console.WriteLine("Message sent via private endpoint!");
Step 7: Test Connectivity
# From within the VNet (e.g., a VM or Cloud Shell with VNet access)
nslookup sb-tutorials-premium.servicebus.windows.net
# Expected: resolves to 10.0.2.x (private IP), NOT public IP
# Verify from Function App logs
az functionapp log tail \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP

Cost Comparison: Standard vs Premium
| Feature | Standard | Premium (1 MU) |
|---|---|---|
| Base cost (monthly) | ~$10 + per-operation | ~$668/month |
| Operations | $0.05 per million | Unlimited (included) |
| Message size | 256 KB | 100 MB |
| Private endpoints | Not available | Included |
| Messaging Units | N/A | Scale 1–16 |
| Best for | Dev/test, low-volume | Production, enterprise |
💡 Premium pricing is per Messaging Unit. Scale up for higher throughput; scale down during off-hours to save costs.
# Scale messaging units (e.g., scale to 2 MU during peak)
az servicebus namespace update \
--resource-group $RESOURCE_GROUP \
--name $NAMESPACE \
--capacity 2
# Scale back down
az servicebus namespace update \
--resource-group $RESOURCE_GROUP \
--name $NAMESPACE \
--capacity 1
Key Takeaways
- Premium tier is required for private endpoints and VNet isolation
- Private DNS zones ensure seamless name resolution inside the VNet
- Disable public access only after confirming private connectivity works
- Code remains unchanged — DNS handles routing to private IP
- Scale Messaging Units based on throughput needs