The system runs in production, customers depend on it, and the only person who knew how it worked has left. Reading the whole codebase front to back feels responsible and is the slowest possible route. The goal for the first two weeks is not understanding - it is the ability to make a small change safely, because that capability is what converts an unknown system into a maintainable one. We do this as the opening phase of legacy modernization work.
01Get it running before you read anything
A system you cannot run is a system you cannot learn. Before reading code, get it building and running locally or in a scratch environment, and write down every undocumented step you had to discover. That document is now the onboarding guide that did not exist.
Expect this to take days rather than hours, and expect to find dependencies on things nobody mentioned: a specific runtime version, a seeded database, an environment variable with no default, a service that only exists in production. Each one you find is a handover risk removed.
02Follow one real request all the way through
Pick the most important thing the system does - a checkout, a booking, a report - and trace one request from entry point to database and back. This gives you the actual architecture rather than the one on the diagram, and it crosses every layer that matters in the order they execute.
Write it down as you go, in prose, with file names. Doing this once for the core flow teaches more than a week of reading modules in isolation, because it shows you which code is on the critical path and which is peripheral.
03Let production tell you what matters
A large codebase is rarely uniformly important. Logs, error tracking and request metrics show which endpoints carry real traffic, which paths fail, and which modules have not executed in months. Code with no traffic is code you can learn later or delete.
This also finds the dead surface. In most inherited systems a meaningful fraction of the code is unreachable - features switched off, migrations completed years ago, integrations with partners who left. Confirming that from production data rather than by reading is far faster and much more reliable.
| Question | Where the answer is | Why it matters first |
|---|---|---|
| How do I run it? | Your own build attempt | Nothing else is possible without it |
| What does it do most? | Request logs and metrics | Tells you which code to learn |
| What breaks most? | Error tracker, support tickets | Predicts your first real work |
| What is not covered? | Test suite and coverage | Defines where changes are risky |
| What is scheduled? | Cron, queues, background jobs | The usual source of surprises |
04Write a characterisation test before your first change
You cannot refactor safely without a test, and you cannot write a meaningful test for behaviour you do not yet understand. The way out is a characterisation test: assert what the system currently does, including anything that looks wrong, so a change that alters behaviour fails loudly.
This deliberately locks in bugs, and that is correct at this stage. Something downstream may depend on the current behaviour, and you cannot know which parts are load-bearing until you have context. Fix them deliberately later, one at a time, with the test updated in the same commit.
05Ship something small and boring in week two
A copy change, a logging improvement, a dependency bump. The point is not the change, it is proving the whole path works: you can build it, test it, deploy it and roll it back. Until that has happened once, every estimate about this system is a guess.
Teams that skip this and start with a significant change discover the deployment process is broken at the worst possible moment, usually while trying to fix something urgent. Find that out on a change you do not care about.
- Confirm you can roll back, not just deploy forward.
- Check that staging genuinely resembles production before trusting it.
- Note who must approve a release, and whether that person still works here.
- Record how long the full cycle took - it is your delivery baseline.
Topics
Lena Voss
Lead Architect · SyncTrix
Writes about the engineering decisions behind production systems - architecture, delivery and the trade-offs that only show up at scale.
Building something like this?
SyncTrix engineers AI, SaaS, platform and cloud systems for enterprises and high-growth teams. Tell us what you're shipping and we'll scope it with you.