Skip to main content

Backstage's DevLake-to-DORA Plugin Puts a Standard DORA Card on Every Service — Here's What That Means for a Self-Hosted PaaS

10 min readDora NodaDora Noda
Share
On this page

For years, getting DORA metrics in front of developers meant a platform team building the same pipeline over and over: stand up Apache DevLake, wire its Grafana dashboards, write custom SQL to slice metrics per team, then bolt a proxy onto Backstage so the numbers show up somewhere developers actually look. Every company built it; nobody shipped it as a product. That just changed. A new DevLake-to-DORA backend module, contributed to Backstage's community-plugins repository (PR #8364) and covered in Backstage Weekly #128, bridges Apache DevLake's engineering-metrics API directly into Backstage's standard DORA plugin — and adds an EntityDoraCard showing deployment frequency, lead time for changes, change failure rate, and failed-deployment recovery time on every service's Catalog Overview page.

Here is the whole pipeline, up front, because it is now short enough to fit in one sentence: your deploy pipeline POSTs deployment events to a DevLake webhook, DevLake computes the four DORA metrics, the new backend module proxies them into Backstage's DORA plugin, and the EntityDoraCard renders them on the service's catalog page. No bespoke dashboard, no custom SQL, no per-team wiring. For a self-hosted PaaS whose control plane already emits every deploy and rollback event — which is exactly the raw material three of the four DORA metrics are made of — this collapses "build an engineering-metrics dashboard" from a quarter-long project into an annotation and a webhook. This post walks through what shipped, where each number comes from, and the concrete wiring that puts a DORA card on every service a git-push platform deploys.

What Actually Shipped: The DevLake-to-DORA Backend Module

The contribution came from Miki Lior, VP of Engineering at Unity, after an 18-message community validation thread in the Backstage #plugins channel — the project's standard route for proving a plugin solves a shared problem before it lands in community-plugins. Three pieces shipped together:

  • A backend module bridging DevLake's API to the standard DORA plugin. Backstage already had a DORA plugin; what it lacked was a first-party path from the most widely deployed open-source metrics platform into it. Teams previously wrote this glue themselves — a custom backend that queried DevLake's MySQL database or REST API and reshaped results into whatever their frontend expected.
  • An EntityDoraCard for the Catalog Overview. This is the visible change. DORA metrics stop being a separate dashboard someone has to remember to visit and become a card on the same page as the service's owner, docs, APIs, and CI status — the page developers already open when they touch a service.
  • A Secure SQL Proxy targeting DevLake v1.0.2. Instead of handing Backstage raw database credentials to DevLake's store (the common, uncomfortable workaround), queries go through a scoped proxy. The module is also fully compatible with Backstage's new Backend System architecture, so it installs like any modern backend module rather than requiring legacy plugin wiring.

Each piece replaces something platform teams were hand-rolling. That is the quiet significance of the contribution: it is not a new capability, it is the standardization of a capability that hundreds of teams had built as one-off internal infrastructure.

The Four Numbers on the Card — and Where DevLake Gets Them

The card shows the four keys as DORA currently defines them. DevLake measures all of them at the project level, joining data from CI plugins, incoming webhooks, code hosts, and issue trackers:

MetricWhat it measuresWhere DevLake gets it
Deployment frequencyDeploys per week to productionCI plugins (Jenkins, GitLab CI, GitHub Actions, BitBucket Pipelines) or the incoming deployments webhook
Lead time for changesFirst commit → running in productionDeployments joined with commit data from a code-host connection (GitHub/GitLab)
Change failure rateFailed deploys ÷ total deploysDeployment status plus incident data (issue tracker or incidents webhook)
Failed deployment recovery timeFailed deploy → incident resolvedIncident open/close timestamps tied to the causing deployment

Two definitional notes worth knowing before you put these numbers in front of every engineer. First, "MTTR" on older dashboards is now failed deployment recovery time — the 2023 DORA report narrowed it from "any incident" to "incidents caused by a deployment," which is a materially different (and fairer) number. Second, the benchmarks people quote come from the 2024 State of DevOps report: elite performers — 19% of respondents — deploy on demand, hold lead time under a day, keep change failure rate under 5%, and recover in under an hour. The 2025 report retired the four-tier ladder entirely in favor of seven team archetypes that fold in human factors like burnout and organizational friction. Keep that in mind for the limits section below: the card shows the four keys, not the whole picture.

Why a Standard Card Beats a Bespoke Dashboard

The before/after is stark. Before: a platform team deploys DevLake, builds Grafana dashboards, writes per-team SQL filters, sets up auth between Grafana and the org's SSO, and then — because developers do not open Grafana — embeds iframes or builds a custom Backstage plugin to surface the numbers. Every step is maintenance surface, and every step is duplicated across every company doing it. After: install the backend module, point it at DevLake, add the card. The metrics wiring a team used to build first is now the part they skip.

