Gartner: 80% of Tech Debt Will Be Architectural by 2026. Are We Solving the Wrong Problems With Linters?

Here’s something that’s been bothering me lately, and I’m curious if others see the same pattern.

Last year at my startup (before it went sideways :sweat_smile:), we had a beautiful component library. Every PR had to pass ESLint, Prettier, SonarQube—the works. Our code quality scores were pristine. 95%+ on every metric. The team was proud of how clean everything was.

And yet… we struggled to scale. Simple features took weeks. Every new requirement felt like navigating a minefield. When we finally shut down and did the post-mortem, we realized: our code was perfect, but our architecture was a disaster.

We’d coupled our auth system to every single component. Our data layer was tangled across features. Service boundaries? What service boundaries?

None of our tools caught this. SonarQube gave us an A+. ESLint was happy. Our linters measured what was easy to measure—style, complexity, duplicates—but completely missed that we’d built a tightly coupled mess.

The Gartner Wake-Up Call

Fast forward to now: Gartner predicts that by 2026, 80% of technical debt will be architectural technical debt. Not code quality issues. Not bugs. Architectural decisions.

And here’s the kicker: most of our debt reduction efforts focus on code-level problems that tools like linters can catch automatically.

Code Quality ≠ Architectural Quality

Here’s the distinction I wish I’d understood earlier:

Code quality issues:

  • Bugs in individual files
  • Inefficient algorithms
  • Security vulnerabilities in specific functions
  • Style inconsistencies
  • What linters catch: :white_check_mark: All of this

Architectural debt:

  • Wrong service boundaries
  • Tight coupling between modules
  • Missing abstraction layers
  • Circular dependencies
  • Architectural drift from original design
  • What linters catch: :cross_mark: Almost none of this

As one article puts it: “Architectural debt is not visible in a pull request and doesn’t appear as a broken unit test or a security vulnerability in a code scanner.”

You literally can’t PR-review your way out of architectural debt.

Why Architectural Debt Has Higher “Interest Rates”

The research is clear: architectural technical debt incurs the highest “interest rates” and imposes the most significant constraints on system evolution.

When you have poor architecture:

  • Entire teams slow down, not just individual developers
  • Compound effects: Bad architecture decisions cascade into more bad decisions
  • Invisible until too late: No failing tests, no security alerts, no linter warnings
  • By the time you notice, you’re already deep in the hole

Meanwhile, a missing semicolon? Your linter catches it in 0.3 seconds. :woman_facepalming:

The Measurement Gap

Tools like SonarQube measure what’s easy to measure:

  • Lines of code :white_check_mark:
  • Cyclomatic complexity :white_check_mark:
  • Code coverage :white_check_mark:
  • Duplicate code :white_check_mark:

But they can’t measure:

  • Are our service boundaries wrong? :cross_mark:
  • Are these modules too tightly coupled? :cross_mark:
  • Did we miss a critical abstraction layer? :cross_mark:
  • Is this feature built in the right place architecturally? :cross_mark:

Current technical debt tools still rely heavily on manual efforts and piecemeal knowledge to assess architectural risk.

So… How Do You Even Detect Architectural Drift?

This is where I’m genuinely stuck:

  • Code reviews don’t help — Too zoomed in, focused on the trees not the forest
  • Architecture Decision Records (ADRs) — Great for documentation, but don’t enforce anything
  • Manual architecture audits — Expensive, infrequent, often happen too late

My question for the community: Are we investing in the wrong layer of debt reduction?

We’ve automated code quality enforcement (linters, CI checks, scanners). But the research says 80% of our actual debt is architectural, and we have almost no automated tools for that.

Questions I’m Wrestling With:

  1. How do you measure architectural health? What metrics actually matter?

  2. Have you ever “fixed” code debt only to realize the architecture was the real problem? I’d love to hear war stories.

  3. What tools or practices actually catch architectural drift early? Before it becomes a multi-month refactoring project?

  4. Should we care less about linter scores and more about… what exactly? System diagrams? Dependency graphs? Deployment topology?

Maybe the uncomfortable truth is that architectural governance requires human judgment and ongoing attention—and we keep defaulting to linters because they’re easy to automate. :woman_shrugging:

But if Gartner’s right and 80% of our debt is architectural, we might be optimizing for the wrong thing entirely.

