Platform Adoption Metrics

Measure and improve adoption of internal developer platforms. Covers DORA metrics, developer satisfaction, adoption funnels, platform health dashboards, and the patterns that prove platform value and drive continuous improvement.

Platform adoption metrics measure the extent, depth, and maturity of usage across a platform engineering ecosystem. They answer: *Who is using what, how often, and with what success?* These metrics are critical when a platform is transitioning from internal tooling to a shared, self-service foundation—especially when teams are expected to adopt platform services without central oversight. They become essential during platform maturity assessments, post-launch reviews, and when diagnosing stagnation in developer productivity.

Tracking Platform Usage

To assess adoption, teams must continuously collect data on platform interactions. The primary signal is event-based telemetry, captured from every service that exposes a platform interface. Events are emitted whenever a user or system interacts with a platform component: a deployment, a config update, a service creation, or a health check. Each event includes a standard set of fields: timestamp, user_id, platform_service, action, status, and duration. The status field is a string code: success, failed, pending, timeout, retrying.

A typical event log entry from a deployment service:

{
  "timestamp": "2025-04-05T12:34:56.789Z",
  "user_id": "[email protected]",
  "platform_service": "deployment",
  "action": "create",
  "status": "success",
  "duration": 1420,
  "metadata": {
    "app_name": "order-processor",
    "environment": "staging",
    "commit_hash": "a3f1b7c9d2e8f4a5b6c7d8e9f0a1b2c3",
    "pipeline_id": "pip-7890"
  }
}

These events are collected into a central log stream, typically using Apache Kafka or AWS Kinesis, and processed by a stream processor like Flink or Spark Structured Streaming. A common aggregation query calculates daily active users (DAU) and monthly active users (MAU) per platform service:

SELECT
  platform_service,
  COUNT(DISTINCT user_id) AS daily_active_users,
  COUNT(DISTINCT user_id) FILTER (WHERE DATE(timestamp) = CURRENT_DATE) AS daily_active_users,
  COUNT(DISTINCT user_id) FILTER (WHERE DATE(timestamp) >= CURRENT_DATE - INTERVAL '30 days') AS monthly_active_users,
  COUNT(*) AS total_interactions
FROM events
WHERE action IN ('create', 'deploy', 'update', 'start', 'scale')
GROUP BY platform_service;

The output is used to track adoption trends, surface underused services, and identify bottlenecks.

Measuring Depth of Usage

Adoption is not just about frequency—it is about depth. Teams are expected to use platform services beyond the basic onboarding. Depth is measured by feature utilization and configuration complexity.

The platform exposes a service catalog with metadata for each service. A service is defined by a service.yaml file, stored in a versioned repository:

name: database
version: 1.2.0
description: "Managed PostgreSQL cluster with automated backups and scaling"
schema:
  - name: size
    type: string
    enum: ["small", "medium", "large", "xlarge"]
    default: "medium"
  - name: backup_schedule
    type: string
    format: "cron"
    default: "0 2 * * *"
  - name: tags
    type: array
    items: { type: string }
    minItems: 1
  - name: enable_monitoring
    type: boolean
    default: true

A service is considered *deeply adopted* when its users configure at least three non-default fields in the schema. The platform’s configuration history tracks every update action on a service instance. A service instance is identified by service_name and environment. For example:

{
  "service_name": "database",
  "environment": "production",
  "user_id": "[email protected]",
  "updated_at": "2025-04-03T09:11:22Z",
  "config": {
    "size": "xlarge",
    "backup_schedule": "0 3 * * 0",
    "tags": ["e-commerce", "payment"],
    "enable_monitoring": true,
    "replication": {
      "mode": "async",
      "failover": true
    }
  }
}

A metric called configuration depth is calculated as the average number of non-default configuration keys per service instance. A service with an average of 4.5 such keys is considered to be used beyond basic setup.

Additionally, template usage is tracked. When a team creates a new service instance, they may select a template from a shared library. Templates are stored in templates/ directory with a template.yaml per template:

name: microservice-basic
description: "A minimal service with health check, metrics, and logging"
services:
  - name: web
    type: http
    config:
      port: 8080
      health_check: "/health"
  - name: database
    type: postgres
    config:
      size: "medium"
      backup_schedule: "0 1 * * *"

The platform logs every template application. A template adoption rate is computed as the percentage of new service instances that use a template. A high rate indicates that teams are not only using the platform, but also aligning on patterns.

Monitoring Developer Success

Platform adoption is not just about interaction—it is about success in execution. The platform must reduce friction and increase reliability. The key signal is success rate of platform workflows.

A workflow is a sequence of platform actions that constitute a common developer task. The most common workflows are:

Each workflow is defined by a workflow specification in workflows/ directory, written in YAML. For example:

