Teknisk gæld: hvad det er, hvordan du måler den, og hvordan du betaler den ned

Teknisk gæld: hvad det er, hvordan du måler den, og hvordan du betaler den ned

Hvad er teknisk gæld?

Teknisk gæld er de ekstra omkostninger og den ekstra kompleksitet, der opstår, når du vælger en hurtig eller midlertidig teknisk løsning i stedet for en mere holdbar løsning. Du får fart nu, men betaler senere i form af dyrere ændringer, flere fejl og sværere vedligehold.

Begrebet stammer fra ideen om økonomisk gæld: du låner tid i dag og betaler renter i morgen. I udvikling betyder det typisk, at du vælger:

  • en hurtig workaround i koden
  • en simpel, men skrøbelig arkitektur
  • at springe tests, dokumentation eller oprydning over
  • at udskyde nødvendige opdateringer og modernisering

Det vigtige er, at teknisk gæld ikke kun handler om “dårlig kode”. Den kan være helt bevidst og rationel, for eksempel for at ramme en hård deadline. Problemet opstår, når gælden ikke synliggøres, ikke måles og ikke har en plan for tilbagebetaling.

Teknisk gæld er heller ikke det samme som legacy. Legacy er gamle eller svært ændrbare systemer. Teknisk gæld er de konkrete kompromiser og meromkostninger, der følger af de tekniske valg, du har truffet. Legacy kan være en stor kilde til teknisk gæld, men begreberne er ikke identiske.

Det gode er, at teknisk gæld kan behandles som netop gæld: du kan opgøre den, prioritere den og betale den ned over tid, i stedet for at lade den vokse i det skjulte.

Hvorfor er teknisk gæld et problem?

Teknisk gæld er et problem, fordi den gør udvikling langsommere, fejl dyrere og ændringer mere risikable. Samtidig kan den hæmme sikkerhed, skalerbarhed og forretningens hastighed, selv om alt på overfladen ser “OK” ud.

Når gælden vokser, viser det sig typisk som:

  • længere tid fra idé til produktion (lead time)
  • flere fejl og hotfixes efter hver release
  • mere manuelt testarbejde og brandslukning
  • højere supportbelastning og utilfredse brugere
  • større risiko ved hver eneste ændring

Her er en enkel måde at oversætte symptomer til forretningseffekt:

Signal Hvad det ofte betyder Forretningspåvirkning
Lead time bliver længere Det er svært at ændre eksisterende kode og arkitektur Langsommere time-to-market, tabte muligheder
Mange hotfixes efter releases Skjult kompleksitet og manglende testdækning Driftsforstyrrelser, dårlig brugeroplevelse, tabt tillid
Høj MTTR (lang tid til at løse incidents) Dårlig observability, uigennemsigtig kode og arkitektur Længere nedetid, direkte omsætningstab
Høj supportbelastning Fejl og særtilfælde er indbygget i løsningen Flere supporttimer, lavere kundetilfredshed
Kun få nøglepersoner forstår systemet Høj kompleksitet, manglende dokumentation og tests Stor personafhængighed og høj risiko ved jobskifte
Udsatte eller forældede opdateringer Sårbar infrastruktur og komponenter Øget sikkerhedsrisiko og compliance-problemer

Når du sætter de her signaler op imod budget og mål, bliver det tydeligt, at teknisk gæld ikke bare er udviklerfrustration. Det er en reel omkostning i tid, kroner og risiko.

Hvilke typer teknisk gæld findes der?

Teknisk gæld findes i flere former, og de vigtigste er kodegæld, arkitekturgæld, testgæld, dokumentationsgæld og infrastrukturgæld. De giver forskellige symptomer og kræver forskellige løsninger, så det er en fejl at behandle dem som én samlet klump.

