Skip to main content

On This Page

Monorepo vs Polyrepo: How a 15-Repo Migration Cut Deployment Time by 82%

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Managing Monorepos at Scale: Lessons from Meta, AWS, and a 15-Repo Migration

Dan Flanagan migrated SID Technologies from 15 separate repositories to a single monorepo over a weekend. The migration cut time to complete a feature spanning 3 services from 10-14 days to 2-3 days.

Why This Matters

The monorepo vs polyrepo debate is frequently framed as a technical choice about scale, but Flanagan’s migration from 15 microservice repos to one monorepo at SID Technologies reveals it is primarily an organizational decision. At Meta, cross-cutting changes were routine in a single repo, while at AWS, the polyrepo model forced teams to reinvent the same CDK patterns dozens of times and manage version pinning hell. Premature polyrepo adoption costs startups 4-6 hours per week in dependency management and 10-14 days for multi-service features—a tax that most teams under 50 engineers cannot afford.

Key Insights

  • Meta runs a monorepo of thousands of engineers committing thousands of times per day, enabling one diff to touch iOS, Android, backend, and web—but requiring distributed caching tools like Buck and Bazel to handle build times.
  • AWS uses a polyrepo model with thousands of independent repositories, creating clear ownership boundaries but causing duplicate implementations of the same CDK patterns across dozens of teams, as observed by Flanagan during his tenure.
  • At SID Technologies, the 15-repo polyrepo required 8-15 PRs for a single cross-cutting change and cost 4-6 hours per week in dependency management; the monorepo reduced both to zero.
  • Google, Meta, Microsoft, Stripe, and Uber run monorepos; Amazon, Netflix, and Spotify run polyrepos—both models work, and the choice is organizational, not engineering capability.
  • Microservices are an architectural deployment pattern orthogonal to repository structure; SID now has 19 services in one monorepo that deploy independently and scale independently.

Working Examples

Go struct for a consolidated User model in the monorepo’s db directory, reducing duplication.

go
// Before: 8 different definitions across 8 repos
// After: One definition
// db/models/user.go
type User struct {
    ID uuid.UUID
    Email string
    OrganizationID uuid.UUID // This field was missing in 3 services
    CreatedAt time.Time
}

GitHub Actions workflow with change detection to test only affected services in the monorepo.

yaml
name: CI
on: [push, pull_request]
jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      services: ${{ steps.filter.outputs.services }}
    steps:
      - uses: actions/checkout@v3
      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            authentication:
              - 'services/authentication/**'
              - 'pkg/authentication/**'
              - 'db/**'
            billing:
              - 'services/billing/**'
              - 'pkg/stripe/**'
              - 'db/**'
  test:
    needs: detect-changes
    if: needs.detect-changes.outputs.services != '[]'
    strategy:
      matrix:
        service: ${{ fromJson(needs.detect-changes.outputs.services) }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Test ${{ matrix.service }}
        run: |
          cd services/${{ matrix.service }}
          go test ./...

Practical Applications

  • Startups with 1-50 engineers should use a monorepo with change-detection CI (e.g., dorny/paths-filter for GitHub Actions) to avoid paying the coordination tax of polyrepos for shared models and auth.
  • Organizations with genuinely independent business units (e.g., HIPAA services vs marketing) should consider polyrepo to enforce security isolation and independent release cadences, but must accept version management overhead.
  • When migrating to a monorepo, preserve git history if possible for audit trails and blame—Flanagan skipped this for speed, noting it should be done carefully.
  • Use CODEOWNERS even in small teams to prevent the ‘everyone and no one owns this’ problem, mirroring the organizational boundaries that polyrepo enforces via repository separation.

References:

Continue reading

Next article

Lossless Compression for RAG Agents: Maximizing LLM Context Windows

Related Content