findthecto
Back to Blog

The Boy Scout Rule: Pay Down Debt While Shipping

Learn how to improve code quality incrementally without dedicated refactoring sprints. The Boy Scout Rule and other tactics that actually work.

Find the CTO
technical-debt refactoring engineering-practices code-quality

“We need to stop all feature development for 3 months to pay down technical debt.”

I’ve heard this at least 20 times. I’ve never seen it work.

What actually happens:

  • Month 1: Team refactors enthusiastically
  • Month 2: CEO panics about lack of features, pressures team to ship something
  • Month 3: Team scrambling to do both, doing neither well
  • Result: Incomplete refactoring, angry customers, burned out engineers

Here’s what actually works: incremental improvement while shipping features.

The Boy Scout Rule

“Leave code better than you found it.”

Every time you touch a file for any reason, improve it slightly. Don’t refactor the whole thing. Just make it a bit better.

Examples:

  • Adding a feature? Add one test for the existing code while you’re there
  • Fixing a bug? Improve the variable names you encounter
  • Reviewing code? Suggest extracting one complex function
  • Reading old code? Add a comment explaining what it does

Small improvements compound over time.

Real Example: The 1,500-Line Function

A startup had a controller method that was 1,500 lines. Impossible to test. Impossible to understand. Every change broke something.

They didn’t schedule a refactoring sprint. Instead, they made a rule: every time someone touches this file, extract one method and add one test.

Month 1: Extracted 3 methods, added 3 tests (15% coverage) Month 3: Extracted 12 methods, 12 tests (40% coverage) Month 6: Down to 300 lines, 80% test coverage, clear structure

Cost: Zero extra. It happened during normal feature work.

Velocity improved because changes were faster and safer.

Tactics That Work for Incremental Improvement

Tactic 1: The 10-Minute Rule

When working on any file, spend 10 extra minutes improving it:

  • Fix obvious bugs you notice
  • Update outdated comments
  • Improve one confusing variable name
  • Extract one duplicated block
  • Add one missing type annotation

10 minutes per file adds up fast. If you touch 5 files per week, that’s 50 minutes of debt paydown weekly without dedicated time.

Tactic 2: The Two-Feature Rule

For every two features shipped, fix one piece of technical debt.

Makes debt paydown part of normal cadence instead of special project.

Example schedule:

  • Sprint 1: Feature A, Feature B, Refactor payment validation
  • Sprint 2: Feature C, Feature D, Update dependencies
  • Sprint 3: Feature E, Feature F, Add tests to auth flow

This ensures steady progress on debt without stopping feature work.

Tactic 3: The Strangler Fig Pattern

Named after strangler fig trees that gradually grow around and replace their host tree.

How it works:

  1. Identify one component to rebuild (start with least risky)
  2. Build new version alongside old version
  3. Route new traffic to new version
  4. Monitor for issues
  5. Once stable, remove old version
  6. Repeat with next component

Real example: A logistics platform rebuilt their route optimization:

  • Week 1-2: Built new algorithm as separate service
  • Week 3: Routed 10% of traffic to new service
  • Week 4: Increased to 50%
  • Week 5: Moved to 100%
  • Week 6: Removed old code

Total time: 6 weeks. Zero downtime. If new service failed, instant rollback to old one.

They rebuilt their entire platform this way over 18 months while continuing to ship features. Customers never noticed.

Tactic 4: Opportunistic Refactoring

Don’t refactor just to refactor. Refactor when you need to change something anyway.

Example: Adding OAuth support to your auth system. While you’re in that code:

  • Clean up the messy password validation
  • Add tests for existing flows
  • Extract hard-coded strings to config
  • Document the auth flow

You were going to be in that code anyway. Make it better while you’re there.

Tactic 5: The Deprecation Path

Can’t remove bad code immediately? Deprecate it gradually.

Steps:

  1. Build new version of the feature
  2. Mark old version as deprecated (add warnings)
  3. Migrate users to new version over time
  4. Remove old version once everyone’s migrated

Example: An API with a messy v1 endpoint:

  • Built cleaner v2 endpoint
  • Added deprecation notice to v1 docs
  • Emailed customers about v2 migration
  • Gave 6 months notice
  • Removed v1 after migration complete

No sudden breaks. Gradual, safe transition.

Tactic 6: Add Abstraction Layers

Can’t rebuild the gnarly code right now? Wrap it in a clean interface.

How it works:

  1. Create new API that makes sense
  2. Behind the API, call the ugly old code
  3. All new code uses the new API
  4. Gradually replace old implementation

Real example: A payments system had spaghetti code for calculating fees. Instead of rewriting:

  • Created a clean FeeCalculator class
  • FeeCalculator internally called old gnarly logic
  • All new code used FeeCalculator
  • Over time, replaced old logic piece by piece

Took 4 months total, zero downtime, no big-bang rewrite.

Allocate Regular Time for Debt

Even with incremental tactics, dedicate regular time specifically for debt reduction.

The 15-20% Rule

Companies leading their industries dedicate 15-20% of each sprint to technical debt work.

How it works:

  • 2-week sprint = 2-4 days for debt reduction
  • Rotate which engineers tackle debt
  • Track debt reduction as a KPI
  • Not “extra” time, it’s planned time

Why it matters: Regular small investments prevent catastrophic rewrites later.

How to Get Buy-In