Type Typiske signaler Hvordan den måles Typisk afhjælpning
Kodegæld “Spaghettikode”, duplikeret logik, svært læselige metoder, mange “quick fixes” Statisk kodeanalyse (fx code smells, maintainability-score), code review Refactoring, bedre struktur, nedbringelse af duplikation, enkle designmønstre
Arkitekturgæld Tæt kobling mellem services, svære integrationer, mange særlige undtagelser Arkitekturgennemgang, afhængighedskort, performance- og skaleringstests Forenkling af domænemodel, tydelige grænseflader (API’er), evt. strangler pattern
Testgæld Få automatiske tests, meget manuelt testarbejde, frygt for at ændre kode Test coverage, fejlrate efter deployment, tid brugt på regressionstest Opbygning af test-suite, fokus på kritiske flows, gradvis øget testdækning
Dokumentationsgæld Onboarding tager lang tid, “tribal knowledge”, README er forældet eller mangler Tid til onboarding, afhængighed af enkeltpersoner, gennemgang af docs Opdateret README, arkitekturoverblik, simple how-to-guides
Infrastrukturgæld Manuelle deploys, ustabile miljøer, forældede servere/OS/databaser Deploy-frekvens, nedetid, tid brugt på drift, antal manuelle trin Automatisering (CI/CD), opdatering eller skifte af platform/hosting

Legacy-systemer skærer ofte på tværs af alle typer: gammel kode, gammel arkitektur, næsten ingen tests, mangelfuld dokumentation og skrøbelig infrastruktur. Her vil en modernisering typisk kræve en kombination af refactoring, arkitekturrevision og ændringer i drift og deployment. Du kan læse mere om sammenhængen mellem arkitektur og praksis i vores introduktion til systemudvikling i praksis.

Hvordan måler man teknisk gæld?

Teknisk gæld måles bedst ved at kombinere statisk kodeanalyse, manuelle vurderinger og drifts- og forretnings-KPI’er. Værktøjer viser kun en del af billedet, så enhver score skal tolkes i konteksten af systemet, teamet og den faktiske drift.

1. Værktøjsmåling: statisk kodeanalyse

Værktøjer som SonarQube og lignende laver statisk kodeanalyse: de læser koden uden at køre den og vurderer fx:

  • antal og type code smells
  • kompleksitet og duplikeret kode
  • testdækning (hvis koblet til testkørsel)
  • sikkerhedsadvarsler

Mange værktøjer estimerer også en “remediation cost” eller “Technical Debt Ratio” i timer eller point. Det kan give et nyttigt fingerpeg, men det er vigtigt at huske:

  • scorerne er relative (god i én kodebase er ikke nødvendigvis god i en anden)
  • de dækker primært kodegæld, sjældent arkitektur, tests, dokumentation eller infrastruktur
  • værktøjet ser ikke forretningskontekst, risiko eller teamets erfaring

Brug derfor værktøjsdata som et objektivt udgangspunkt, ikke som sandheden om hele din tekniske gæld.

2. Manuel vurdering: arkitektur, tests og dokumentation

Nogle ting kan et værktøj simpelthen ikke se. Her er du nødt til at supplere med manuelle vurderinger, fx via arkitekturreviews, code reviews og testgennemgang.

Et praktisk greb er at score hvert hovedsystem på en simpel skala (fx 1-5) inden for:

  • arkitekturkvalitet (kobling, grænseflader, domænemodel)
  • testkvalitet (kritiske flows dækket, automatisk regressionstest)
  • dokumentation og onboarding
  • infrastruktur og deployment (automatisering, stabilitet)

Det behøver ikke være akademisk. Målet er at kunne sige: “Disse to systemer er tydeligt værre end resten, og her er hvorfor.”

3. Drifts- og forretnings-KPI’er

