---
name: "Last9 Deployment Marker"
description: "Send deployment change events to Last9 from Buildkite pipelines."
author: "last9"
repo: "deployment-marker-buildkite-plugin"
stars: 1
official: false
version: "v1.0.0"
lastUpdated: "2026-04-06T06:06:43.000Z"
---

# Last9 Deployment Marker — Buildkite Plugin

[![CI](https://github.com/last9/deployment-marker-buildkite-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/last9/deployment-marker-buildkite-plugin/actions/workflows/ci.yml)

Sends deployment events to [Last9](https://last9.io) from Buildkite pipelines so you can correlate releases with errors, latency shifts, and APDEX changes on your dashboards.

```yaml
steps:
  - label: ":rocket: Deploy"
    command: ./deploy.sh
    plugins:
      - last9/deployment-marker#v1.0.0:
          refresh_token: "${LAST9_REFRESH_TOKEN}"
          org_slug: "your-org"
          env: "production"
```

That's it. The plugin wraps your deploy step — fires a `start` event before it runs and a `stop` event when it completes (`success` on exit 0, `failure` on anything else) with `duration_ms` included automatically.

## Configuration

| Option | Required | Default | Description |
|---|---|---|---|
| `refresh_token` | Yes | — | Last9 API refresh token |
| `org_slug` | Yes | — | Your Last9 organization slug |
| `env` | Yes | — | Deployment environment (`production`, `staging`, …) |
| `service` | No | Pipeline slug | Service name — must match your APM `service_name` label |
| `event_name` | No | `deployment` | Label for the change event |
| `data_source_name` | No | — | Last9 cluster or data source name |
| `api_base_url` | No | `https://app.last9.io` | Override the Last9 API base URL |
| `max_retry_attempts` | No | `3` | Retry attempts on failure |
| `retry_backoff_ms` | No | `1000` | Initial backoff in ms |
| `max_retry_backoff_ms` | No | `30000` | Maximum backoff cap in ms |

Store `LAST9_REFRESH_TOKEN` as a [Buildkite secret](https://buildkite.com/docs/pipelines/security/secrets/managing) or in your agent's environment hooks. Never hard-code it.

## What gets sent

Every event includes the deployment outcome plus the full Buildkite context automatically:

| Attribute | Source |
|---|---|
| `service` | `service` config (or pipeline slug) |
| `env` | `env` config |
| `result` | `success` / `failure` (stop event only) |
| `pipeline_slug` | `BUILDKITE_PIPELINE_SLUG` |
| `pipeline_name` | `BUILDKITE_PIPELINE_NAME` |
| `build_id` | `BUILDKITE_BUILD_ID` |
| `build_number` | `BUILDKITE_BUILD_NUMBER` |
| `build_url` | `BUILDKITE_BUILD_URL` |
| `commit_sha` | `BUILDKITE_COMMIT` |
| `branch` | `BUILDKITE_BRANCH` |
| `tag` | `BUILDKITE_TAG` |
| `commit_message` | `BUILDKITE_MESSAGE` |
| `actor` | `BUILDKITE_BUILD_CREATOR` (falls back to `BUILDKITE_BUILD_AUTHOR`) |
| `step_label` | `BUILDKITE_LABEL` |
| `step_key` | `BUILDKITE_STEP_KEY` |
| `job_id` | `BUILDKITE_JOB_ID` |
| `source` | `BUILDKITE_SOURCE` |
| `retry_count` | `BUILDKITE_RETRY_COUNT` |
| `triggered_from_build_id` | `BUILDKITE_TRIGGERED_FROM_BUILD_ID` |
| `rebuilt_from_build_id` | `BUILDKITE_REBUILT_FROM_BUILD_ID` |
| `duration_ms` | Computed: wall-clock time from step start to marker send (stop event only) |

Empty values are omitted. `result` and `duration_ms` are only present on the stop event.

## Requirements

`curl` and `jq` — both available on standard Buildkite agent images.

## Documentation

Full documentation at [last9.io/docs/integrations/ci-cd/buildkite](https://last9.io/docs/integrations/ci-cd/buildkite).

## Related

- [last9/deployment-marker-action](https://github.com/last9/deployment-marker-action) — same thing for GitHub Actions