Guide · AWS MSK Serverless

MSK Serverless for MCP Servers — Capacity Model, IAM-Only Auth, and Probe Pipeline Trade-offs

MSK Serverless removes partition pre-provisioning: you create topics without specifying shard counts and AWS scales the underlying storage and throughput automatically up to a per-cluster quota of 200 MiBps ingress and 400 MiBps egress. For MCP probe pipelines with bursty ingest — many probes completing simultaneously during a scan wave — this eliminates the capacity-planning loop that plagues provisioned MSK clusters. The catch is that MSK Serverless enforces IAM authentication only; SCRAM credentials and mTLS certificate auth are not supported. Every producer and consumer must use the SASL_SSL protocol with sasl.mechanism=AWS_MSK_IAM and a valid IAM role. If your existing Kafka clients use SCRAM or username/password auth, migration to MSK Serverless requires a client-side change before you can connect at all.

TL;DR

MSK Serverless is the right choice when your probe ingest volume is unpredictable and you do not want to size broker counts and partition counts in advance. Use provisioned MSK when you need custom topic-level configs (retention.ms overrides, log compaction), MSK Connect sink connectors, or MSK Replication — none of those features are available on MSK Serverless. Authentication is IAM-only; plan the IAM principal and policy before cluster creation. Pricing is per-GiB-hour of partition storage plus per-MB of data ingressed and egressed — there are no broker-hour charges.

Capacity model: how throughput scales without partition management

On a provisioned MSK cluster, throughput is bounded by (broker count) × (per-broker throughput ceiling). You plan ahead: N brokers × M topics × P partitions. MSK Serverless replaces that model with a single per-cluster soft quota:

MetricMSK Serverless default quotaProvisioned MSK (comparison)
Ingress throughput200 MiBps per clusterScales with broker count and instance type
Egress throughput400 MiBps per clusterScales with broker count and instance type
Partitions per clusterUp to 120 partitions (soft)Up to 300,000 partitions (depends on instance)
Topic-level retention overridesNot supportedSupported per topic via configuration
Partition rebalancingAutomaticManual (rack-aware assignment)

For AliveMCP, the probe pipeline produces one Kafka message per probe completion — typically 1–4 KB of JSON containing endpoint ID, HTTP status, response time, and tool-schema hash. At 2,000 probe completions per second that is roughly 8 MiBps ingress, well within the 200 MiBps quota. The 120-partition soft limit is the binding constraint for scale-out: if the probe worker fleet grows beyond ~120 concurrent consumer threads and each needs its own partition for ordered processing, you will need provisioned MSK.

IAM-only authentication: required configuration

MSK Serverless enforces SASL/IAM for all clients. There is no option to enable unauthenticated, SCRAM, or mTLS access. Every producer and consumer needs:

  1. A boto3 or AWS SDK credential chain (instance profile, ECS task role, Lambda execution role, or explicit access key)
  2. The aws-msk-iam-auth library (Java) or a compatible SASL/IAM plugin for the client language
  3. An IAM policy granting kafka-cluster:Connect, kafka-cluster:DescribeGroup, kafka-cluster:AlterGroup, kafka:DescribeTopic, kafka-cluster:ReadData, and/or kafka-cluster:WriteData on the cluster and topic ARNs
# Node.js producer with MSK IAM auth (using kafkajs + msk-iam-auth-library)
import { Kafka } from 'kafkajs';
import { MSKAuthProvider } from 'aws-msk-iam-sasl-signer-js';

const kafka = new Kafka({
  clientId: 'alivemcp-probe-producer',
  brokers: ['b-1.cluster.msk.us-east-1.amazonaws.com:9098'],
  ssl: true,
  sasl: {
    mechanism: 'oauthbearer',
    oauthBearerProvider: async () => {
      const provider = new MSKAuthProvider({ region: 'us-east-1' });
      const token = await provider.generateAuthToken();
      return { value: token };
    },
  },
});

The IAM token has a 15-minute expiry. The MSKAuthProvider re-fetches a token before each connection and on token expiry — your probe worker does not need a refresh loop. On Lambda, the execution role is the IAM principal; the SDK credential chain resolves it automatically.

Minimum IAM policy for a probe result producer

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kafka-cluster:Connect",
        "kafka-cluster:DescribeTopic",
        "kafka-cluster:WriteData"
      ],
      "Resource": [
        "arn:aws:kafka:us-east-1:123456789012:cluster/alivemcp-probe-results/*",
        "arn:aws:kafka:us-east-1:123456789012:topic/alivemcp-probe-results/*/probe-results"
      ]
    }
  ]
}