Den vigtigste forskel på “pæn” og “nyttig” måling er, om du kobler teknisk gæld til reel effekt. Det gør du med drifts- og forretningsdata, fx:

  • Lead time: tid fra ændring startes til den er i produktion
  • Deployment-frekvens: hvor ofte og hvor let I kan levere
  • Fejlrate: bugs pr. release, antal incidents
  • MTTR (Mean Time To Repair): tid til at løse en hændelse
  • Supportomkostninger: tid og penge brugt på brugerproblemer
  • Sikkerhedsfund: antal og alvor af kendte sårbarheder

Her kan det være en fordel at have styr på monitorering, logging og incident-håndtering. Hvis du ikke allerede har det, er guiden om systemdrift for udviklere et godt sted at starte.

4. Et simpelt scorecard for teknisk gæld

En praktisk måde at samle det hele på er at lave et lille scorecard pr. system eller produkt:

Dimension Eksempel på input Spørgsmål
Værktøjs-score Maintainability-score, antal kritiske code smells Ser koden væsentligt værre ud end i andre systemer?
Arkitektur & tests Subjektiv 1-5 rating på kobling, testdækning Er arkitektur og tests en reel barriere for ændringer?
Drift Lead time, MTTR, fejlrate Skaber gælden synlige driftsproblemer?
Forretning Omsætning/brugere, strategisk betydning Hvor vigtig er løsningen for forretningen?

Du behøver ikke én magisk totalscore. Pointen er at kunne pege på, hvor gælden gør mest ondt, så du kan prioritere nedbetalingen.

5. En enkel økonomisk estimering

Hvis du vil oversætte teknisk gæld til kroner, kan du bruge en simpel model som eksempel:

  • estimer timer til at udbedre en konkret gældspost (fx 120 timer)
  • gang med en intern fuldt belastet timeomkostning (fx 900 kr.)
  • så har du et ca.-beløb (120 × 900 = 108.000 kr.)

Det er ikke en præcis pris, men en måde at gøre størrelsesordenen konkret for ledelsen. Husk at nævne usikkerheden: estimatet bygger både på tekniske vurderinger og antagelser om timeomkostning.

Hvilke værktøjer og KPI’er bør du bruge?

De bedste værktøjer er dem, der passer til formålet: udviklerfeedback, ledelsesoverblik eller porteføljestyring. Brug værktøjer til kodeanalyse som supplement, men mål også lead time, fejlrate, MTTR og supportomkostninger for at få den fulde effekt.

Værktøjstyper

Du kan groft dele værktøjerne op i fire kategorier:

  • Udviklernære værktøjer til statisk kodeanalyse og feedback i pull requests (fx SonarQube). De hjælper med at holde kodegæld nede løbende.
  • Portefølje- og rapportværktøjer til at sammenligne systemer og teams på tværs og vise trends over tid.
  • Drifts- og observability-værktøjer (logs, metrics, tracing), som afslører hvor gælden skaber nedbrud og flaskehalse.
  • Projekt- og backlog-værktøjer, hvor du registrerer gældsposter som egentlige opgaver med estimeret omfang og prioritet.

Hvis du ikke allerede arbejder systematisk med metrics og logging, er artiklen om observability i praksis relevant som næste skridt.

KPI’er til dit tekniske gælds-dashboard

Et enkelt dashboard til teknisk gæld kan fx indeholde:

  • kode: maintainability-score, antal kritiske issues
  • drift: lead time, deployment-frekvens, MTTR, antal incidents
  • kvalitet: fejlrate pr. release, andel automatiske tests på kritiske flows
  • support: antal sager relateret til kendte tekniske begrænsninger

Vælg få, stabile KPI’er og følg dem over tid. Det er vigtigere at se retning og trend end at jagte én perfekt score.

Hvordan betaler man teknisk gæld ned?

Teknisk gæld betales bedst ned ved at registrere gældsposterne, prioritere dem efter risiko og effekt og afsætte fast kapacitet til gradvis refactoring eller modernisering, mens den normale udvikling fortsætter.

1. Registrér gælden som konkrete poster