The reason "put it in Backstage" is the right call in 2026 rather than just a call is adoption gravity. Backstage counts over 3,400 adopters and ranks among the top five CNCF projects by development velocity; the Q1 2026 CNCF Technology Radar places it in the "Adopt" tier for application delivery alongside Helm. Gartner's forecast that 80% of large engineering organizations will run platform teams by 2026 (up from 45% in 2022) is the demand side of the same curve. When that many organizations converge on one portal, "every service's Catalog Overview page" becomes the closest thing the industry has to a standard location — the golden path's front door.

And placement changes behavior. An org-level Grafana dashboard answers "how is engineering doing?" — a question managers ask quarterly. A per-service card answers "how is this service doing?" — a question its own developers confront every time they open its page to check ownership or docs. Deploy frequency sitting next to the API definitions makes delivery performance a property of the service, like its README, rather than a report about it.

Wiring a Self-Hosted PaaS's Deploy API Into the Card

Now the part the title promised: what this means for a self-hosted PaaS. A git-push platform — take bex, the open-source Render alternative that turns a git push into a running HTTPS service on your own machines, as the example — already produces the exact events DevLake's DORA pipeline wants. Every deploy is an API-visible state transition on an App resource: build started, deploy succeeded, deploy failed, rollback executed. On managed PaaS platforms this event stream is locked behind the vendor's dashboard; on a self-hosted platform it is yours to forward. The wiring:

1. Create a DevLake incoming webhook per service. DevLake generates a unique URL and an API key per webhook. Granularity matters: DevLake relates incidents to deployments at the webhook's scope, so one webhook per service gives you service-level DORA — which is precisely what a per-service catalog card needs.

2. POST deployments from the deploy pipeline. Whatever fires on deploy completion — a CI job, a controller hook, the platform's own notifier — sends DevLake the event:

bash
curl https://devlake.internal/api/plugins/webhook/1/deployments \
  -X 'POST' -H "Authorization: Bearer $DEVLAKE_API_KEY" \
  -d '{
    "id": "deploy-20260804-1432",
    "startedDate": "2026-08-04T14:32:01Z",
    "finishedDate": "2026-08-04T14:33:12Z",
    "result": "SUCCESS",
    "deploymentCommits": [{
      "repoUrl": "https://github.com/acme/checkout-service",
      "refName": "main",
      "commitSha": "9f2c1ab"
    }]
  }'

A failed deploy sends "result": "FAILURE"; a rollback that resolves an incident closes the loop for recovery time via the incidents webhook or a linked issue tracker.

3. Annotate the service's catalog-info.yaml so the DORA plugin knows which DevLake project the entity maps to, and the EntityDoraCard renders on its Overview page. Done: every service the platform deploys now carries its own DORA card in the portal developers already use.

Be precise about coverage, though — the deploy API alone does not fill all four cells. Deployment frequency comes entirely from step 2. Change failure rate and failed deployment recovery time come from deploy results plus incident events — a platform that tracks rollbacks natively already has the failure half; incidents need the webhook or an issue-tracker connection. Lead time for changes is the one the deploy event stream cannot produce by itself: DevLake computes it by joining deployments to commits, so you need a code-host connection (GitHub or GitLab plugin) alongside the webhook. The commitSha in the deployment payload is what makes that join work — include it, or your lead-time cell stays empty.

This is also where a Cluster-API-managed platform's architecture pays off twice. The same control plane that emits deploy events can register its App resources as a Backstage catalog source — services appear in the catalog because the platform deployed them, and their DORA cards populate because the platform reported the deploys. The portal and the platform stop being two systems a team reconciles by hand.

What the Card Won't Tell You

Three honest limits before you roll this out:

  • Granularity is a design decision, not a default. DevLake measures DORA at the project level and relates incidents to deployments at the webhook's scope. If you create one org-wide webhook to save setup time, you get org-level numbers wearing per-service cards — worse than no card, because it looks authoritative. Budget for one webhook per service from day one.
  • The four keys are no longer the whole DORA story. The 2025 report's move to seven archetypes was an explicit acknowledgment that delivery metrics without human factors mislead: a team can look "elite" on throughput while burning out, and the metrics won't show it until the people leave. Treat the card as a conversation starter on the service's page, not a performance review.
  • Backstage's release cadence deserves respect. The same newsletter that announced this module flagged regressions in release 1.49.3 (double page headers in the new frontend system, a broken scaffolder field explorer). The module targets the new Backend System — if you're on an older Backstage, the upgrade is a prerequisite, and worth doing deliberately rather than as a side effect of wanting one card.

The Portal Is Becoming the Platform's Front End

The direction of travel is clear. Backstage's DORA card is one instance of a broader pattern: the catalog is becoming the neutral surface where platform-produced facts — ownership, deploys, costs, incidents, now delivery metrics — get read, by humans and increasingly by agents. A control plane that exposes machine-readable state (deploys as API events, services as catalog entities) slots into that world without translation layers. One that hides its event stream behind a vendor dashboard does not.

For platform engineers running their own PaaS, the practical takeaway is concrete: the metrics dashboard you were going to build this quarter now costs a webhook, a code-host connection, and an annotation. Spend the recovered quarter on the platform itself.


Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with deploys and rollbacks exposed as API events your metrics stack can consume. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex