Taking Over a Production Platform: What to Fix in the First 90 Days
- Published on
- Reading time
- 16 min read
Taking over an existing production platform is not the moment for a rewrite. The first 90 days should reduce uncertainty: map the system, make failures visible, protect critical paths, understand delivery bottlenecks and only then change architecture. A practical stabilization playbook for engineering leaders. #EngineeringLeadership #ProductionEngineering #Scalability #Observability #TechnicalDebt #Laravel #SaaS
Taking Over a Production Platform: What to Fix in the First 90 Days
Taking responsibility for an existing production platform is very different from starting a greenfield project.
The system already has users, revenue, operational habits, technical debt, integrations, deployment history and undocumented assumptions.
You cannot stop everything while the engineering team redraws the architecture.
And you should not assume that the code that looks worst is the thing hurting the business most.
The first job is not modernization.
It is reducing uncertainty.
Before changing the system, make the system understandable. Before making it faster, make failure visible. Before rewriting it, learn why it evolved this way.
A useful first-90-days plan therefore moves through three broad phases:
Days 1–30 → Understand and stabilize
Days 31–60 → Control and simplify
Days 61–90 → Improve and prepare to scale
The dates are not rigid deadlines. A serious incident can change the order immediately. The value is in the sequence of priorities.
Do not begin with a rewrite
A new technical leader can quickly find code they would not have written themselves.
That is not evidence that the platform needs rewriting.
Existing code contains years of business decisions, edge cases and operational knowledge. Some of it may be poor. Some may look poor because the original constraint is no longer visible.
A rewrite started before understanding the system creates two simultaneous platforms:
- The production system that still needs support.
- The replacement system consuming engineering capacity.
Now the team has twice the surface area and the business still needs features.
Rewrite only when evidence shows that incremental change cannot reasonably solve the actual constraint.
Day one: establish the critical business paths
Do not start by reading every repository from top to bottom.
Start with the product.
Which workflows must work for the business to operate?
For a SaaS platform these might include:
Sign up
→ Authentication
→ Subscription/payment
→ Core product action
→ Notifications/integrations
→ Reporting
For a marketplace they might be search, order creation, payment, fulfilment and refund.
For a learning product they may be authentication, content delivery, progress tracking, quizzes and subscription state.
The exact paths differ.
The principle does not:
Technical priority should begin with business-critical flows.
If one obscure admin page is slow, that is different from authentication intermittently failing.
Build a system map before an architecture diagram
Architecture diagrams often show what people believe exists.
A system map should show what actually participates in production.
Inventory:
- Applications and services.
- Databases and caches.
- Queues and workers.
- Object storage.
- Search systems.
- Scheduled jobs.
- External APIs.
- Payment providers.
- Authentication providers.
- Email/SMS/push services.
- Analytics.
- Monitoring and error tracking.
- CI/CD pipelines.
- Cloud accounts and deployment environments.
- DNS/CDN/WAF layers.
- Secrets and configuration sources.
Then map dependencies.
Mobile/Web
↓
API/Application
↓
DB · Cache · Queue · Storage
↓
Workers / Integrations
↓
External providers
You are looking for hidden single points of failure and hidden ownership.
Find out how production changes reach users
One of the first questions I want answered is:
What exactly happens between merging code and users receiving it?
Document:
Commit
→ CI
→ Tests
→ Build
→ Deploy
→ Migrations
→ Health checks
→ Traffic
→ Monitoring
If parts are manual, record them.
If one person knows a secret deployment step, that is operational risk.
If migrations run without visibility, that is risk.
If rollback is theoretical, that is risk.
You do not need to automate everything in week one. You need to know where the danger is.
Observability before optimization
A platform cannot be stabilized from user complaints alone.
At minimum, you need enough visibility to answer:
- Is the application healthy?
- Which endpoints or jobs are failing?
- What changed before the failure?
- Are database queries slowing down?
- Are queues building up?
- Are workers crashing?
- Are external providers timing out?
- Which version is running?
- Is the problem global or isolated?
Useful signals usually include application errors, structured logs, request latency, database health, queue depth/age, worker failures, infrastructure metrics and deployment markers.
Do not collect telemetry merely because a dashboard looks professional.
Collect it because it helps someone make a decision.
Alerts should represent action
An alert that nobody understands or acts on becomes noise.
For each important alert, define:
- What condition triggered it?
- Why does it matter?
- Who owns it?
- What should they check first?
- When should it escalate?
If the team receives hundreds of unactionable alerts, the monitoring system can hide incidents rather than reveal them.
Alert quality matters more than alert quantity.
Learn the incident history
Past incidents are one of the fastest ways to understand a mature platform.
Look for recurring patterns:
- Database saturation.
- Queue backlog.
- Memory exhaustion.
- Third-party failures.
- Deployment regressions.
- Data inconsistencies.
- Expired credentials.
- Storage limits.
- Slow queries.
- Race conditions.
- Cache failures.
Ask not only “what broke?” but:
Why was the system allowed to reach that state without earlier detection or containment?
The answer often identifies a higher-leverage fix than the original bug.
Separate symptoms from constraints
A slow API endpoint is a symptom.
The constraint might be an unindexed query, N+1 access, an external API in the request path, lock contention, serialization cost, oversized payloads or insufficient capacity.
High cloud cost is a symptom.
The constraint might be idle resources, inefficient queries, overprovisioning, excessive logs, expensive network traffic or architecture designed for a workload that no longer exists.
Do not create roadmap items such as “improve performance” without identifying what constrains performance.
Understand the data before changing the code
In an established platform, the database often contains more truth about the product than documentation does.
Inspect:
- Largest tables.
- Growth rate where data is available.
- Indexes.
- Slow queries.
- Foreign-key and integrity assumptions.
- Soft-delete behavior.
- JSON/unstructured fields.
- Background cleanup.
- Retention.
- Replication/backups.
- Migration history.
A code refactor that ignores data shape can make production worse even when the new code is cleaner.
Backups are not enough; verify recovery
A dashboard saying “backup successful” is comforting but incomplete.
You need to understand:
- What is backed up?
- How often?
- For how long?
- Where is it stored?
- Who can restore it?
- How long would recovery approximately take under current procedures?
- Have restore procedures actually been tested?
The goal is not a theoretical backup.
The goal is recoverability.
Security: fix exposed risk before architecture elegance
Early security review should prioritize concrete exposure.
Examples:
- Shared credentials.
- Secrets committed to repositories.
- Excessive production access.
- Missing MFA for critical infrastructure.
- Publicly exposed services.
- Unpatched critical dependencies.
- Weak authorization boundaries.
- Missing audit trails for sensitive actions.
- Overpowered API tokens.
A beautiful service decomposition does not compensate for an exposed production database.
Map ownership, not only technology
A platform can be technically healthy and operationally fragile because nobody knows who owns what.
Create ownership for critical areas:
Authentication → owner
Payments → owner
Mobile API → owner
Infrastructure → owner
Data pipeline → owner
Notifications → owner
Ownership does not mean only one person may touch the code.
It means someone is responsible for understanding health, changes and risks in that area.
The team is part of the architecture
During the first month, understand how work actually moves.
Ask:
- How does a requirement become engineering work?
- Who decides priority?
- How large are work items?
- How are changes reviewed?
- What blocks releases?
- How is QA performed?
- How are production bugs handled?
- How often does work return because requirements were unclear?
A delivery problem is not always a developer-performance problem.
The bottleneck can be requirements, ownership, reviews, QA, dependencies, deployment or architecture.
Days 1–30: the output should be a risk map
By the end of the first phase, I want more than a list of bugs.
I want a map such as:
Risk / constraint
Business impact
Evidence
Current owner
Immediate containment
Longer-term fix
Confidence
This changes conversations with product and business teams.
Instead of “the codebase is bad,” engineering can say:
This queue delays a critical workflow under load; here is the evidence, containment and proposed fix.
That is actionable technical leadership.
Days 31–60: control and simplify
Once critical risks are visible, the second phase is about making production change safer and removing recurring operational friction.
Fix the repeat offenders first
Do not sort technical debt by how ugly the code looks.
Prioritize issues that repeatedly create:
- Incidents.
- Customer impact.
- Delivery delay.
- Security exposure.
- High operating cost.
- Manual operational work.
A boring reliability fix can create more business value than an exciting architecture project.
Create a safe deployment baseline
The exact pipeline depends on the product, but the goal is consistent:
A normal change should be boring to release.
Improve the weakest points in:
- Automated tests.
- Static analysis/linting.
- Build reproducibility.
- Environment configuration.
- Database migration safety.
- Health checks.
- Deployment visibility.
- Rollback/roll-forward procedures.
- Feature flags where appropriate.
Do not chase a perfect CI/CD diagram. Remove the most dangerous uncertainty first.
Put critical workflows under tests
A mature platform can have thousands of tests and still miss the paths that matter.
Or it can have few tests and be afraid to change anything.
Start from risk.
Protect business-critical workflows, authorization boundaries, money-changing logic, data transformations and bugs that have already escaped to production.
Every serious regression is a candidate for a test that prevents the same class of failure.
Test count is not the objective.
Confidence to change the system is.
Reduce production access
If engineers routinely SSH into servers or edit production data manually, ask why.
Sometimes emergency access is necessary.
But frequent manual production intervention usually signals missing tooling.
Replace repeated manual operations with controlled commands, admin workflows, audited jobs or deployment automation.
The goal is not to prevent engineers from solving incidents.
It is to make the safe path easier than the dangerous path.
Make background work observable
Queues can hide enormous amounts of operational risk.
Track at least what matters for the platform:
- Pending work.
- Age of oldest job.
- Failure rate.
- Retry behavior.
- Worker health.
- Processing latency.
A queue with 100 jobs may be healthy if jobs complete in seconds.
A queue with 10 jobs may be broken if the oldest has been waiting for hours.
Context matters.
Put limits around external dependencies
Every third-party API is part of your production system whether you own it or not.
Define timeouts, retries, rate-limit handling and failure behavior.
Ask what happens if the provider is unavailable for five minutes, one hour or a day.
Should the user request fail?
Should work queue for later?
Can the product operate in degraded mode?
Do not let an optional integration become an accidental single point of failure for the core platform.
Remove hidden synchronous work
A common mature-platform problem is too much work inside the web request:
User request
→ database writes
→ third-party API
→ email
→ analytics
→ document generation
→ response
Some of that work may be moved to background jobs when business semantics allow it.
This can improve latency and resilience, but do not move work to a queue blindly.
You now need idempotency, retry safety and job observability.
Asynchronous architecture trades one set of problems for another. Make the trade deliberately.
Attack expensive queries with evidence
Do not start by adding indexes everywhere.
Use query data.
Identify expensive/high-frequency queries, inspect execution plans, understand data distribution and then change indexes or access patterns.
An index improves reads but has storage and write costs.
Performance work should be evidence-driven.
Control technical debt through the roadmap
A separate “technical debt backlog” can become a graveyard.
Tie debt to business outcomes:
Debt: synchronous provider call
Impact: checkout fails when provider is slow
Work: decouple non-critical step
Outcome: checkout no longer depends on provider latency
Now product leadership can understand why the work matters.
Standardize the way incidents are learned from
You do not need a bureaucratic postmortem for every small bug.
For meaningful incidents, capture:
- What happened?
- User/business impact.
- Timeline.
- Detection.
- Root/contributing factors.
- Containment.
- What prevented earlier detection?
- Follow-up actions and owners.
Avoid turning incident review into a search for the engineer who made the mistake.
Systems improve when teams can expose failure honestly.
Days 31–60: the output should be control
At this point the platform should be easier to reason about.
You should know what is deployed, see important failures, have clearer ownership, understand major operational constraints and have safer paths for routine changes.
That foundation is what makes deeper architecture work possible.
Days 61–90: improve and prepare to scale
Only after stabilization do I want to make larger structural decisions.
Build the architecture roadmap from measured constraints
Now you can ask:
- Which database limit will hurt first?
- Which service has a different scaling profile?
- Which queue needs partitioning?
- Which external dependency needs decoupling?
- Which table needs archival/partitioning?
- Which module creates the most change risk?
- Which infrastructure spend is unjustified?
This produces a roadmap based on observed constraints rather than architecture fashion.
Do not split the monolith because it is a monolith
A large Laravel application is not automatically a problem.
A microservice architecture is not automatically scalable.
Split a boundary when there is a reason such as:
- Independent scaling.
- Different reliability requirement.
- Security/isolation boundary.
- Separate ownership.
- Different runtime requirement.
- A domain that genuinely needs independent deployment.
Otherwise, improving modularity inside the existing application may be cheaper and safer.
Capacity planning starts with workload shape
“Can this handle ten million users?” is not a useful capacity question by itself.
Ten million registered users can create very different load depending on activity.
Measure the dimensions that matter:
- Concurrent users.
- Requests per second.
- Read/write ratio.
- Queue throughput.
- Peak-to-average traffic.
- Data growth.
- File/storage growth.
- Expensive endpoint frequency.
- External API quotas.
Scale the workload, not the marketing number.
Load-test critical paths, not vanity endpoints
A homepage returning 200 OK under heavy synthetic traffic proves little if the real bottleneck is booking creation, checkout, content progress or report generation.
Load tests should model important user flows and realistic data access.
Then observe the whole system: application, database, cache, queues and dependencies.
The purpose is to discover the first constraint safely before customers discover it in production.
Define reliability targets that match the business
Not every internal admin screen needs the same reliability target as authentication or payments.
Identify critical capabilities and define meaningful service indicators around them.
Examples can include successful authentication, successful order creation, API latency or job completion time.
Targets should help teams decide when reliability work outranks feature work.
Do not create SLOs only because the acronym belongs in an engineering deck.
Cost optimization comes after attribution
Cloud cost discussions often begin with “AWS is expensive” or “we should move providers.”
First understand where cost comes from.
Attribute spend to compute, database, storage, network, logs, third-party services and workloads where possible.
Then optimize the expensive constraint.
Moving an inefficient workload to another cloud may only move the invoice.
Decide what should be modernized — and what should be left alone
By this point, you have enough evidence to classify legacy areas:
Keep: stable, low-risk, low-change code that does its job.
Improve: important areas where incremental refactoring reduces risk.
Replace: components whose constraints cannot reasonably be solved incrementally.
Retire: features/services that no longer justify their operational cost.
Not touching stable legacy code is sometimes an architecture decision.
Create an engineering scorecard that drives decisions
Avoid a giant dashboard of metrics nobody uses.
Choose a small set that reflects delivery and production health.
Depending on the product, that might include:
- Critical incident trend.
- Deployment health.
- Change failure/regression signals.
- Critical endpoint latency/errors.
- Queue health.
- Database saturation/slow-query signals.
- Lead time or blocked-work indicators.
- Infrastructure cost trends.
Metrics should create questions and actions, not performance theatre.
Build a roadmap in horizons
A useful engineering roadmap after the takeover can separate:
Now
Risks that can hurt users/business today.
Next
Structural improvements that reduce recurring delivery or operational cost.
Later
Scale and modernization work justified by expected growth.
This prevents long-term architecture work from hiding immediate reliability risk, and prevents urgent bugs from consuming every future investment.
Communicate in business language
A technical leader taking over an existing platform needs to translate engineering risk.
Instead of:
We need to refactor the queue architecture.
Explain:
This workflow can currently delay customer-facing processing when the external provider slows down. Decoupling it reduces that dependency and gives us controlled retries.
Instead of:
The database schema is terrible.
Explain:
This table is creating measurable query pressure on a critical workflow; here is the change and the expected operational effect we will verify.
The architecture is technical.
The prioritization is business.
What I would want by day 90
Not a perfect platform.
Not a completed rewrite.
Not zero technical debt.
I would want:
- A reliable system/dependency map.
- Clear critical business flows.
- Actionable production observability.
- Known top risks and owners.
- A safer deployment path.
- Better protection for critical workflows.
- A tested understanding of backup/recovery.
- Fewer recurring manual operations.
- Evidence about performance and scale constraints.
- A technical roadmap tied to business impact.
Most importantly, the team should be making fewer decisions from guesses.
The first 90 days are about earning the right to make bigger changes
When you inherit a large production platform, architecture opinions arrive immediately.
Evidence takes longer.
The job of the first phase is to create enough visibility and operational control that larger decisions become defensible.
That is why my preferred sequence is:
Understand
→ Observe
→ Stabilize
→ Control
→ Measure
→ Improve
→ Scale
Not:
Arrive
→ Rewrite
The best first 90 days do not make the platform look newer. They make the next 900 days safer to build.
Taking over an existing SaaS or production platform and need to stabilize delivery, architecture and infrastructure without stopping the business?
I work with product and engineering teams on platform takeovers, technical leadership, architecture, production reliability and modernization — turning unknown technical risk into an evidence-based roadmap.
Related: Engineering Leadership, Custom Software Development, Technical Debt: When Is It a Business Problem?, and Why Software Projects Are Late When Engineers Are Busy.
Comments (0)