Første skridt er at gøre gælden synlig. I praksis betyder det at oprette egentlige opgaver i jeres backlog:

  • hvad er problemet (kort og konkret)?
  • hvilken type gæld er det (kode, arkitektur, test, dokumentation, infrastruktur)?
  • hvad er konsekvensen i dag (risiko, tid, fejl, support)?
  • hvad er et realistisk bud på omfang (fx S/M/L eller timer)?

Det kan virke banalt, men erfaringen er, at “usynlig” gæld aldrig bliver betalt.

2. Prioritér: hvad skal løses først?

En enkel prioritering kan tage udgangspunkt i tre spørgsmål:

  • Hvor høj er risikoen (nedbrud, sikkerhed, kritiske fejl)?
  • Hvor meget forstyrrer det fremtidig udvikling (blokeringer, store ekstra-omkostninger)?
  • Hvor vigtig er den berørte del af systemet for forretningen?

Høj risiko + høj forretningsværdi kommer øverst. Lav risiko + lav forretningsværdi kan ofte vente.

3. Afsæt kapacitet til afdrag

Hvis teknisk gæld kun håndteres ad hoc, vinder nye features næsten altid. En mere holdbar model er at afsætte fast kapacitet hver iteration eller hver sprint, fx:

  • 10-20 % af teamets kapacitet bruges konsekvent på gæld og forbedringer
  • større, aftalte oprydningsopgaver planlægges som egentlige leverancer

Pointen er, at nedbetaling bliver en del af normalen, ikke et særprojekt, der konstant skubbes.

4. En 30/60/90-dages afdragsplan (eksempel)

En konkret måde at komme i gang er at lave en kort afdragsplan over et kvartal:

De første 30 dage

  • kortlæg 3-5 vigtigste systemer og lav simple scorecards
  • identificér de 10-20 værste gældsposter (høj risiko / stor effekt)
  • opret dem i backloggen med ejer, estimeret omfang og kort konsekvensbeskrivelse
  • afklar med ledelsen hvor stor en andel af kapaciteten, der må gå til gæld

Dag 31-60

  • angrib de hurtige gevinster (lavt omfang, høj effekt)
  • planlæg 1-2 større oprydningsopgaver som deciderede leverancer
  • mål effekten: mindre fejl, hurtigere ændringer, mindre support på udvalgte områder

Dag 61-90

  • evaluér: hvad gav mest effekt pr. investeret time?
  • justér prioriteringskriterier og kapacitet baseret på erfaringerne
  • forankr fast “afdragsprocent” af kapaciteten i jeres roadmap og governance

Herefter kan afdrag på teknisk gæld blive en løbende rytme, ikke et engangsprojekt.

5. Typiske nedbetalingsgreb

Afhængig af gældstypen vil du ofte vælge forskellige greb:

  • Kodegæld: løbende refactoring, bedre struktur, fjerne duplikation
  • Arkitekturgæld: introducere klare API-grænser, dele systemer op, forenkle domænemodel
  • Testgæld: starte med automatiske tests på de vigtigste brugerrejser
  • Dokumentationsgæld: skrive/forbedre README’er og enkle arkitektur-diagrammer – se fx guiden om README’er der faktisk bliver læst
  • Infrastrukturgæld: automatisere builds og deploys, rydde op i miljøkonfiguration – her kan CI i lille skala være et godt startpunkt

Hvornår giver teknisk gæld mening?

Teknisk gæld kan være acceptabel, når den er bevidst, dokumenteret og tidsafgrænset. Den bliver problematisk, når den er skjult, vokser ukontrolleret eller mangler en plan for nedbetaling.

Du kan bruge et lille beslutningsflow:

  • Er gælden et bevidst trade-off?
    Hvis ja: er valget dokumenteret (fx i backlog eller arkitektur-noter)?
  • Er der en plan?
    Findes der en konkret opgave eller milepæl, hvor gælden skal nedbringes?
  • Er risikoen forstået?
    Ved team og ledelse, hvad der kan ske, hvis oprydningen udskydes?
  • Er tidsrammen realistisk?
    Er “midlertidig” reelt måneder og ikke år?

