Chapter 31Lesson 04~205 minutes

Large Repositories, Monorepos, Search, Actions Cost Controls, and Platform Performance: Diagnostics, Failure Modes, Security, and Performance

Diagnose missed checks, storage drift, ownership sprawl, search blind spots, historical binary cost, and rate/latency symptoms without destructive guesswork.

DiagnosticsCODEOWNERSHistoryRate limits

Learning objectives

  • Diagnose missed validation, storage drift, ownership-rule sprawl, search blind spots, and historical binary cost.
  • Interpret a broken path filter without blaming the runner or cache layer.
  • Choose the least destructive repair and preserve evidence before cleanup or history rewriting.
  • Distinguish GitHub latency/rate limiting from application or workflow defects.

1. Diagnostic sequence for scale failures

Performance failures tempt teams to jump directly to cleanup, larger runners, or more path filters. Instead use the same evidence-first discipline as earlier chapters:

  1. Preserve evidence: run ID, base/head SHA, changed-file list, job timestamps, cache/artifact inventory, search query, API status/headers.
  2. Identify scope: Git history, repository, workflow, runner, cache/artifact, search index, API bucket, policy.
  3. Inspect controls: trigger filters, router mapping, CODEOWNERS/rulesets, retention, concurrency, runner labels.
  4. Classify cause: missing dependency edge, storage drift, historical blob, indexing blind spot, rate limiting, or platform latency.
  5. Choose least destructive correction: fix routing or retention before rewriting history or deleting evidence.
  6. Verify independently: rerun the exact scenario and compare measured state.

2. Broken example: a path filter hides a global dependency

This workflow looks efficient, but its trigger cannot know that libs/shared/ changes affect the API:

name: broken-api-only
on:
  pull_request:
    paths:
      - 'services/api/**'
permissions:
  contents: read
jobs:
  api:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
      - run: python -m py_compile services/api/app.py

Observed failure: a PR changes only libs/shared/version.txt. No run appears for broken-api-only. This is not a runner failure, timeout, cache miss, or test success. The workflow was never instantiated because the event filter excluded it.

Repair: start one cheap PR workflow reliably, calculate changed paths against immutable base/head SHAs, expand through a tested dependency map, and report one stable aggregate gate. GitHub also documents changed-file limits for native path filtering on very large diffs, another reason not to treat globs as a complete dependency engine.

3. Failure: cache or artifact retention becomes the hidden cost center

gh cache list --repo OWNER/REPO --limit 100 --json id,key,sizeInBytes,createdAt,lastAccessedAt

gh api -H 'X-GitHub-Api-Version: 2026-03-10' \
  'repos/OWNER/REPO/actions/artifacts?per_page=100' \
  --jq '.artifacts[] | {id,name,size_in_bytes,created_at,expires_at}'

Look for high-cardinality keys, caches that constantly evict/recreate, artifacts nobody consumes, and retention inconsistent with evidence requirements. Do not immediately delete everything: artifacts may be incident or release evidence, and artifact deletion is irreversible. First identify owner/consumer and reduce future retention/cardinality; clean only disposable or explicitly approved data.

4. Failure: CODEOWNERS and rules become broader than the architecture

A monorepo may begin with concise team ownership, then accumulate hundreds of overlapping exceptions. Symptoms include every PR requesting the same large group, unexpected owners for generated files, or a CODEOWNERS file so large GitHub cannot load it. GitHub currently requires CODEOWNERS to remain under 3 MB.

Repair by moving stable ownership to directory-level team patterns, documenting exceptions, testing representative paths, and separating review routing from authorization/ruleset policy. A CODEOWNERS match is not a substitute for dependency routing and not a repository ACL.

5. Failure: search result is treated as complete inventory

Imagine Code Search returns zero matches for an old unsafe workflow string. That does not prove the string never existed: Code Search covers default-branch indexed content, not every historical commit/non-default branch.

# Hosted discovery on default branch
gh search code 'dangerous-command' --repo OWNER/REPO --limit 100

# Current explicit local ref
git grep -n 'dangerous-command' main || true

# History across all fetched refs
git log --all -S'dangerous-command' --oneline -- .

The evidence sources answer different questions. Search is excellent for discovery; Git history answers historical repository questions; audit logs answer platform actions within their scope and retention.

6. Failure: deleting a generated binary does not erase its historical cost

Use only a local disposable repository for this demonstration:

mkdir /tmp/ch31-history-demo && cd /tmp/ch31-history-demo
git init -b main
python - <<'PY'
from pathlib import Path
Path('generated.bin').write_bytes(b'X' * (5 * 1024 * 1024))
PY
git add generated.bin && git commit -m 'Add generated binary by mistake'
git rm generated.bin && git commit -m 'Delete generated binary from current tree'

git rev-list --objects --all | grep generated.bin
git count-objects -vH

The object remains reachable through the earlier commit. Moving future binaries to LFS/releases/object storage prevents growth; it does not retroactively purge history. History rewriting is destructive and is not executed in this lesson. If the blob contains a credential, revoke/rotate first as Chapter 24 established. If history cleanup is justified for size/compliance, coordinate backups, refs, forks/clones, branch protection, force-push windows, and consumer re-cloning before using a history-rewrite tool.

7. Failure: rate limiting is misdiagnosed as platform slowness

A client that polls search or repository APIs aggressively can receive primary or secondary rate-limit responses. Capture HTTP status and headers before increasing timeout or concurrency:

gh api --include -H 'X-GitHub-Api-Version: 2026-03-10' rate_limit | head -40

Respect Retry-After where present, the rate-limit reset metadata, and secondary-limit guidance. Prefer webhooks for change notification and periodic reconciliation over high-frequency polling. Conversely, if rate metadata is healthy but jobs wait before starting, investigate runner queue/platform status rather than rewriting API code.

8. Least-destructive repair table

Symptom Bad first reaction Better first correction
Shared change missed tests Add random broad glob everywhere. Add/test dependency edge; keep stable router/gate.
Storage bill grows Delete all artifacts/caches. Inventory owner/consumer; lower future retention/cardinality; delete approved disposable data.
Clone slow Move to largest runner. Measure history/blobs/refs; shallow/sparse/partial strategy; move generated binaries.
Search misses result Assume absence. Verify query/ref/index scope; use Git/API/audit evidence.
Historical binary large Force-rewrite production immediately. Stop future growth; assess benefit; coordinate rewrite only if justified.

9. Summary

Scale diagnostics are strongest when the first question is “which layer failed?” rather than “what can I delete or parallelize?” Native filters, indexes, caches, ownership files, and repository history all have bounded semantics. Lesson 5 combines the chapter into a measured checkpoint and production cost/performance report.

Knowledge check

A shared-library PR has no API workflow run. Which layer failed?

Why should you not immediately delete large artifacts during a billing investigation?

What does a CODEOWNERS match prove?

A string is absent from Code Search but present in git log -S. Is that contradictory?

Why is history rewriting explicitly outside the normal cleanup path?

Next lesson

Checkpoint Lab — Large Repositories, Monorepos, Search, Actions Cost Controls, and Platform Performance

Further reading — current primary sources

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.