What do you all think? Am I overthinking this, or are we collectively solving the wrong problems?


Sources:

You’ve nailed something that keeps me up at night, Maya. This resonates deeply from the executive perspective.

Last year, I led a cloud migration at my previous company. Our engineering team was proud—SonarQube scores were excellent, code coverage above 85%, security scans clean. The board loved seeing those green checkmarks in our quarterly reviews.

But the reality? We had a beautifully polished monolith that was architecturally impossible to decompose.

The codebase was “clean” by every automated metric. But services were tightly coupled through shared databases. Business logic was scattered across layers. Domain boundaries didn’t exist. When we tried to extract microservices, we discovered circular dependencies that no linter had ever flagged.

It took us 18 months to untangle. And during that time, our feature velocity dropped 40%. Try explaining THAT to a board when “your linter is green.”

The Executive Challenge

Here’s what’s particularly painful from the CTO chair: How do you justify architectural refactoring to a CFO who sees clean code quality reports?

The conversation goes like this:

  • CFO: “Why are we slowing down? Your metrics look great.”
  • Me: “We have architectural debt.”
  • CFO: “But SonarQube says A+. What’s the actual problem?”
  • Me: “Our service boundaries are wrong.”
  • CFO: “Can we hire more people to go faster?”
  • Me: “That will make it worse.”

Linter scores don’t help when you’re trying to explain why a “simple” feature now takes 3 sprints instead of 1.

What Actually Works at Scale

From leading engineering orgs at Microsoft, Twilio, and now here, I’ve found a few things that help:

1. Architecture Fitness Functions

  • Automated tests that enforce architectural constraints
  • Example: “No service in domain A can directly call domain B’s database”
  • Like linters, but for architecture rules
  • Tools: ArchUnit, NDepend, fitness-function-based testing

2. Domain-Driven Design Boundaries + Deployment Topology

  • Don’t just document bounded contexts—enforce them through separate deployments
  • If teams CAN’T deploy coupled code, they won’t write coupled code
  • Platform constraints as architectural governance

3. Regular Architecture Audits (Quarterly, Not Yearly)

  • Dependency graph reviews in planning sessions
  • “Architectural health” as explicit OKR
  • Review coupling metrics alongside velocity metrics

The Real Measurement Problem

You’re absolutely right that we measure inputs (code quality) not outputs (system evolvability).

What I want to measure:

  • Time to add a new feature (trending up = architectural debt)
  • Blast radius of changes (how many services touched per PR)
  • Coupling metrics (dependencies between modules/services)
  • Team cognitive load (do engineers understand the system?)

What we actually measure:

  • Lines of code
  • Code coverage
  • Cyclomatic complexity

The disconnect is real.

Provocative Thought: Do We Need “Architectural Linters”?

Maybe the answer isn’t just human judgment—maybe we need automated tools that enforce architectural boundaries the way linters enforce code style.

Tools that:

  • Detect service dependency violations
  • Flag coupling increases over time
  • Measure “architectural drift” from documented design
  • Fail CI/CD when boundaries are violated

Some of this exists (NX module boundaries, import linters, AWS SCPs), but it’s nowhere near as mature or widespread as code linters.

My Question Back to the Community

Has anyone successfully quantified architectural debt in dollar terms for executive buy-in?

I can show my CFO that technical debt costs us X% velocity loss, but translating that to revenue impact or customer churn is hard. If I could say “this architectural coupling will delay our Q3 roadmap by M in lost revenue,” I’d get budget for refactoring immediately.

How do you make architectural health legible to non-technical executives?

Great post, Maya. This is exactly the kind of strategic conversation we need to be having.

Both Maya and Michelle are hitting on something critical, and I want to add the distributed team dimension that makes this even harder.

Architectural Drift Is Worse With Remote/Global Teams

At my current company (financial services), we have engineering teams in Austin, Mumbai, and London. When everyone was co-located, we had implicit architectural understanding—the kind of knowledge that lived in hallway conversations and whiteboard sessions.

Remote work broke that. What was “obvious” to someone who joined in 2019 became undocumented tribal knowledge in 2023.

Here’s a real example that cost us dearly:

