"We bought a startup for $2M. A month later, we learned the code needed to be rewritten from scratch."
An investor showed me their "acquisition": 3 years of development, 150K lines of code, a "working product" with 5K users. Looked great in the demo.
After 2 weeks of technical audit, the picture changed:
- Architecture: monolith on a 12-year-old unsupported framework
- Security: passwords in plain text, SQL injections in 15 places
- Scalability: database crashes at 100 concurrent users
- Team: 80% of code written by one developer who already left
Real acquisition cost: $2M deal + $1.5M for rewrite = $3.5M instead of stated $2M.
Over 15 years, I've conducted technical audits of dozens of projects before acquisitions or investments. In this article — a checklist on how to avoid the "beautiful demo" trap and understand the real state of a startup's technical foundation.
TL;DR: Key Points for Decision Makers
For investors and buyers:
- Technical due diligence costs 0.5-1% of the deal but saves on average 30-50% in overpayment
- 5 critical checks: Security, Bus Factor, Test Coverage, Dependencies, Infrastructure
- Technical debt > 30% = deal revaluation minimum 20-40% down
- If Bus Factor = 1 and developer already left — it's a deal breaker
For founders (sellers):
- Start preparation 6 months before the deal
- Priority: fix critical security issues, cover core functionality with tests
- Prepare "Data Room": architecture diagrams, ADRs, performance metrics
- Good code can add 10-20% to deal price
Audit duration: 2-4 weeks for $1M-5M deals
Cost of skipping audit: On average +44% to initial price due to hidden debt
What is Technical Due Diligence and Why You Need It
Technical Due Diligence is a technical audit of a company before investment or acquisition. The goal is to understand:
- What is the product really worth? (considering hidden debts)
- What risks are you buying? (security, scalability, team)
- Can you develop the product? (or will you have to rewrite)
When to conduct technical due diligence
- Startup or tech company acquisition
- Tech project investment (Series A and above)
- Before strategic partnership
- M&A deals with technical component
Technical due diligence isn't about finding bugs. It's about evaluating the cost of ownership and future product development.
How much does NOT doing technical due diligence cost
Real example:
E-commerce platform bought for $5M. Technical due diligence wasn't conducted ("why, if it works?").
What was discovered after 3 months:
- Database doesn't scale (migration to different architecture needed)
- Payment gateway written with hardcoded API keys
- No automated testing (regression on every release)
- Deployment takes 6 hours (manual process)
Total costs:
Purchase price: $5.0M
DB migration: $0.8M
Payment refactoring: $0.5M
CI/CD implementation: $0.3M
Test coverage: $0.6M
──────────────────────────────
Total: $7.2M
Overpayment: 44% of original deal
Technical due diligence cost: $20K-50K. Savings: $2.2M.
What to Check: Complete Checklist
1. Architecture and Code
Codebase Quality
Metrics to check:
- Cyclomatic Complexity — code complexity (norm: <10 per function)
- Code Coverage — test coverage (minimum: 60%, good: 80%+)
- Code Duplication — code duplication (norm: <5%)
- Technical Debt Ratio — debt to code ratio (critical: >20%)
How to check:
# Python: Cyclomatic Complexity
pip install radon
radon cc -a src/ --total-average
# Test Coverage
pytest --cov=src --cov-report=term
# Code Duplication
npm install -g jscpd
jscpd src/Red flags:
- ❌ Cyclomatic Complexity > 20 in critical modules
- ❌ Test Coverage < 30%
- ❌ Code Duplication > 15%
- ❌ Technical Debt Ratio > 25%
Architectural Patterns
What to look for:
- Architecture matches business requirements (not over-engineered?)
- Monolith vs microservices (is the choice justified?)
- Separation of responsibilities (SOLID principles)
- Dependencies between modules
Questions for the team:
- Why was current architecture chosen?
- How has it changed during development?
- What bottlenecks do you know about?
- What would you change if starting now?
Red flags:
- ❌ Cannot explain architectural decisions
- ❌ "It happened historically" as the only explanation
- ❌ Monolith with 500K+ lines without decomposition plans
- ❌ Microservices with a team of 3 developers
- ❌ Circular dependencies between modules
2. Technology Stack
Technology Currency
Check:
- Framework and library versions
- Active support availability (LTS, EOL dates)
- Community size and activity
- Security updates
How to check:
# Python: outdated packages
pip list --outdated
# Node.js: outdated packages
npm outdated
# CVE check (vulnerabilities)
npm auditCritical questions:
- When were dependencies last updated?
- Are there deprecated libraries?
- Is migration to new versions planned?
Red flags:
- ❌ Framework/language with expired support (e.g., Python 2.7)
- ❌ Critical security vulnerabilities (CVSS > 7.0)
- ❌ Dependencies not updated for over a year
- ❌ Using deprecated APIs
Vendor Lock-in Risks
What to check:
- Dependency on specific cloud provider
- Proprietary solutions vs open source
- Migration complexity to other platforms
Vendor lock-in examples:
🚨 Critical lock-in:
- AWS-specific services (Lambda, DynamoDB) without abstractions
- Firebase for all business logic
- Proprietary CMS without data export
✅ Acceptable lock-in:
- Standard managed services (PostgreSQL, Redis)
- Kubernetes (portable between clouds)
- Open source solutions
3. Security
Critical checks:
Authentication & Authorization
Questions:
- How are passwords stored? (bcrypt/argon2 or plain text?)
- How are sessions managed?
- Is MFA implemented?
- How does password recovery work?
Red flags:
- ❌ Passwords in plain text or MD5
- ❌ Session tokens without expiration
- ❌ No rate limiting on login
- ❌ Secret keys in git repository
Data Protection
Check:
- Encryption at rest (for sensitive data)
- Encryption in transit (HTTPS everywhere?)
- Backup strategy and recovery testing
- GDPR/compliance requirements
Tools:
# Search for secrets in git history
git log --all --full-history --source -S "password="
git log --all --full-history --source -S "api_key="
# Or use gitleaks
docker run --rm -v $(pwd):/path zricethezav/gitleaks:latest detect --source="/path"SQL Injection & XSS
How to check:
- Code review of critical endpoints
- ORM usage vs raw SQL queries
- Input validation and sanitization
- Output encoding
Examples of vulnerable vs secure code:
# ❌ CRITICAL: SQL Injection vulnerability
def get_user(username):
query = f"SELECT * FROM users WHERE username = '{username}'"
return db.execute(query)
# ✅ SECURE: Parameterized queries
def get_user(username):
query = "SELECT * FROM users WHERE username = %s"
return db.execute(query, (username,))// ❌ CRITICAL: XSS vulnerability
function displayMessage(msg) {
document.getElementById("output").innerHTML = msg; // Any HTML will execute!
}
// ✅ SECURE: Content escaping
function displayMessage(msg) {
document.getElementById("output").textContent = msg; // Text only
}# ❌ CRITICAL: Command Injection
def backup_database(db_name):
os.system(f"pg_dump {db_name} > backup.sql") # Dangerous!
# ✅ SECURE: Use subprocess with arguments
def backup_database(db_name):
subprocess.run(['pg_dump', db_name], stdout=open('backup.sql', 'w'))Red flags:
- ❌ String concatenation/interpolation in SQL queries
- ❌ No input validation on user input
- ❌ User input in
eval(),exec(),os.system() - ❌
innerHTMLfor displaying user data - ❌ No CSP (Content Security Policy) headers
One found SQL injection is a reason for thorough examination of the entire codebase. If developers made this mistake in one place, it's likely in others too.
4. Infrastructure and DevOps
CI/CD Pipeline
What should be present:
- Automated testing
- Automated deployment
- Code review process
- Rollback mechanism
Questions:
- How long does deployment take?
- How often do you release?
- What happens when production crashes?
- Are there staging/QA environments?
Red flags:
- ❌ Manual deployment (copying files via FTP)
- ❌ No staging environment
- ❌ Production deploy without code review
- ❌ Releases less than once a month
Monitoring and Alerting
Critical metrics:
- Application Performance Monitoring (APM)
- Error tracking
- Uptime monitoring
- Resource utilization (CPU, Memory, Disk)
Should have:
Minimum requirements:
✅ Logging (ELK, CloudWatch, or equivalent)
✅ Error tracking (Sentry, Rollbar)
✅ Uptime monitoring (UptimeRobot, Pingdom)
✅ Application metrics (Prometheus, Grafana)
Red flags:
- ❌ No centralized logging
- ❌ Learn about problems from users
- ❌ No historical performance data
- ❌ Don't know about last incident
Scalability
Check:
- Can the system scale horizontally?
- Are there architectural bottlenecks?
- How does it behave under load?
Questions:
- What is current load (RPS, concurrent users)?
- What maximum have you handled?
- Has load testing been conducted?
- Where will the bottleneck be with 10x growth?
Red flags:
- ❌ Single point of failure (SPOF)
- ❌ No load testing conducted
- ❌ Database on single server without replication
- ❌ Stateful architecture without horizontal scaling capability
5. Documentation
What should exist:
- README — how to run project locally
- Architecture documentation — how the system is built
- API documentation — current API documentation
- Deployment guide — how to deploy
- Runbooks — what to do during incidents
Red flags:
- ❌ No documentation at all
- ❌ "Documentation is outdated, check the code"
- ❌ No one can explain how critical component works
- ❌ Onboarding new developer takes more than a month
6. Team and Processes
Bus Factor
Bus Factor — number of people who must "get hit by a bus" for the project to stop.
How to check:
# Git: who authored the code?
git ls-files | xargs -n1 git blame --line-porcelain | \
grep "^author " | sort | uniq -c | sort -rg | head -5Interpretation:
12456 John Doe # ← 60% of code — Bus Factor = 1 (critical!)
3421 Alice Smith # ← 17% of code
1987 Bob Johnson # ← 10% of code
Red flags:
- ❌ Bus Factor = 1 (one person knows all the code)
- ❌ Key developers already left
- ❌ No code review culture
- ❌ No pair programming or knowledge sharing
Development Processes
Questions for team:
- What does your sprint/development cycle look like?
- How do you make technical decisions?
- Is there code review?
- How do you manage technical debt?
Red flags:
- ❌ "Code review is a waste of time"
- ❌ No process for making architectural decisions
- ❌ No one knows about technical debt
- ❌ "We always do what the founder says"
Red Flags: Critical Warning Signs
Level 1: Immediate NO to Deal
These problems make acquisition inadvisable without serious reconsideration of terms:
- ❌ Critical security vulnerabilities — SQL injection, XSS, passwords in plain text
- ❌ No code rights — licensing issues, using pirated software
- ❌ Irreparable vendor lock-in — impossible to migrate without complete rewrite
- ❌ Entire team left and Bus Factor was = 1-2
Level 2: Deep Refactoring Required
Can buy, but must allocate 6-12 months and significant budget for fixes:
- ⚠️ Technical Debt Ratio > 30% — critical debt level
- ⚠️ Test Coverage < 20% — practically no tests
- ⚠️ Monolith with 500K+ lines without modular structure
- ⚠️ No CI/CD — manual deployment
- ⚠️ Deprecated technologies with EOL in next 12 months
Level 3: Controlled Risks
Can fix during development (3-6 months):
- ℹ️ Debt Ratio 15-20% — medium debt
- ℹ️ Test Coverage 40-60% — basic coverage exists
- ℹ️ Outdated dependencies (but with migration path)
- ℹ️ Weak documentation — can be restored
- ℹ️ Bus Factor = 2-3 — dependency on several people
How to Evaluate Technical Debt in Money
Debt Evaluation Formula
Cost of Technical Debt =
(Remediation Cost) + (Opportunity Cost) + (Risk Cost)
where:
Remediation Cost = Time to fix × Team cost
Opportunity Cost = Lost revenue due to slow development
Risk Cost = Incident probability × Downtime cost
Calculation Example
Situation:
- Monolith with 300K lines
- Test Coverage: 25%
- Technical Debt Ratio: 28%
- Deployment: manual, 4 hours
- Team: 5 developers × $80K/year
Remediation Cost (fixing debt):
Critical modules refactoring: 3 months × $33K = $100K
Test coverage to 70%: 2 months × $33K = $66K
CI/CD implementation: 1 month × $33K = $33K
Documentation: 2 weeks × $16K = $16K
──────────────────────────────────────────────────────
Total Remediation: $215K
Opportunity Cost (lost revenue):
Current velocity: 1 feature per month
After refactoring: 2-3 features per month
Lost revenue:
6 months × 2 features × $50K potential revenue = $600K
Risk Cost (risks):
Critical incident probability: 40% per year
1 hour downtime cost: $5K
Average recovery time: 4 hours
Risk Cost = 0.4 × ($5K × 4 hours) = $8K/year
Total Cost of Technical Debt:
Remediation: $215K
Opportunity: $600K (during refactoring period)
Risk: $8K/year
Real acquisition cost:
Deal price + Remediation + Opportunity
$2M + $215K + $600K = $2.815M
Revaluation: +40% from stated price
Technical Due Diligence Process
Stage 1: Preparation (1-2 days)
Information request:
- Git repository access
- Documentation (Architecture, API, Deployment)
- Infrastructure diagrams
- List of technologies and dependencies
- Performance metrics (if available)
- Incident history and postmortems for last year
Stage 2: Automated Analysis (2-3 days)
Running tools:
# 1. Code metrics
radon cc -a src/ --total-average
radon mi src/
# 2. Test coverage
pytest --cov=src --cov-report=html
# 3. Code duplication
jscpd src/
# 4. Security scan
npm audit
git log --all | grep -i "password\|secret\|key"
# 5. Dependencies audit
npm outdated
pip list --outdatedTools Table for Audit Automation
| Category | Open Source Tools | Commercial Solutions | What It Checks |
|---|---|---|---|
| Static Code Analysis | SonarQube, CodeClimate, ESLint, Pylint | Codacy, DeepSource | Complexity, Code Smells, Maintainability |
| Security Scanning | Gitleaks, TruffleHog, Bandit (Python), Semgrep | Snyk Code, GitGuardian, Checkmarx | Secrets, code vulnerabilities |
| Dependencies | npm audit, pip-audit, safety | Snyk, WhiteSource Bolt, Dependabot | CVEs in libraries, outdated packages |
| Test Coverage | Coverage.py, Jest, pytest-cov | Codecov, Coveralls | % test coverage |
| Code Duplication | jscpd, PMD Copy/Paste Detector | SonarQube (paid tier) | Code duplication |
| Infrastructure as Code | Terrascan, Checkov, tfsec | Bridgecrew, Prisma Cloud | Terraform/K8s security |
| SAST (Static Analysis) | Semgrep, Bandit, Brakeman (Ruby) | Veracode, Fortify | SQL injection, XSS, CSRF |
| Container Security | Trivy, Grype, Clair | Snyk Container, Aqua Security | Docker image vulnerabilities |
Recommended minimum stack for due diligence:
- Code Quality: SonarQube Community Edition (free)
- Security: Gitleaks + Semgrep + npm audit
- Dependencies: Snyk Open Source (free for OSS)
- Coverage: Codecov or built-in language tools
Tool costs:
- Basic stack (open source): $0
- Full commercial stack: ~$500-2000/month
- ROI: One critical bug found pays for annual subscription
Stage 3: Code Review (3-5 days)
Review priorities:
- Critical modules — authentication, payments, data access
- Architecture — design patterns, dependencies
- Security — input validation, data encryption
- Performance — database queries, caching
Stage 4: Team Interviews (1-2 days)
Questions for developers:
- What architectural decisions cause you pain?
- Where is the biggest technical debt?
- What would you change if starting now?
- What were the most serious incidents?
Questions for DevOps:
- How often does production crash?
- How long does recovery take?
- What are infrastructure bottlenecks?
Stage 5: Report and Recommendations (2-3 days)
Report structure:
# Technical Due Diligence Report
## Executive Summary
- Overall assessment (Go/No-Go/Go with conditions)
- Key risks
- Financial debt assessment
## Code Quality
- Metrics (Complexity, Coverage, Duplication)
- Architecture review
- Critical issues
## Security
- Vulnerabilities found
- Compliance gaps
- Remediation plan
## Infrastructure
- Scalability assessment
- DevOps maturity
- Cost optimization opportunities
## Team & Process
- Bus Factor
- Development practices
- Knowledge transfer risks
## Financial Impact
- Remediation cost
- Opportunity cost
- Risk cost
- Adjusted valuation
## Recommendations
- Immediate fixes (before closing)
- Short-term improvements (0-6 months)
- Long-term roadmap (6-12 months)Common Mistakes in Technical Due Diligence
Mistake 1: Focus on Syntax, Not Architecture
Problem:
Auditor spends time on code style violations and naming conventions, missing critical architectural problems.
Example:
# Auditor got stuck on this:
def getUserData(userId): # ❌ "Not camelCase!"
return db.get(userId)
# Missed the real problem:
def process_payment(amount):
# Hardcode, no retry logic, no error handling
requests.post("https://api.stripe.com", json={"amount": amount})Solution:
Prioritize checks:
- Security (critical)
- Architecture & Scalability (important)
- Code quality metrics (medium)
- Code style (low)
Mistake 2: Not Checking Operational Readiness
What's missed:
- Are there runbooks for typical incidents?
- How does team respond to production incidents?
- How long does rollback take?
- Is there a disaster recovery plan (and has it been tested)?
Check:
Ask the team: "Show me what you do when the database crashes at 3 AM?"
If answer: "Uh... call DevOps?" — it's a red flag.
What should exist:
- Documented runbooks
- On-call rotation
- Post-mortem culture (incident records)
- Tested backup recovery
Mistake 3: Not Talking to Junior Developers
Problem:
Only communicating with CTO/Tech Lead. They know about problems but may downplay them.
Solution:
Request anonymous developer survey:
Questions:
- What part of code causes you the most pain?
- What are you afraid to touch during development?
- If you started project from scratch, what would you change?
- What technical problems block product development?
Junior developers often know about "skeletons in the closet" more than management.
Mistake 4: Ignoring Test Quality
Problem:
Only looking at % coverage, not evaluating test quality.
Example of bad tests with high coverage:
# Test Coverage: 90%, but tests are useless
def test_calculate_discount():
result = calculate_discount(user=mock_user, total=1000)
assert result is not None # ❌ Only checks it's not None
def test_process_payment():
process_payment(100)
assert True # ❌ Always passesWhat to check:
- Are there integration tests (not just unit tests)?
- Are there E2E tests for critical flows?
- Are edge cases and error scenarios tested?
- How often do tests fail (flaky tests)?
Mistake 5: Not Conducting Load Testing
Why critical:
Code may work great with 10 users and crash with 100.
Case from practice:
Audit showed good code. Bought it. Black Friday — system crashed. Cause: N+1 queries to database that only manifested under load.
Minimum:
- Conduct stress test with 2-5x current load
- Find bottleneck (DB? API? Frontend?)
- Evaluate scaling cost
Mistake 6: Not Checking Compliance and Legal
What's missed:
- Open source library licenses (GPL vs MIT vs Apache)
- Using pirated software
- GDPR/CCPA compliance for personal data
- Code rights (contributor agreements)
Example problem:
Startup used GPL library in proprietary product. After purchase, received letter from rights holders demanding open source or pay $500K fine.
Check:
# Check licenses in Node.js project
npm install -g license-checker
license-checker --summary
# Look for GPL/AGPL licenses (may require code disclosure)
license-checker | grep -i "gpl"Mistake 7: Not Evaluating Dependency on Specific People
Beyond Bus Factor:
Check:
- Who is the only one who knows deployment process?
- Who is the only one with production access?
- Who is the only one who understands billing logic?
Real case:
Bought startup. A month later learned AWS account was on founder's personal credit card. Founder left. Lost 3 days migrating accounts and almost lost production access.
Check:
- All critical access on corporate accounts
- Minimum 2 people have access to each critical resource
- Access transfer process is documented
Due Diligence Checklist
✅ Code & Architecture
- Metrics: Complexity, Coverage, Duplication within norms
- Architecture: Matches scale and business requirements
- Patterns: Best practices used
- Dependencies: Current, without critical vulnerabilities
- Technical Debt: Ratio < 15%
✅ Security
- Authentication: Secure password storage (bcrypt/argon2)
- Authorization: Proper access control
- Data Protection: Encryption at rest and in transit
- Input Validation: Protection from injection attacks
- Secrets Management: No keys in code
- Security Audit: Conducted in last 12 months
✅ Infrastructure & DevOps
- CI/CD: Automated deployment
- Monitoring: APM, error tracking, alerting
- Backups: Regular + tested recovery
- Scalability: Can scale horizontally
- High Availability: No single points of failure
- Disaster Recovery: Plan exists and tested
✅ Testing
- Unit Tests: Coverage > 60%
- Integration Tests: Critical flows covered
- E2E Tests: Smoke tests for production exist
- Load Testing: Conducted for peak load
- Security Testing: Penetration testing performed
✅ Documentation
- Architecture Docs: ADR (Architecture Decision Records)
- API Documentation: Current (Swagger/OpenAPI)
- Deployment Guide: Step-by-step process
- Runbooks: Incident response procedures
- Onboarding: Documentation for new developers
✅ Team & Process
- Bus Factor: ≥ 3 for critical components
- Code Review: Mandatory for all PRs
- Knowledge Sharing: Regular tech talks/pairing
- Development Process: Defined and followed
- Tech Debt Management: Planned and tracked
✅ Compliance & Legal
- Licenses: Open source licenses compatible
- IP Rights: All intellectual property belongs to company
- GDPR/Privacy: Compliance for target regions
- SLAs: Documented and executed
Real Cases
Case 1: "Beautiful Demo, Terrible Code"
Situation:
SaaS project management product. 10K paying users, $500K ARR. Deal price: $5M.
Due Diligence found:
- Database: single PostgreSQL server, no replication
- Backup: last successful backup — 2 months ago
- Authentication: passwords in MD5
- Test coverage: 8%
- Bus Factor: 1 (main developer already left)
Critical risks:
Security incident: 90% probability within year
Data loss risk: 60% probability
Scalability: Current infrastructure won't handle 2x growth
Fix costs:
Security fixes: $150K
Infrastructure: $200K
Tests: $100K
Knowledge recovery: $80K
────────────────────────────
Total: $530K
Downtime risk: $2M potential losses
Decision:
Deal didn't happen. Seller didn't agree to revaluation considering risks.
Case 2: "How We Bought Startup and Increased Revenue 3x"
Situation:
E-learning platform. 5K users, $200K ARR. Price: $1.5M.
Due Diligence showed:
- Code Quality: good (Debt Ratio 12%)
- Test Coverage: 75%
- Architecture: modular, extensible
- Security: no critical issues
- Team: Bus Factor = 4
Found opportunities:
- Infrastructure overprovisioned (can save 40%)
- No A/B testing framework (can increase conversion)
- Mobile app outdated (rewrite to React Native)
Result:
Purchase: $1.5M
Infrastructure optimization: -$40K/year
Feature velocity increased: +50% (thanks to good code)
New features: +$400K ARR in year
ROI: 26% in first year
Case 3: "Hidden Technical Debt Ate All Profit"
Situation:
Fintech startup. 20K users, $800K ARR. Price: $6M.
Due Diligence missed:
- Load testing wasn't conducted (missed in audit)
- Architecture documentation existed but outdated
- Team didn't mention "slow" endpoints
What happened after purchase:
Black Friday. Load increased 5x. System crashed.
Root problem:
# Found after incident
def get_user_transactions(user_id):
# This code was called 1000 times per second
all_transactions = db.query("SELECT * FROM transactions") # 10M records!
user_txs = [tx for tx in all_transactions if tx.user_id == user_id]
return user_txs
# N+1 problem in critical code
# Load testing would have shown thisResult:
- 12 hours downtime
- $150K lost revenue
- 1 month for emergency fix
- User trust damaged
Lesson:
Load testing is mandatory for due diligence. Without it, you don't know how system behaves under load.
For Founders: How to Prepare Startup for Technical Audit
This section is for founders planning sale or raising investment. Good preparation can increase deal price by 10-20%.
6 Months Before Deal
1. Fix Critical Security Issues
Priority #1:
# Check your project NOW:
# 1. Secrets in code
git log --all --full-history -S "password=" -S "api_key="
# 2. Security vulnerabilities
npm audit --audit-level=high
pip-audit
# 3. Outdated dependencies with CVEs
npm outdatedWhat to fix immediately:
- ✅ Passwords: bcrypt/argon2 (not MD5/SHA1)
- ✅ Secrets: move to environment variables or secrets manager
- ✅ SQL Injection: parameterized queries everywhere
- ✅ HTTPS: everywhere, no exceptions
- ✅ Dependencies: update packages with critical CVEs
Investment: 2-4 weeks development ROI: Prevents 20-40% deal price reduction
2. Cover Critical Functionality with Tests
Don't need 80% coverage. Need to cover business-critical code:
- Authentication & Authorization
- Payment processing
- Data access layer
- Core business logic
Goal: Coverage > 60% on critical modules
Investment: 1-2 months ROI: Shows team seriousness, reduces buyer risks
3. Start Maintaining ADR (Architecture Decision Records)
What is it:
Documentation of architectural decisions in format:
# ADR-001: Choosing PostgreSQL Database Over MongoDB
## Context
We need DB for storing transactions with strong consistency
## Decision
Using PostgreSQL with ACID guarantees
## Consequences
- Pros: Transactions, foreign keys, mature ecosystem
- Cons: Harder horizontal scaling
- Risks: At growth > 10M records will need shardingWhy important:
Buyer sees decisions were made reasonably, not "as it happened".
ADR Template: adr.github.io
4. Set Up Automatic Metrics Monitoring
Minimum stack:
- Error tracking: Sentry (free up to 5K events/month)
- Uptime monitoring: UptimeRobot (free for 50 monitors)
- Application metrics: Prometheus + Grafana (open source)
Why:
During due diligence, buyer will ask to show metrics for last 3-6 months. Without monitoring, you can't answer:
- What is your uptime?
- How many errors per day?
- What is average response time?
Investment: 1-2 weeks setup ROI: Demonstrates process maturity
3 Months Before Deal
5. Refactor Top-3 Problem Modules
How to find:
# Git: most frequently changed files
git log --since="6 months ago" --pretty=format: --name-only \
| sort | uniq -c | sort -rg | head -10
# Python: most complex modules
radon cc -a src/ -n CWhat to do:
- If Complexity > 20 → split into functions
- If Code Duplication → extract to utils
- If Bus Factor = 1 → conduct knowledge sharing
6. Write Deployment and Recovery Documentation
What should exist:
- Deployment Guide: Step-by-step deployment process
- Rollback Procedure: How to rollback release
- Disaster Recovery Plan: What to do if DB/server crashes
- Runbooks: Typical incidents and solutions
Format:
# Deployment Guide
## Pre-deployment checklist
- [ ] Tests pass in CI
- [ ] Staging testing completed
- [ ] Database migrations reviewed
## Deployment steps
1. `git pull origin main`
2. `docker-compose build`
3. `docker-compose up -d`
4. Run health check: `curl /health`
## Rollback procedure
1. `git revert HEAD`
2. Redeploy previous version7. Conduct Internal Security Audit
Options:
- Hire external security consultant ($5K-15K)
- Use automated tools (OWASP ZAP, Burp Suite)
- Code review focused on security
Goal:
Find and fix problems BEFORE buyer finds them.
1 Month Before Deal
8. Prepare "Data Room" for Due Diligence
Data Room structure:
technical-data-room/
├── architecture/
│ ├── system-architecture.pdf
│ ├── database-schema.sql
│ ├── api-documentation.yaml (OpenAPI)
│ └── adr/ (Architecture Decision Records)
├── metrics/
│ ├── performance-reports/ (last 6 months)
│ ├── uptime-statistics.csv
│ └── error-rate-trends.png
├── security/
│ ├── security-audit-report.pdf
│ ├── penetration-test-results.pdf
│ └── compliance-certificates/ (SOC2, ISO, etc.)
├── code-quality/
│ ├── sonarqube-report.html
│ ├── test-coverage-report.html
│ └── dependency-audit.txt
├── team/
│ ├── team-structure.pdf
│ ├── knowledge-distribution.csv (Bus Factor analysis)
│ └── onboarding-guide.md
└── tech-stack/
├── technologies-used.md
├── infrastructure-diagram.pdf
└── third-party-services.xlsx
Why:
- Speeds up due diligence (saves 1-2 weeks)
- Demonstrates professionalism
- Reduces "red flags"
9. Conduct Mock Due Diligence
How:
- Ask CTO friend or advisor to conduct audit
- Use checklist from this article
- Fix found problems
Questions for mock audit:
- Can you run project locally in < 30 minutes?
- Are there critical security issues?
- What is Bus Factor?
- Can system scale 5x?
- What happens if DB crashes right now?
What NOT to Do
❌ Rewrite code to new framework — too risky
❌ Add features for demo — buyer needs stability, not features
❌ Hide problems — will find anyway, but you'll lose trust
❌ 100% test coverage — waste of time, 60-70% on core is enough
ROI of Audit Preparation
Costs:
Security fixes: 2-4 weeks
Testing: 1-2 months
Documentation: 2-4 weeks
Monitoring setup: 1-2 weeks
Mock audit: 1 week
──────────────────────────────────
Total: 3-4 months effort
Cost (1 dev): $40K-60K
Benefits:
- Deal price: +10-20% ($200K-500K for $2M-5M deal)
- Deal speed: -20% time (faster closing)
- Deal failure probability: -50%
Real case:
Startup spent $50K on audit preparation (4 months):
- Fixed security issues
- Covered core with tests
- Wrote documentation
Result:
- Initial offer: $3M
- After due diligence: $3.6M (+20%)
- Preparation ROI: $600K / $50K = 12x
Technical Due Diligence Cost
Who Conducts
- In-house CTO/Tech Lead — if have competence
- External consultant — independent expert (Senior/Principal/CTO level)
- Specialized firm — for large M&A deals
Budget
| Deal Size | Due Diligence Cost | Duration |
|---|---|---|
| < $1M | $10K-20K | 1-2 weeks |
| $1M-5M | $20K-50K | 2-3 weeks |
| $5M-20M | $50K-150K | 3-4 weeks |
| > $20M | $150K-500K+ | 1-2 months |
Technical due diligence typically costs 0.5-1% of deal size. Savings from preventing one bad purchase pays for dozens of audits.
What to Do with Due Diligence Results
Scenario 1: Everything Great (rarely happens)
Indicators:
- Technical Debt Ratio < 10%
- Test Coverage > 70%
- Security issues: minor or none
- Bus Factor ≥ 4
- Good documentation
Action:
✅ Buy at stated price or even with premium (if team is strong)
Scenario 2: Controlled Risks (often)
Indicators:
- Debt Ratio 15-20%
- Test Coverage 40-60%
- Security: no critical, but medium issues exist
- Bus Factor 2-3
- Partial documentation
Action:
📊 Revaluation considering remediation cost:
Original price: $5.0M
Remediation cost: $0.8M
Risk discount (15%): $0.7M
─────────────────────────────
Adjusted offer: $3.5M
OR
Original price with conditions:
- $2M upfront
- $3M earnout (upon achieving metrics after fixes)
Scenario 3: Critical Problems (sometimes)
Indicators:
- Debt Ratio > 30%
- Critical security issues
- Bus Factor = 1
- No tests, no documentation
Action:
❌ Walk away or radical revaluation:
Original price: $5.0M
Remediation cost: $2.5M
Risk premium: $1.5M
─────────────────────────────
Adjusted offer: $1.0M
+ Conditions:
- Key developers stay for 2 years
- 6 months transition period
- Earnout tied to quality metrics
Conclusions and Recommendations
Key Principles
- Technical due diligence — not optional, but mandatory for tech deals
- Beautiful demo ≠ quality code — always look under the hood
- Technical debt is measured in money — calculate remediation + opportunity + risk cost
- Bus Factor = 1 is critical risk — requires immediate action
- Load testing is mandatory — without it you don't know system limits
Minimum Checklist
Even if time is short, check these 5 things:
- Security — passwords, secrets, SQL injection
- Bus Factor — who owns knowledge
- Test Coverage — are there any tests at all
- Dependencies — critical vulnerabilities
- Infrastructure — single points of failure
If even one of these items has critical problems — stop and conduct full audit.
When NOT to Buy
- ❌ Critical security vulnerabilities + seller unwilling to fix
- ❌ Entire team already left and Bus Factor was = 1
- ❌ Remediation cost > 50% of deal price
- ❌ Seller hides code access or refuses due diligence
When to Buy with Premium
- ✅ Excellent code quality + strong team
- ✅ Good documentation and processes
- ✅ Scalable architecture
- ✅ High Bus Factor (≥ 5)
- ✅ Technical Debt managed consciously
Need Help with Technical Due Diligence?
Over 15 years, I've conducted technical audits of many projects before investments and acquisitions. I can help:
- Conduct full technical due diligence
- Evaluate technical debt in money
- Identify critical risks
- Prepare report for investors/board
- Create remediation roadmap
Write to email — let's discuss your case.
First consultation is free. I'll tell you what to pay attention to in your specific situation.
Liked the article?
Share with investor colleagues or founders planning startup sale. Knowing what buyers will check helps prepare in advance and not lose in price.
Subscribe to updates in Telegram — I write about architecture, technical management, and tech investments. Only practice, no fluff.