name: onboarding-new-service
description: "Set up a new microservice from scratch"
steps:
  - name: create-service
    service: service-registry
    action: create
    required: true
    timeout: 30
    expected_status: "success"
  - name: configure-service
    service: configuration-store
    action: update
    required: true
    expected_status: "success"
    condition: "config.size != 'small'"
  - name: deploy
    service: deployment
    action: deploy
    required: true
    expected_status: "success"
    retries: 2
  - name: verify-deployment
    service: monitoring
    action: check-health
    required: true
    expected_status: "success"
    timeout: 60

The platform records workflow execution traces. A trace is a list of step results, each with step_name, status, duration, error, and output.

A workflow execution fails when any required step fails, or when a step exceeds its timeout. The workflow success rate is calculated over a period:

SELECT
  workflow_name,
  COUNT(*) AS total_executions,
  COUNT(*) FILTER (WHERE status = 'success') AS successful_executions,
  (COUNT(*) FILTER (WHERE status = 'success')) * 100.0 / COUNT(*) AS success_rate
FROM workflow_runs
WHERE started_at >= NOW() - INTERVAL '7 days'
GROUP BY workflow_name;

Low success rates in the onboarding-new-service workflow, for example, indicate that onboarding is not self-service. A common failure mode is the deploy step timing out due to missing preconditions—such as unconfigured monitoring or an outdated build image.

Detecting Platform Stickiness

Adoption is not static. The platform must become a default. Stickiness measures how long teams remain active and how deeply they engage.

The platform computes active user retention using the cohort method. A cohort is a group of users who first interacted with a platform service in a given week. The retention metric tracks how many of them return within 7, 14, 21, and 28 days.

The platform logs every user interaction, including login, create, update, deploy, and view. A user_session table is updated with user_id, started_at, ended_at, and last_activity.

A session duration threshold is set at 15 minutes. A user is considered engaged if they complete at least one session per week. The platform stickiness score is the fraction of users who have at least one session in the last 7 days.

Additionally, feature-specific stickiness is measured by tracking how often users revisit a service. The platform calculates a revisit rate for each service: the number of users who interact with the service more than once in a week.

A critical failure mode: users create a service but never update it again. The platform detects this by comparing the first_interaction timestamp with the last_interaction timestamp. If the gap exceeds 14 days and no subsequent interaction, the service is marked orphaned.

Orphaned services are surfaced via a daily batch job that queries:

SELECT
  service_name,
  environment,
  user_id,
  first_interaction,
  last_interaction,
  DATEDIFF(last_interaction, first_interaction) AS days_since_creation
FROM service_instances
WHERE last_interaction < NOW() - INTERVAL '14 days'
  AND first_interaction = last_interaction
  AND (SELECT COUNT(*) FROM events
       WHERE events.service_name = service_instances.service_name
         AND events.environment = service_instances.environment
         AND events.user_id = service_instances.user_id
         AND events.action = 'create'
         AND events.timestamp = service_instances.first_interaction)
ORDER BY days_since_creation DESC
LIMIT 100;

These orphaned services are flagged for platform team review and form the basis of a “platform health” dashboard.

Diagnosing Adoption Failure

When adoption stalls, the platform team must diagnose root causes. The most common failure is low engagement in high-visibility services.

A service is considered high-visibility if it appears in the developer portal’s top services list, which is populated by cumulative interaction counts over the past 30 days. The portal queries:

SELECT
  service_name,
  COUNT(*) AS total_interactions,
  COUNT(DISTINCT user_id) AS unique_users,
  AVG(duration) AS avg_duration,
  MAX(timestamp) AS last_interaction
FROM events
WHERE action IN ('create', 'deploy', 'update', 'start')
  AND timestamp >= NOW() - INTERVAL '30 days'
GROUP BY service_name
ORDER BY total_interactions DESC
LIMIT 10;

A service with high interaction volume but low engagement (few unique users) indicates centralized ownership—only one team uses it, while others are unaware or undermotivated.

Another failure: high error rates in workflow steps. The platform aggregates error logs from each service and correlates them with workflow runs. A recurring Error: 502 Bad Gateway on the deploy step suggests that the deployment service is overloaded or misconfigured.

The error distribution is analyzed by service and step. A step is considered unstable if it has a 5% or higher failure rate over the past 7 days. The platform generates alerts when a step’s failure rate exceeds 10% for two consecutive days.

A common silent failure: missing configuration defaults. When a new service is created, the platform applies defaults from the service schema. But if a default is missing or outdated, the service fails to start. The platform logs missing_default events when a required field in the schema has no value in the instance config.

These events are surfaced in a configuration health dashboard, which shows:

This dashboard helps the platform team prioritize schema updates and onboarding documentation.

Summary

Platform adoption metrics are not a set of reports—they are a continuous feedback loop. They tell teams when a service is adopted, when it is underused, when it fails, and when developers are stuck. The data comes from events, workflows, sessions, and configuration history. The metrics are not static: they evolve with the platform’s maturity. The most important insight is that adoption is not adoption until it is measurable, actionable, and visible.

This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.