The Payment-Notification Circular Dependency Incident

  • Team in Austin built a payment processing service (beautiful code, 92% test coverage)
  • Team in Mumbai built a notification service (also clean, passed all linters)
  • Both teams were working in parallel, different time zones, minimal overlap
  • Nobody realized they’d created circular dependencies between services

The payment service called the notification API to send receipts. The notification service called the payment API to check transaction status before sending emails. When one service went down, both went down in a cascading failure.

No tool caught this. SonarQube was happy. Our import linters didn’t flag it because they were separate repos. It only surfaced during a production incident at 2am.

The Documentation Gap

Michelle mentioned ADRs (Architecture Decision Records), and I agree they’re valuable—IF people write them and read them.

In practice:

  • Under deadline pressure, ADRs get skipped
  • New engineers don’t know to check them
  • They become stale quickly
  • They document decisions but don’t prevent violations

Linters enforce code standards automatically. We need similar automation for architecture. You don’t need to “remember” to run ESLint—it runs in pre-commit hooks. Why don’t we have the same for architectural constraints?

Practical Patterns That Help

Here’s what we’ve implemented that’s actually working:

1. Module Boundaries Enforced via Import Linting

  • Tools like NX, eslint-plugin-boundaries
  • Define which modules can import from which other modules
  • Fails CI if you violate boundaries
  • Example: “Payment domain can’t import from Billing domain”

2. Auto-Generated Dependency Graphs

  • C4 diagrams generated from actual code dependencies (not manually drawn)
  • Updated automatically in CI
  • Reviewed in quarterly architecture planning
  • Makes drift visible quickly

3. Dependency Review in Sprint Planning

  • Before any cross-service change, review dependency graph
  • Ask: “Does this create new coupling?”
  • Track coupling metrics over time

The Challenge: Codifying “Good Architecture”

Here’s where I partly disagree with the “we just need better tools” narrative:

Code standards are universal: Indentation, naming conventions, cyclomatic complexity thresholds work across most codebases.

Architecture standards are contextual: What’s “good architecture” depends on:

  • Domain complexity
  • Team size and distribution
  • Scale/performance requirements
  • Regulatory constraints
  • Legacy system integration needs

In fintech, we need stronger isolation boundaries than a simple CRUD app. Our architectural rules are stricter. How do you build a “linter” for that?

Agrees on Visibility

Michelle’s point about making architectural health visible to leadership is spot-on. At my level (Director), I can see the pain—engineers saying “this should be easy but it’s taking forever.”

But quantifying it for executives is hard. We track:

  • Feature cycle time trends (if simple features take longer over time, likely architectural debt)
  • Number of services touched per feature (increasing = growing coupling)
  • Incident blast radius (cascading failures suggest tight coupling)

But translating that to business impact? Still figuring it out.

Maya, your original question—“Are we solving the wrong problems?”—the answer is yes, because we’re solving the easy problems.

Automated linting is tractable. Architectural governance requires judgment, context, and ongoing human attention. That’s why we default to what’s automatable, even though it misses 80% of the actual debt.

Great discussion. Would love to hear how others handle this on distributed teams.

This thread is gold. I’m coming at this from the product side, and I want to translate what you’re all saying into the language that shows up in board meetings—because that’s where architectural debt becomes a strategic crisis.

The Business Pain: Architectural Debt = Lost Product Optionality

Last quarter, we wanted to add multi-tenancy to our B2B SaaS product. Seemed straightforward—just add customer IDs to tables, right?

Engineering came back with: “6 months minimum.”

The board was shocked. “It’s just adding a field to the database. Why does it take half a year?”

Turns out: Our entire auth system, data access layer, and API design assumed single-tenant. User sessions were coupled to the database schema. Permissions were hardcoded. We’d have to refactor 40% of the codebase.

This is architectural debt showing up as product strategy constraint.

Nobody cared that our linter scores were high. What mattered was: We couldn’t build the feature our biggest enterprise prospect needed. We lost the deal.

The Communication Challenge

Here’s what’s hard from the product-engineering boundary:

Easy to explain: “We need to fix bugs.” (Linters catch bugs, clear ROI)

Hard to explain: “We need to refactor service boundaries.” (Abstract, no visible customer impact)

When engineers say “architectural debt,” PMs hear “we want to rewrite code that already works.” When PMs push back, engineers feel unheard.

Linter reports give concrete numbers. “147 code smells, 23 security vulnerabilities”—I can show that to stakeholders.

