---
title: Code Coverage Carryforward
description: >-
  Reuse coverage data from ancestor commits when not every CI job runs, so total
  coverage stays accurate on every pull request.
breadcrumbs: Docs > Code Coverage > Code Coverage Carryforward
---

# Code Coverage Carryforward

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ().
{% /alert %}

{% /callout %}

{% callout %}
##### Join the Preview!

Carryforward is in Preview and is subject to change.
{% /callout %}

## Overview{% #overview %}

In large repositories, CI pipelines often run only the subset of test jobs that are relevant to the files changed in a pull request. For example, a PR that touches only frontend code may skip backend unit tests and integration tests. When that happens, only some of the coverage reports are uploaded for the commit, and the total coverage metric drops because the data from the skipped jobs is missing.

Carryforward solves this problem. When a coverage report is missing for a commit, Datadog reuses the most recent matching report from an ancestor commit so that total coverage reflects what the result would have been if every CI job had run.

Carryforward works at the [flag](https://docs.datadoghq.com/code_coverage/flags.md) level. For each flag that has no uploaded report on the target commit, Datadog looks back through the commit's ancestors and reuses the latest report tagged with that flag.

{% image
   source="https://docs.dd-static.net/images/code_coverage/carryforward_overview.90e55087e55e0dd1b8e6b98621d36f19.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/code_coverage/carryforward_overview.90e55087e55e0dd1b8e6b98621d36f19.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Diagram showing commit A with two uploaded reports, and commit B with one uploaded report and one carried forward from commit A." /%}

## Prerequisites{% #prerequisites %}

Carryforward builds on top of [Code Coverage flags](https://docs.datadoghq.com/code_coverage/flags.md). Do the following before you enable carryforward:

- Tag every coverage report with one or more flags using the `--flags` option on `datadog-ci coverage upload`. See [Add flags to coverage reports](https://docs.datadoghq.com/code_coverage/flags.md#add-flags-to-coverage-reports).
- Use a stable set of flags across CI runs. The same flags should be produced whenever the corresponding tests or tested code change. If your CI distributes tests randomly across workers or generates a different set of reports on each run, carryforward results are not meaningful.

For the consistency requirement, assign one CI job per coverage report. For example, use separate jobs for unit tests, backend integration tests, and UI tests, with each job tagging its report with a stable flag.

## Enable carryforward{% #enable-carryforward %}

Carryforward is configured in the `code-coverage.datadog.yml` file at the root of your repository.

### Enable carryforward for all flags{% #enable-carryforward-for-all-flags %}

Set the top-level `carryforward` field to `true` to enable carryforward for every flag in the repository:

In the `code-coverage.datadog.yml` file:

```yaml
schema-version: v1
carryforward: true
```

### Enable carryforward for specific flags{% #enable-carryforward-for-specific-flags %}

To enable carryforward for only a subset of flags, leave the top-level `carryforward` field unset (or `false`) and opt in per flag using the `flags` map:

In the `code-coverage.datadog.yml` file:

```yaml
schema-version: v1
flags:
  unit-tests:
    carryforward: true
  integration-tests:
    carryforward: true
```

### Disable carryforward for specific flags{% #disable-carryforward-for-specific-flags %}

When carryforward is enabled at the repository level, you can disable it for individual flags. This is useful for flaky test suites or report types where reusing ancestor data is not appropriate:

In the `code-coverage.datadog.yml` file:

```yaml
schema-version: v1
carryforward: true
flags:
  nightly-tests:
    carryforward: false
```

In this example, carryforward applies to every flag except `nightly-tests`.

## How carryforward works{% #how-carryforward-works %}

When a new commit is pushed to a repository where carryforward is enabled, Datadog follows these steps:

1. Looks back through the commit's ancestors.
1. For every flag with carryforward enabled, finds the most recent report tagged with that flag.
1. Reuses the coverage data from those ancestor reports for the new commit, until a fresh report for the flag is uploaded.

Carried-forward data is automatically replaced as soon as a real report is uploaded for the same flag on the new commit. The merged total coverage on the commit always reflects a combination of the following:

- Fresh reports uploaded for the commit
- Carried-forward reports for flags where no fresh report was uploaded

## Use with PR Gates{% #use-with-pr-gates %}

While carryforward is in Preview, Datadog recommends starting with a non-blocking [PR Gate](https://docs.datadoghq.com/code_coverage/configuration.md#pr-gates) to observe how carryforward affects evaluation before enforcing it as a merge requirement.

## Further reading{% #further-reading %}

- [Code Coverage](https://docs.datadoghq.com/code_coverage.md)
- [Set up Code Coverage](https://docs.datadoghq.com/code_coverage/setup.md)
- [Configure Code Coverage](https://docs.datadoghq.com/code_coverage/configuration.md)
- [Organize coverage data with flags](https://docs.datadoghq.com/code_coverage/flags.md)