Tiered storage: default on Serverless

MSK Serverless uses tiered storage by default. Data is written to local broker SSD first, then offloaded to S3-backed tiered storage. There is no fixed local storage limit — the cluster will not fill a disk. Retention is controlled at the cluster level via the log.retention.ms default (7 days). You cannot override retention.ms per-topic on MSK Serverless — all topics share the cluster-level retention.

For AliveMCP probe result topics, 7-day retention covers the DLQ replay window (probe results are archived to S3 via a separate archiver consumer within 1 hour; the Kafka retention is an emergency replay buffer). If you need per-topic retention tuning — for example, a 1-day topic for ephemeral probe commands and a 30-day topic for historical raw results — you need provisioned MSK with topic-level configs.

What MSK Serverless does NOT support

FeatureMSK ServerlessProvisioned MSK
MSK Connect (S3 Sink, DynamoDB Sink)Not availableAvailable
MSK Replication (cross-region DR)Not availableAvailable
Log compactionNot availableAvailable per topic
Per-topic retention.ms overrideNot available (cluster-level only)Available
SCRAM / mTLS authNot available (IAM only)Available
Custom broker config (e.g., message.max.bytes)Not availableAvailable via configuration versions
Tiered storageAlways onOptional (must enable)

CDK provisioning for MSK Serverless

MSK Serverless uses the L1 construct CfnServerlessCluster — there is no L2 wrapper yet. The cluster creation includes an inline VPC config and security group, and a client authentication block that enforces IAM.

import * as cdk from 'aws-cdk-lib';
import { aws_msk as msk, aws_ec2 as ec2 } from 'aws-cdk-lib';

const vpc = ec2.Vpc.fromLookup(this, 'Vpc', { isDefault: false });

const mskSg = new ec2.SecurityGroup(this, 'MskSg', {
  vpc,
  description: 'MSK Serverless probe results',
  allowAllOutbound: true,
});

// Allow probe workers (in their own SG) to reach MSK on port 9098
mskSg.addIngressRule(probeWorkerSg, ec2.Port.tcp(9098), 'Kafka SASL/TLS');

const serverlessCluster = new msk.CfnServerlessCluster(this, 'ProbeCluster', {
  clusterName: 'alivemcp-probe-results',
  vpcConfigs: [{
    subnetIds: vpc.privateSubnets.map(s => s.subnetId),
    securityGroups: [mskSg.securityGroupId],
  }],
  clientAuthentication: {
    sasl: { iam: { enabled: true } },
  },
});

new cdk.CfnOutput(this, 'ClusterArn', { value: serverlessCluster.attrArn });

CloudWatch metrics for MSK Serverless

MSK Serverless emits a subset of the metrics available on provisioned clusters. Key metrics for probe pipeline monitoring:

MetricNamespaceWhat to alarm on
BytesInPerSecAWS/Kafka> 180 MiBps sustained (near 200 MiBps quota)
BytesOutPerSecAWS/Kafka> 360 MiBps sustained (near 400 MiBps quota)
OffsetLagAWS/KafkaIncreasing lag on probe-result consumer group
FetchMessageConversionsPerSecAWS/KafkaHigh value indicates message format conversion overhead
ProduceTotalTimeMsMeanAWS/Kafka> 100ms for probe result writes warrants investigation

Note: UnderReplicatedPartitions is not meaningful for MSK Serverless (replication is managed by AWS). Do not build alarms on it for serverless clusters — it will always read 0.

Common failure modes

SymptomCauseFix
Producer fails to connect: SASL handshake failedClient is using SCRAM or PLAIN mechanism — not supported on MSK ServerlessSwitch to sasl.mechanism=AWS_MSK_IAM (OAUTHBEARER) with MSKAuthProvider
Producer fails with TopicAuthorizationExceptionIAM policy missing kafka-cluster:WriteData on topic ARNAdd topic-level WriteData action; cluster-level allow is insufficient
Throughput capped at ~200 MiBps with retriesPer-cluster ingress quota reachedThrottle probe scan rate, or migrate to provisioned MSK with higher broker count
Partition count hits 120 soft limitToo many topics × partitionsConsolidate topics; or request quota increase via AWS Support
Unable to create MSK Connect connectorMSK Connect not supported on ServerlessUse a consumer application to write to S3/DynamoDB, or migrate to provisioned MSK