Architectural issues are nebulous. “Our services are too coupled”—what does that even mean in business terms?

Why This Matters for Product Strategy

Bad architecture doesn’t just slow down current features—it limits future product optionality.

Examples from our roadmap:

  • Can’t build mobile app: Auth system is coupled to web browser sessions
  • Can’t offer API to customers: Internal APIs aren’t designed for external use
  • Can’t expand to EU market: Data residency controls don’t exist architecturally
  • Can’t do usage-based pricing: Metering isn’t instrumented in service layer

Each of these is a business opportunity we can’t pursue because of architectural decisions made 3 years ago when we were a 10-person startup.

Michelle’s question about quantifying this in dollar terms? Here’s my attempt:

Architectural Debt = Lost Revenue Opportunities

Product Capability Revenue Impact Blocked By Architecture Est. Refactor Time
Multi-tenancy for enterprise M ARR deals Single-tenant assumptions 6 months
Mobile app 30% user growth Web-coupled auth 4 months
EU expansion M TAM No data residency design 8 months
API for partners M partnership revenue Internal-only API design 3 months

Total opportunity cost: ~M+ in blocked revenue.

That’s the language CFOs and boards understand. Not “we have technical debt”—but “we’re leaving M on the table because of architectural decisions.”

Measurement from Product Perspective

Luis mentioned feature cycle time—that’s exactly what we track on the product side:

“Feature Complexity Score” Over Time

We rate every feature as Simple/Medium/Complex based on scope. Then track:

  • How long Simple features take
  • Trend over time

When “simple” features start taking 2-3 sprints instead of 1, that’s architectural debt showing up.

Example: Adding a new notification type used to be 2 days. Now it’s 2 weeks because our notification system is tangled with payment logic, user preferences, and email templates.

Velocity trends tell the story linters miss.

Should Architectural Refactoring Be in Product Roadmap?

Here’s a provocative question: Should product leaders co-own architectural decisions?

Traditionally:

  • Engineering owns “technical debt”
  • Product owns “features and roadmap”

But architectural decisions directly impact product strategy:

  • What markets can we enter?
  • What customer segments can we serve?
  • What integrations can we build?
  • How fast can we experiment?

At my previous company (Airbnb), product and engineering jointly owned platform investments. We had a “Platform Roadmap” separate from “Feature Roadmap,” and both rolled up to company OKRs.

Maybe the real issue is that architectural health is treated as an engineering concern when it’s actually a product-engineering shared responsibility.

Agrees on Tooling Gap

Maya’s original point stands: We have sophisticated tooling for code quality, almost nothing for architectural quality.

What I wish existed:

  • “Architectural Health Dashboard” that shows coupling trends, boundary violations, feature velocity impact
  • Translate technical metrics to business metrics: “This coupling will slow Q3 roadmap by 30%” instead of “This violates SOLID principles”
  • Predictive analytics: “At current architectural drift rate, feature velocity will drop 20% by Q4”

If someone builds this, I’ll buy it. :sweat_smile:

Great thread. This is exactly the kind of cross-functional conversation that prevents architectural debt in the first place.

This conversation is hitting all the right pain points. I want to add the organizational scaling dimension—because architectural debt compounds exponentially as teams grow.

Scaling Organizations Amplifies Architectural Debt

When I joined my current EdTech company 2 years ago, we had 25 engineers. Today we’re at 80+. The scaling journey exposed something critical:

Small teams can manage architectural complexity through implicit knowledge.

At 25 people:

  • Everyone knew the system architecture
  • Tribal knowledge filled the gaps
  • Architectural decisions happened in Slack threads
  • Code reviews caught most boundary violations

Large teams lose implicit architectural understanding.

At 80+ people:

  • New engineers join weekly
  • Cross-team dependencies multiply
  • Nobody has full system context
  • Architectural drift accelerates

Maya’s linter comparison is perfect: Linters are the great equalizer for junior engineers. They encode team standards so new people don’t need to “just know” them.

We have no equivalent for architecture.

The Junior Engineer Problem

Here’s what keeps me up at night:

Junior engineers rely on linters to learn code standards. ESLint teaches them: “Don’t use var, use const.” SonarQube teaches them: “Reduce cyclomatic complexity.”

But nobody teaches them system boundaries.

