fastmon Docs
Guides

Compare releases

Tag deploys from CI/CD and answer "did this deploy regress LCP?" in one query.

Tag every deploy as a release and compare the metrics before and after it. This guide covers the API key, the release call from CI/CD, and the comparison.

Time to set up: 10–15 minutes. You'll need: an authenticated fastmon account, edit access to your CI/CD pipeline, and a site that's already ingesting beacons.

1. Create an API key

  1. In fastmon, open your organization's settings, then Access, and click Create key. An organization key (fmo_…) belongs to the organization and keeps working when its creator leaves. (A personal key under Account → Access works too, but follows your role and memberships.)
  2. Tick release:write and analytics:read; the release call and the comparison query below need nothing else. Choose an expiry.
  3. Copy the value: it is shown once. Store it in your CI's secret store as FASTMON_API_KEY.

A pipeline that only posts releases can skip the settings page: the CI/CD snippet on the application page creates a release:write key in place, asks whether it should belong to you or to the organization, and writes it into the curl command.

If the key leaks, revoke it. For a fresh secret, rotate it, see Authentication.

2. Find the site ID

In fastmon, open the site, then Settings. Copy the site's id (UUID v7, looks like 01HZX...). Store it in your CI as FASTMON_SITE_ID.

3. Add a release call to your deploy job

The release call goes at the end of your deploy job, after the deploy has finished. The minimum payload is just version:

curl -fsS https://api.fastmon.eu/sites/$FASTMON_SITE_ID/releases \
  -H "Authorization: Bearer $FASTMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"version\": \"$DEPLOY_VERSION\",
    \"released_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
  }"

-fsS makes curl fail on non-2xx responses without progress output. Without released_at, the server sets now.

GitHub Actions

- name: Tag fastmon release
  if: success()
  env:
    FASTMON_API_KEY: ${{ secrets.FASTMON_API_KEY }}
    FASTMON_SITE_ID: ${{ vars.FASTMON_SITE_ID }}
  run: |
    curl -fsS https://api.fastmon.eu/sites/$FASTMON_SITE_ID/releases \
      -H "Authorization: Bearer $FASTMON_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{ \"version\": \"${{ github.sha }}\" }"

GitLab CI

fastmon-release:
  stage: post-deploy
  needs: ["deploy"]
  script:
    - |
      curl -fsS https://api.fastmon.eu/sites/$FASTMON_SITE_ID/releases \
        -H "Authorization: Bearer $FASTMON_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{ \"version\": \"$CI_COMMIT_SHORT_SHA\" }"

Vercel

Vercel doesn't run arbitrary post-deploy commands inside the build itself. Two options:

  • Deploy hook: set up a webhook receiver that fires on Vercel's deployment.succeeded event, and have the receiver call the fastmon endpoint with the SHA from the payload.
  • Edge function: add a small cron-triggered function that polls the Vercel API for new deployments and tags them.

4. Verify the release was recorded

Reload your site's release list:

curl https://api.fastmon.eu/sites/$FASTMON_SITE_ID/releases \
  -H "Authorization: Bearer $FASTMON_API_KEY"

You should see your new release in the data array, with the version you supplied and its window: from released_at to the next release, at most 14 days.

5. Compare metrics

On every metric page, Filter → Compare → Release, against the one before sets both windows, see Compare with an earlier window.

In the API, send the release's window from the release list as time_range and the previous release as compare_to:

curl https://api.fastmon.eu/organizations/$ORG_ID/analytics/query \
  -H "Authorization: Bearer $FASTMON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "time_range": { "from": "2026-05-07T12:00:00Z", "to": "2026-05-08T12:00:00Z" },
    "metrics": ["lcp", "inp", "cls"],
    "aggregations": ["p75"],
    "filters": { "site_id": "01HZX..." },
    "compare_to": { "release_id": "01HZY..." }
  }'

Every row then carries a comparison with the same metrics, and request.comparison_time_range shows the window used. The previous release's window starts at its released_at, runs as long as time_range, and ends early at the next release or now.

compare_to also takes any window { "from": …, "to": … } or one of previous_period, previous_day, previous_week, previous_month. The older compare_to_release_id is deprecated but still served.

What "good" looks like

  • Every successful deploy tags a release automatically, nothing by hand.
  • The release version is something you can resolve back to a commit: git SHA, tag, build number, whatever your team uses.
  • Your CI has a step that fails the deploy if the release call fails.

Common surprises

  • Omitting released_at defaults to "now." That fits most of the time. Watch out when your deploy job runs minutes before the artifact is actually live (blue/green flips later, etc.). Then back-date it.
  • Releases are per site. A monorepo deploy that ships three sites needs three release calls.
  • The comparison follows the query length. A 7-day time_range compares with the first 7 days of the previous release. Keep it short (1–24 h) to catch regressions sharply.

On this page