Hvis du kan svare ja til disse punkter, kan teknisk gæld være et fornuftigt middel til at øge hastigheden kortvarigt, fx for at få en MVP i brug eller ramme en vigtig markedsmulighed.

Hvis svaret er nej, er du reelt i gang med at opbygge skjult risiko, uanset hvor pæn koden ellers ser ud på overfladen.

Hvordan gør man teknisk gæld til et ledelsesproblem?

Teknisk gæld bliver et ledelsesproblem, når den påvirker budget, risiko, tid til markedet og forretningens evne til at levere. Derfor bør den styres som en portefølje med klare ejere, prioritering og synlige beslutninger.

Oversæt teknik til ledelsessprog

Ledelsen reagerer sjældent på “vores kode er grim”. De reagerer på:

  • øget risiko for nedbrud og sikkerhedshændelser
  • lavere leveringshastighed og tabte muligheder
  • stigende drifts- og supportomkostninger
  • afhængighed af få nøglepersoner

Når du præsenterer teknisk gæld, så bind den til konkrete nøgletal og eksempler: “Vi bruger ca. X timer om måneden på support relateret til dette modul” eller “Hver ændring her tager typisk to uger længere end andre steder”.

Styr gæld som en portefølje

På ledelsesniveau kan teknisk gæld styres lidt som investeringer:

  • lav en oversigt over de største gældsposter pr. system/produkt
  • marker risiko (høj/mellem/lav) og strategisk betydning
  • estimér omfanget af oprydning i grove træk
  • diskutér, hvor meget budget og kapacitet der årligt allokeres til nedbetaling

Det handler ikke om at fjerne al gæld, men om at vælge, hvor den er acceptabel, og hvor den ikke er det. Det er klassisk porteføljestyring, bare med tekniske aktiver.

Gør aftalerne eksplicitte

Til sidst er der governance-delen:

  • Beslut om der skal være en fast “afdragsprocent” på alle teams.
  • Definér hvem der ejer den samlede oversigt over teknisk gæld.
  • Få teknisk gæld på agendaen i de møder, hvor roadmap og budget besluttes.

Når teknisk gæld bliver behandlet på linje med andre investeringer, forsvinder den lidt diffuse “vi burde også rydde op engang” og bliver til konkrete valg.

Hvad ser teknisk gæld ud som i praksis?

I praksis ser teknisk gæld ofte ud som forældede platforme, svære integrationer, manglende tests, tynd dokumentation eller kode, der gør selv små ændringer dyre og risikable. Det er sjældent én stor katastrofe, men mange små besværligheder, der lægger sig oven på hinanden.

Eksempel 1: Fire CMS’er bliver til ét

Et klassisk eksempel på teknisk gæld og nedbetaling er organisationer, der driver flere CMS-platforme samtidig. Hver platform har sine licenser, integrationspunkter, deployment-pipeline og sit eget team eller leverandør.

Gælden viser sig som:

  • høj licens- og driftsomkostning
  • svært ved at genbruge funktionalitet på tværs af sites
  • mange forskellige måder at integrere på
  • forøget sikkerheds- og compliance-arbejde

En målrettet nedbetaling kan her være at konsolidere til ét fælles CMS. Det kræver et moderniseringsprojekt, men kan til gengæld give store, konkrete besparelser i licenser og drift, plus en enklere arkitektur og hurtigere ændringer bagefter.

Eksempel 2: Ældre platforme og databaser

I mange kodebaser lever gamle database-strukturer og manuelle ændringsprocedurer videre, fordi de “altid har virket”. Det er klassisk infrastrukturgæld og ofte også arkitekturgæld.

Symptomerne er fx:

  • hver databaseændring føles risikabel
  • ændringer deployes manuelt og sent om aftenen
  • “det virkede på min maskine” opstår ofte