Non-technical stakeholders resist dedicating time to “non-features.” Here’s how to frame it:

Instead of: “We need 20% of sprint for technical debt”

Say: “We’re currently shipping 8 features per quarter. If we invest 20% of time in code quality, we’ll ship 10 features per quarter within 6 months because features will be faster to build.”

Show the velocity improvement. Make it about outcomes, not activities.

One startup showed their CEO a chart: velocity declining from 12 features/month to 4 features/month over 18 months. Projecting forward, they’d be at zero velocity in another year.

CEO immediately approved 20% debt time.

Integrate Debt Work Into Workflow

Don’t treat debt as special. Make it part of how you work.

Code Review Standards

During code review, check for:

  • Are tests included?
  • Is this code readable?
  • Are there obvious improvements?
  • Does this add new debt?

If code adds debt without justification, it doesn’t merge.

One team added a “debt score” to PRs. If the PR increased debt significantly, it needed extra justification or refactoring.

Definition of Done

A feature isn’t done until:

  • Code is written
  • Tests are added
  • Documentation is updated
  • Related debt is addressed
  • Code is reviewed

Not “code works in dev.” Actually done.

Debt Tickets in Backlog

Treat technical debt like features:

  • Create tickets for each debt item
  • Prioritize in backlog
  • Assign to sprints
  • Track to completion

Make debt visible. If it’s invisible, it gets ignored.

Automated Tools

Use tools to catch debt before it grows:

Linters:

  • ESLint for JavaScript
  • Pylint for Python
  • RuboCop for Ruby

Code quality tools:

  • SonarQube (tracks code smells, duplicati on, complexity)
  • CodeClimate (automated code review)
  • Codacy (code quality metrics)

Dependency management:

  • Dependabot (auto PRs for dependency updates)
  • Renovate (smarter dependency management)
  • Snyk (security vulnerabilities in dependencies)

Set up CI/CD to fail builds that introduce too much debt.

One team configured SonarQube to fail PRs that:

  • Dropped test coverage below 60%
  • Added functions over 50 lines
  • Created files over 500 lines
  • Introduced critical code smells

Prevented new debt from accumulating.

Track Improvement Over Time

Measure these metrics monthly:

Code quality metrics:

  • Test coverage percentage
  • Lines of code per file (average)
  • Cyclomatic complexity (average)
  • Duplicate code percentage
  • Number of code smells

Velocity metrics:

  • Features shipped per sprint
  • Time from code start to production
  • Bug count in production
  • Deployment frequency

Team health:

  • Engineer satisfaction scores
  • Retention rate
  • Time to productivity for new hires

If code quality improves but velocity doesn’t, you’re doing it wrong. Both should improve together.

When to Do a Dedicated Refactoring Sprint

Sometimes incremental isn’t enough. Do a dedicated refactoring sprint when:

The debt is catastrophic:

  • Features are blocked completely
  • Production incidents are constant
  • Engineers are quitting
  • You failed investor due diligence

The fix is all-or-nothing:

  • Database migration that touches everything
  • Major framework upgrade (React 16 to React 18)
  • Switching authentication systems
  • Breaking API changes

You have runway and buy-in:

  • 6+ months of runway
  • CEO and board approve
  • Engineers are committed
  • Customers are informed

Even then, try to break it into incremental pieces if possible.

For major refactoring decisions, see Stop Rebuilding Your Product From Scratch.

Real Success Stories

Startup A: E-commerce Platform

  • Problem: Monolithic 35,000-line file
  • Approach: Boy Scout Rule for 12 months
  • Result: Broken into 47 modules, test coverage 18% to 71%, features ship 2.5x faster
  • Cost: Zero dedicated time, just incremental improvement

Startup B: B2B SaaS

  • Problem: Deployment took 4 hours, failed 30% of time
  • Approach: 15% of each sprint dedicated to CI/CD and deployment
  • Result: After 4 months, deployment takes 12 minutes, fails 2% of time
  • Cost: 15% of 4 engineers for 4 months = ~$50K, saved 100+ hours of incident response

Startup C: Fintech

  • Problem: Payment processing had 8 incidents in 6 months
  • Approach: Strangler fig pattern to rebuild payment system
  • Result: Zero incidents in 12 months since completion, feature velocity improved 40%
  • Cost: 2 engineers for 5 months = ~$100K, saved millions in incident costs

The Bottom Line

You don’t need to stop feature development to pay down technical debt.

What works:

  • Boy Scout Rule: Leave code better than you found it
  • 10-Minute Rule: Spend 10 extra minutes improving each file
  • Two-Feature Rule: For every 2 features, fix 1 debt item
  • Strangler Fig: Replace bad code incrementally, not all at once
  • 15-20% of sprint time for debt reduction

What doesn’t work:

  • “We’ll stop features for 3 months to refactor”
  • Waiting until debt becomes catastrophic
  • Treating debt as separate from feature work
  • No dedicated time at all

The key is making improvement part of your normal workflow, not a special project.

Small improvements compound over time. Six months of Boy Scout Rule beats one month of big-bang refactoring.

Need help establishing practices for managing technical debt? Book a call to discuss how to integrate debt reduction into your workflow without stopping feature development.

Ready to Build Investor-Ready Technology?

Get expert technical guidance without the full-time cost. Book a free strategy call to discuss your challenges.

Book Free 15-Min Strategy Call