Pensero can record every deployment your CI/CD pipeline makes and link it to the pull requests it shipped. Once deployments flow in, the Efficiency page gains a Delivery to production section with five cards (Deployment Frequency, Lead Time for Changes, Fixes or rework, Defect lifetime and Deployed share) and a Deployments tab listing each deployment with its pull requests.
No deployment provider integration is needed: your pipeline sends one small JSON event per deployment to Pensero, so it works with GitHub Actions, GitLab CI, Jenkins, ArgoCD or any script that can run curl.
Set up deployments
1. Create a deploy token
As an organization admin, go to Organization > Deployments and click Generate token. Copy the token and store it as a secret in your CI/CD system (for example as PENSERO_DEPLOY_TOKEN); you can copy it again from the same page at any time until you revoke it. Each organization has a single deploy token: regenerating it invalidates the previous one, and revoking it stops your pipeline from reporting deployments.
2. Send a deployment event from your pipeline
At the end of your deploy job, POST to https://pensero.ai/api/v1/deployments/events with the token as a bearer header. Replace the placeholders with the values your pipeline exposes:
curl -fsS -X POST https://pensero.ai/api/v1/deployments/events \
-H "Authorization: Bearer $PENSERO_DEPLOY_TOKEN" \
-H "Content-Type: application/json" \
--data @- <<EOF
{
"event_id": "<pipeline-run-id>",
"target": "my-service",
"environment": "production",
"status": "succeeded",
"started_at": "2026-09-03T11:00:00Z",
"finished_at": "2026-09-03T11:04:30Z",
"revisions": [
{
"repository": "my-org/my-repo",
"sha": "<deployed-commit-sha>",
"ref": "<branch-or-tag>",
"previous_sha": "<previously-live-commit-sha>"
}
]
}
EOF
event_id (required): a unique id for this deployment, for example the pipeline run id. Sending the same event_id again updates the deployment instead of creating a duplicate, so you can safely send an in_progress event at the start and a succeeded or failed one at the end.
target (required): the service or application being deployed (lowercase slug, e.g. api, web-frontend). One target per independently deployable unit.
environment (optional, default production): only production deployments count towards the metrics; other environments are stored but not charted.
status (required): in_progress, succeeded, failed or cancelled.
started_at / finished_at: ISO 8601 timestamps in UTC. finished_at is the moment the change is considered live; Deployment Frequency and Lead Time use it.
revisions (required, 1 to 50): what was deployed. repository must match a repository connected to Pensero (owner/name), sha is the deployed commit and previous_sha the commit that was live before. With both, Pensero binds every pull request merged between them; without previous_sha only the pull request that produced sha is bound.
Make the reporting step non-blocking in your pipeline so a Pensero outage can never fail a deployment.
Example: GitHub Actions. On a push-to-main deploy, github.run_id gives you the event id, github.sha the deployed commit, github.event.before the previous SHA, and job.status (success or failure) maps to succeeded / failed. Add continue-on-error: true to the step.
Example: GitLab CI. Use $CI_PIPELINE_ID as event id, $CI_COMMIT_SHA as sha, $CI_COMMIT_BEFORE_SHA as previous_sha and $CI_COMMIT_REF_NAME as ref; put the call in an after_script, whose failures do not fail the job.
3. Check it works
Open Efficiency > Deployments. New deployments appear within minutes with their status, target and the pull requests they shipped. Pull requests are bound asynchronously and re-checked periodically, so a deployment that shows no pull requests right after a merge usually fills in once the repository sync catches up.
Until your organization has received its first deployment, the Delivery to production section and the Deployments tab show a setup prompt with a link to Organization > Deployments for admins.
What the metrics mean
All cards use production deployments only, grouped by week, and follow the date range and scope filter of the page.
Deployment Frequency
How often you ship. Bars show production deployments per week, split into succeeded and failed; cancelled deployments are drawn as a separate series but never counted.
Headline: the number of succeeded deployments in the period and the failure ratio, failed / (succeeded + failed). In-progress deployments are excluded.
Caveat: the ratio reflects the outcome reported by your pipeline, not incidents detected afterwards in production.
Lead Time for Changes
How long a change takes to reach production. Measured per pull request from its first commit (or, when commit dates are unavailable, from when the pull request was opened) to the end of the first successful production deployment that contained it.
Headline: the weekly median in hours; the number of pull requests is shown in the weekly tooltip.
Caveat: pull requests count in the week they reached production, so a week with few deployments can show a noisy median.
Fixes or rework
How often you ship fixes or redo what you shipped. The share of successful production deployments that included a pull request Pensero classifies as a revert, a bugfix or a rework of a pull request already deployed to production earlier. Each deployment is counted once.
Headline: flagged deployments / succeeded deployments; the weekly tooltip shows the revert, bugfix and rework counts.
Caveat: classification runs after pull requests are analysed, so a recent deployment can be reclassified a few hours later. This is broader than DORA's rework rate: it counts any redo of shipped work, planned or not.
Defect lifetime in production
How long a defect lives in production. For every bugfix pull request linked to the pull request that introduced the defect, the time between the first production deployment of the original change and the first production deployment of the fix.
Headline: the weekly median in hours, by the week the fix reached production; the tooltip shows the number of resolved defects.
Caveat: bugfixes without a linked original pull request are not included. Without incident data, this is Pensero's stand-in for DORA's recovery time.
Deployed share
How much of what you merge reaches production. For the pull requests merged each week, their delivery points (Pensero's productivity measure for a pull request) are split between those whose pull request has since been deployed to production, in any week, and those still waiting.
Headline: the share of delivery points deployed. Delivery points belong to the people in the selected scope.
Caveat: only repositories that report production deployments count, so piloting deployments on one repository does not lower the share. Recent weeks read lower until their pull requests ship; that gap is your undeployed backlog.
How the scope filter applies to deployments
A deployment is attributed to the people behind the pull requests it shipped: the pull request author, the co-authors detected in the code and, for pull requests produced by an AI agent such as Devin, the person who started the agent session. Bots and agents are not treated as people. A deployment is visible for a scope when at least one of those people is in it. Deployments with no attributable person (no pull request bound yet, or only bot-authored changes such as dependency updates) are visible in every scope.
Good to know
Deployments are stored as received, so a wrong status or finished_at can be corrected by resending the event with the same event_id.
Charts are cached for up to two hours for the current period, while the card headline and the Deployments table are live; small temporary differences between them are expected.
Only a repository that is connected to Pensero can have pull requests bound; deployments of other repositories are still counted in Deployment Frequency but do not contribute to the other cards.