How to reveal whether developers are happy with your self-service system or are just trying until the PR is green?
Press enter or click to view image in full size
Most platform teams will tell you their Kafka self-service is working. The evidence they point to is almost always the same: developers can create their own topics and connectors, there are guardrails in place, and bad configs get blocked before they reach production. The cluster looks sane, it’s governed, it has self-service, it’s working great!
No, it depends. “Nothing broke” and “our Github process rejects bad PRs” are not measures of whether self-service works. They measure whether your enforcement works, which is a different and much easier thing. You protect a castle, great, but a business is about adoption and avoiding frictions to do more.
Real self-service has a job: let a developer who isn’t a Kafka expert provision a correct resource, quickly, without pulling the platform team in.
You can have strict guardrails and still be failing at that completely. Let’s see how to identify this.
Let’s agree on what “self-serve works” means
Self-service is working when three things are true at once:
- developers can provision what they need without filing a ticket
- the result is correct on the first try
- the platform team’s involvement per request trends toward zero.
If any of those are not true, you don’t have self-service; you have a ‘slower’ ticket queue with extra steps.
Why? Enforcement and guidance are two separate pieces of the system, it’s easy to build enforcement, it’s harder to build guidance.
- A guardrail, a policy, a CI check, a rejected pull request, a naming-convention regex, answers one question: is this allowed? That’s useful, it’s the easy half.
- Helping developers arrive at yes (the right partition count, the right cleanup policy, the right replica settings) is way more difficult.
So the question for measurement becomes:
Are your developers reaching the right answer on their own, or are they trying until the gate stops rejecting them?
KR1: Lead time from request to working resource
Measure the time it takes from “I need a topic” to “I have a correct, running topic.” In working self-service this is minutes. If it’s hours or days, the gate is technically open but the developer is stuck in front of it:
- reading docs
- asking in Slack
- trial-and-fitting configs against your policy until something passes.
A “self-service enabled” with a multi-day lead time means you’ve automated the rejection, not the provisioning.
KR2: Gate rejection rate
Track what fraction of create/update attempts your policies reject. Counterintuitively, a high rejection rate is bad news, not proof your guardrails are useful for people.
It means developers can’t predict what will pass: they’re trying and failing. Each rejection teaches them only that one specific combination failed.
A healthy system has a low rejection rate not because the rules are loose, but because developers start from defaults that already work.
KR3: Repeat questions for the same config
Count how often the same questions resurface:
- “How many partitions should this have?”
- “Do I want compaction or deletion here?”
- “Which min-in-sync-replicas goes with replication factor three?”
If your platform channel answers these, the knowledge that resolves them is trapped in people instead of encoded in the system.
Working self-service makes that expertise “inheritable”: a new team gets it by default, without asking.
It’s like Agents Skills: Build once. Reuse for anyone.
Recurring config questions are a direct signal of expertise that hasn’t been turned into a reusable asset.
KR4: Creation from templates
What percentage of new topics and connectors are created from a vetted template versus from a blank form and the cluster’s generic defaults?
This is often one thing missing. Every developer has to rethink decisions your experts already made one day and they often fail as they are not Kafka experts.
When you have templates and they are massively reused, the expert call gets made once and reused — encoded into a template with context and condition.
Template adoption rate is the closest thing you have to a single metric for whether the guidance exists.
KR5: Misconfiguration incidents
Find a way to associate production issues to a provisioning-time choice (wrong partitions, wrong metadata, wrong replication, wrong data center, wrong semantics, wrong config, etc.).
- Partition count is the canonical example: it’s a deliberate capacity decision about parallelism, and one of the few topic settings that’s genuinely painful to change after the fact. It can be very costly over time and invisibly causing wide platform issues.
If you’re discovering wrong partition counts during incidents rather than setting them right at creation, your self-service is letting expensive, hard-to-reverse mistakes going through.
Not only partition, but lack of masking or encryption data can lead to data leaks and severe fines; misconfigurations lead to consumers outage or partner traffic being stuck etc.
A template moves that call to the moment it’s free: before the resources even (topics, schemas, connectors, etc.).
KR6: The connector fallback rate
Topics are one thing. Connectors are another big item to self-serve, where unguided self-service is the enemy.
- Configure a JDBC sink connector’s config and you’re looking at dozens of properties; to a developer who isn’t a Kafka Connect specialist, that ‘s a big issue. They don’t care of Kafka Connect, they need to move data from their database/datalake to Kafka or vice-versa.
Measure it: of all connector requests, what fraction still route back to the platform team? Also measure connectors issues due to misconfigurations (looking at your Debezium).
A high connector-fallback rate is the signal that you’ve help with provisioning but failed at guiding what good looks like.
Kafka, Schemas, Connect, Streams, are hundreds of properties. Nobody has time for this. This is where self-service templates must pre-decide vetted by platform team and experts) so the regular developer thinks in terms of use-case and not in terms of low-level tech.
Conclusion
Self-service is not just provisioning and “topic as a service” using GitOps.
You’re avoiding the real thing: guidance. You are part of an organization, with people and agents. If you’re part of a platform team, your job is not just delivering tech, is to delivery a platform to help people building and scaling their use-cases and to stay focus on that, not the low-level nitty-gritty technical Kafka details.
Failing at guidance can feel demoralizing for developers, and corrosive to the trust self-service depends on.