Result? Well-formatted code that violates architectural principles.

Real example from last quarter:

  • Junior engineer (3 months tenure) built a new feature
  • Code review: beautiful—clean, tested, passed all linters
  • Shipped to production
  • Problem: They’d imported from a module they shouldn’t have, creating a circular dependency
  • No tool flagged it. Code reviewers didn’t catch it because they were focused on code quality, not architectural boundaries.

The incident caused a rollback and 4 hours of downtime.

Scaling Makes This Worse: The 25→80 Journey

When we scaled from 25 to 80+ engineers in 18 months, here’s what happened:

Code quality stayed high:

  • Linters enforced standards
  • PR reviews caught bugs
  • Test coverage remained above 80%
  • SonarQube scores: A+

Architectural coherence degraded rapidly:

  • Multiple teams built overlapping services
  • Service boundaries blurred
  • Tight coupling emerged organically
  • Cross-team dependencies grew unchecked

Why? Because linters scale, but implicit architectural knowledge doesn’t.

What Actually Helped

We implemented several things that moved the needle:

1. Platform Team with Enforcement Power

Not just “platform team that suggests standards.” A team with veto power on cross-boundary changes.

  • Any PR that touches multiple domains → Platform team review required
  • They don’t just advise—they can block merges
  • Controversial, but necessary at scale

2. Architecture Guild with Decision Authority

Monthly architecture review sessions:

  • Review dependency graphs
  • Flag architectural drift
  • Make binding decisions on service boundaries
  • Document in ADRs (with enforcement)

3. “Architectural Health” as Explicit OKR

Made architecture a first-class metric:

  • OKR: “Reduce cross-service coupling by 20% this quarter”
  • Measured via automated dependency analysis
  • Tied to team performance reviews

When architecture is just “something engineering cares about,” it gets deprioritized. When it’s an OKR, it gets attention.

The People Problem Linters Can’t Solve

Luis’s point about contextual architecture is critical. Here’s the deeper issue:

Linters enforce objective rules:

  • “No var, use const” → Universally correct
  • “Max cyclomatic complexity = 10” → Objectively measurable

Architecture requires judgment:

  • “Should this be a separate service?” → Depends on domain, scale, team structure
  • “Is this coupling acceptable?” → Depends on change frequency, performance needs

How do you enforce judgment at scale?

This is where the human element can’t be automated away. But we CAN add guardrails.

Architecture Needs Guardrails, Not Just Guidelines

What I wish we had:

Automated Architectural Checks:

  • Service dependency direction (no cycles, enforce DAG)
  • Module coupling thresholds (flag when coupling increases)
  • API contract violations (detect breaking changes)

Tools that already exist (underutilized):

  • AWS Service Control Policies (prevent certain cross-service calls)
  • NX module boundaries (enforce import restrictions)
  • ArchUnit (architecture tests in CI/CD)
  • Fitness functions (test architectural constraints)

What’s missing:

  • Wide adoption of these tools
  • Integration into standard workflows
  • Maturity level comparable to linters

Links Back to Maya’s Core Question

Maya asked: “Are we solving the wrong problems?”

Yes—we’re solving the easy problems because they’re automatable.

  • Code linting: Easy to automate, objective rules, universal applicability
  • Architectural governance: Requires judgment, context-dependent, ongoing human attention

That’s why we default to linters even though they miss 80% of the debt.

The uncomfortable truth: Architectural health requires senior engineering time and ongoing attention. You can’t “set it and forget it” like a linter config.

But at scale, that human attention is exactly what’s scarce. We need to automate what we can and ruthlessly prioritize where humans add judgment.

My Answer to David’s Question

David asked: Should architectural refactoring be in the product roadmap?

Yes, absolutely. But not framed as “refactoring”—framed as “expanding product optionality.”

At my previous company (Slack), we had quarterly “Platform Investment” sprints explicitly on the roadmap. Not hidden as “20% time”—visible to the board.

Why? Because platform investments unlocked future product velocity. And when product leaders co-owned architectural decisions, they understood the tradeoffs.


Amazing thread. This is the strategic conversation engineering leadership needs to have—not just with each other, but with product, design, and executive teams.

If 80% of our debt is architectural, we need 80% of our tooling, processes, and leadership attention focused there. Right now, it’s inverted.