Her kan nedbetaling handle om at indføre sikrere mønstre for databaseændringer og deployment. Hvis du kan genkende de her symptomer, er guiden om database-migrationer i teams et godt sted at hente konkrete mønstre.

Eksempel 3: Dokumentation og onboarding

Endnu et typisk billede: nye udviklere bruger uger på at forstå et system, fordi det meste viden kun findes i hovedet på en enkelt senior. Hver gang noget skal ændres, tager det lang tid at finde ud af hvor og hvordan.

Det er dokumentationsgæld. Nedbetalingen er sjældent fancy: en ordentlig README, et opdateret arkitekturdiagram og et par korte “sådan sætter du projektet op”-noter kommer overraskende langt. Det kræver disciplin, men ikke nødvendigvis store projekter.

Næste skridt

Hvis du vil arbejde mere systematisk med teknisk gæld, kan du med fordel:

Det vigtigste er at komme i gang i det små: gør gælden synlig, mål hvor den gør mest ondt, og afsæt fast kapacitet til at betale den ned. Resten kan du bygge op over tid.

Brug en kombination af kvantitative og kvalitative målepunkter: testdækning, statiske analyser (f.eks. SonarQube), kompleksitetsmål, antal hotfixes, lead time og MTTR. Før samtidig en simpel gældsliste eller backlog med beskrivelser og risikoniveau, så du kan følge trend over tid frem for kun enkeltstående tal.
Prioriter efter forretningspåvirkning, sandsynlighed for fejl og indsats til udbedring; vælg først høj risiko/høj påvirkning med lav til medium indsats. Brug en enkel scoremodel (impact gange probability divideret med effort) og inddrag produkt- og driftsejere, så prioriteringen er forretningsdrevet.
Afse en fast del af kapaciteten til teknisk gæld hver sprint - typisk 10-20 procent - eller book faste refaktorings-iterationer. Kræv at nye features leveres med tests og dokumentation, og kanaliser små forbedringer som del af normal feature-udvikling for gradvis nedbringelse.
Lav et lille spike eller proof of concept for at få realistiske timeestimater, brug t-shirt sizing for overblik og bryd arbejdet op i små stories. Medtag test, QA og deployment i estimatet, og beregn forventede gevinster i form af færre fejl eller kortere lead time for at vurdere ROI.

Mikkel Schrøder er den dér stille type, der i årevis har siddet om aftenen med en kop kaffe og et åbent kodeprojekt, mens resten af huset er ved at falde til ro. Hans interesse for kodning startede, da han som teenager forsøgte at lave en simpel hjemmeside til sit favorit-fodboldhold og opdagede, at man kunne ændre alt ved at rode med HTML og CSS. Siden har han lært tingene ved at prøve sig frem, læse forumtråde og pille ved små projekter, indtil de gjorde det, han ville.

På Coding Class deler han ikke perfekte løsninger fra et glansbillede-univers, men de ting han faktisk selv har bokset med: mærkelige JavaScript-fejl, CSS der ikke opfører sig som forventet, og små Python-scripts, der starter i kaos og ender med at spare tid i hverdagen. Han kan godt lide at vise både den første, halvdårlige løsning og den forbedrede udgave, så du kan se forskellen og forstå tankegangen bag.

Mikkel brænder for at gøre programmering mindre skræmmende for dem, der ikke ser sig selv som "tech-typer". Derfor skriver han på helt almindeligt dansk, med små, konkrete kodeeksempler og fokus på, hvordan du selv kan komme fra teori til noget, der faktisk virker. På Coding Class forsøger han at bygge bro mellem manual-sproget og virkeligheden ved at vise, hvordan det føles at sidde med fejlen klokken 22.30 – og hvad der skulle til, før den forsvandt.

1 kommentar

comments user
Allan M.

Interessant. Den del om måling af teknisk gæld gemmer jeg til senere.

Send kommentar

You May Have Missed