---
title: "Run shared validation once"
description: "Remove overlapping task or matrix invocations that perform the same check on the same inputs."
url: https://starsling.dev/ci-playbooks/techniques/avoid-duplicate-validation
canonicalUrl: https://starsling.dev/ci-playbooks/techniques/avoid-duplicate-validation
---

# Run shared validation once

Remove overlapping task or matrix invocations that perform the same check on the same inputs.

## How to choose an approach

Compare the examples by repository setup, prerequisites, and risks before adopting one. Each company implemented this in its own environment; measure each change against your own baseline.

- **[DoorDash](https://starsling.dev/ci-playbooks/doordash#checks-on-one-leg)**: Use it when A matrix over operating systems repeats checks whose result is the same on every OS. Check before adopting: Keep any check that reads platform-specific code paths, native modules or line endings on every leg it can differ on.
- **[Mastra](https://starsling.dev/ci-playbooks/mastra#version-hooks)**: Use it when An automated version PR repeats hooks already enforced by required CI. Check before adopting: Never bypass a check merely because it is expensive. Prove equivalent file scope and failure propagation in required workflows; retain checks that only the hook performs.
- **[Stripe](https://starsling.dev/ci-playbooks/stripe#delegate-snapshots-once)**: Use it when Snapshot or generated-output checks run both on their own and inside a broad suite. Check before adopting: Skip a class in one lane only while a required lane runs it, and keep runtime variants and aggregate results unchanged.
- **[Stripe](https://starsling.dev/ci-playbooks/stripe#remove-duplicate-tests)**: Use it when A test wrapper invokes another test task that CI also calls directly, or two configurations run the same code. Check before adopting: Compare the test and screenshot inventories before and after, and keep a configuration that has its own code paths or its own published build.

## Apply this technique

````text
Evaluate and apply this CI technique to my repository: Run shared validation once.

Remove overlapping task or matrix invocations that perform the same check on the same inputs.

Read the technique and its source-backed company examples: https://starsling.dev/ci-playbooks/techniques/avoid-duplicate-validation.md

Inspect this repository’s CI workflows, build and test commands, dependencies, and recent run timings. Identify where this technique applies and explain the expected benefit using this repository’s evidence.
Measure a baseline from recent comparable runs: elapsed time, queue time, runner minutes and failures where available. If data is unavailable, say what cannot be measured.
Compare relevant company approaches, checking prerequisites, platform differences and tradeoffs. Rank applicable options by evidence, fit and measurable opportunity; do not present company results as predictions for this repo.
Recommend the smallest safe change, show what checks and fallback paths remain, and ASK ME WHICH CHANGE TO APPROVE BEFORE EDITING ANY FILES.
Only after approval, work on a new feature branch, make one reversible change, and open a reviewable pull request. Never merge or push to a default or protected branch.
Keep required checks, test coverage, deployment and release behavior intact. Validate the change and compare equivalent runs where possible; report limitations and what should be monitored after merge.
````

## How companies used this technique

Read what each company changed and follow the original sources.

### DoorDash: Run platform-independent checks on one matrix leg

The desktop job ran on macOS, Linux x64 and Linux arm64, and each leg repeated typecheck, lint, format, API drift, unit, component and security suites. The PR runs those steps on the ubuntu-latest leg; every leg still packages the app, with ubuntu-latest x64 running the full journey suite and macOS and ubuntu arm64 running a 5-journey smoke subset.

Evidence: Source PR/commit evidence

Use it when: A matrix over operating systems repeats checks whose result is the same on every OS.

Before applying it: Keep any check that reads platform-specific code paths, native modules or line endings on every leg it can differ on.

[Read more in the DoorDash playbook](https://starsling.dev/ci-playbooks/doordash#checks-on-one-leg)

[Primary source](https://github.com/doordash-oss/agentic-orchestrator/pull/139)

### Mastra: Avoid repeating CI checks in a version bot’s commit hook

The versioning action disabled Husky because separate workflows already handled its precommit checks. This adapts the duplicate-command recipe and depends on required CI running the same checks.

Evidence: Source PR/commit evidence

Use it when: An automated version PR repeats hooks already enforced by required CI.

Before applying it: Never bypass a check merely because it is expensive. Prove equivalent file scope and failure propagation in required workflows; retain checks that only the hook performs.

[Read more in the Mastra playbook](https://starsling.dev/ci-playbooks/mastra#version-hooks)

[Primary source](https://github.com/mastra-ai/mastra/pull/2952)

### Stripe: Run snapshot checks once in a dedicated lane

Stripe iOS re-records snapshots in a dedicated job and skips those snapshot classes in the main unit-test jobs only when that dedicated job is part of the pipeline. Standalone framework jobs keep every test.

Evidence: Source PR/commit evidence

Use it when: Snapshot or generated-output checks run both on their own and inside a broad suite.

Before applying it: Skip a class in one lane only while a required lane runs it, and keep runtime variants and aggregate results unchanged.

[Read more in the Stripe playbook](https://starsling.dev/ci-playbooks/stripe#delegate-snapshots-once)

[Primary source](https://github.com/stripe/stripe-ios/pull/7332)

### Stripe: Stop invoking tests twice through overlapping tasks

Stripe Android’s screenshot verification already ran the unit tests. A new dispatcher task runs screenshot verification for modules that have it and unit tests for the rest, so each module runs its tests once. Stripe .NET removed a Debug build and test pass that repeated the Release pass for an SDK with no configuration-specific code.

Evidence: Source PR/commit evidence

Use it when: A test wrapper invokes another test task that CI also calls directly, or two configurations run the same code.

Before applying it: Compare the test and screenshot inventories before and after, and keep a configuration that has its own code paths or its own published build.

[Read more in the Stripe playbook](https://starsling.dev/ci-playbooks/stripe#remove-duplicate-tests)

[Primary source](https://github.com/stripe/stripe-android/pull/13033)

## CI optimization is continuous work.

Apply this technique yourself, or use StarSling Runners for faster GitHub Actions and optional agent-driven optimization PRs, which teams on eligible paid plans can turn on.

[Get self-improving CI](https://starsling.dev/products/runners)

## Related techniques

### [Package once, and build full installers after merge](https://starsling.dev/ci-playbooks/techniques/package-once)

Drop the build step that packaging repeats, and build the unpacked app pull requests test.

1 implementation · 1 company (DoorDash)

### [Remove repeated build steps](https://starsling.dev/ci-playbooks/techniques/avoid-duplicate-builds)

Trace artifact producers and consumers so package, release, or test stages reuse work instead of triggering the same build again.

4 implementations · 3 companies (Mastra, OpenAI, Spotify)

### [Build once and share the output with test shards](https://starsling.dev/ci-playbooks/techniques/build-once-for-shards)

Separate the build producer from test consumers and hand the same verified artifact to each shard.

2 implementations · 2 companies (OpenAI, Stripe)

## Company Playbooks

### [Anthropic](https://starsling.dev/ci-playbooks/anthropic)

Run only affected tests

### [DoorDash](https://starsling.dev/ci-playbooks/doordash)

Run build and test in parallel, sharded across CI agents

### [Linear](https://starsling.dev/ci-playbooks/linear)

Benchmark the same job on faster hardware

### [Mastra](https://starsling.dev/ci-playbooks/mastra)

StarSling runners for the slowest test workflow

### [OpenAI](https://starsling.dev/ci-playbooks/openai)

Rank CI fixes by the minutes they save

### [Ramp](https://starsling.dev/ci-playbooks/ramp)

Move a CPU-bound test suite to a faster CPU

### [Shopify](https://starsling.dev/ci-playbooks/shopify)

Let an agent iterate against one CI metric

### [Spotify](https://starsling.dev/ci-playbooks/spotify)

Build arm64 on native arm64 runners

### [Stripe](https://starsling.dev/ci-playbooks/stripe)

Run only the tests a change can reach

### [Uber](https://starsling.dev/ci-playbooks/uber)

Build the merge-queue speculations most likely to be needed

## Related guides

Implementation guides for this technique.

### [Filter workflows by changed files](https://starsling.dev/best-practices/github-actions/path-filter-workflows)

Use paths and job conditions while keeping required checks reporting.

### [Cancel superseded CI runs](https://starsling.dev/best-practices/github-actions/cancel-superseded-runs)

Cancel obsolete PR runs with a correctly scoped concurrency group.

### [Bound runner jobs with timeouts](https://starsling.dev/best-practices/github-actions/bound-job-timeouts)

Set job and step timeouts using expected durations and failure behavior.

### [Right-size GitHub Actions runners](https://starsling.dev/best-practices/github-actions/right-size-runners)

Match runner resources to the workload and compare equivalent runs.
