You're about to change a legacy application, and the real question is simple: what could break if we touch it, and how sure are we? That confidence doesn’t come from a prettier diagram. It comes from identifying how the app actually behaves across your estate.
This means identify material dependencies and record what remains unverified across systems, data flows, batch jobs, reports, APIs, file drops, schedulers, certificates, queues, and scripts the application needs or silently affects. It also includes the people, vendors, support teams, and operating steps required to keep it running, plus downstream consumers that rely on its outputs. Done right, this rolls up into an evidence-backed dependency record you can use to make scope, wave, and cutover decisions.
Diagrams, CMDB records, source repos, ticket history, and stakeholder recall are useful starting evidence but not the whole truth. They’re claims to be tested. Shadow jobs, environment drift, expiring certs, and "one-time" scripts often sit outside documentation, making systematic discovery essential to avoid blind spots.
Here’s the practical method we’ll use:
- Set clear boundaries for the application and its interfaces.
- Triangulate evidence across runtime behavior, declared configuration, operational knowledge, and business workflows.
- Document relationships in an inventory and validate them with accountable owners.
- Rank dependencies by business impact, coupling, recoverability, and evidence confidence.
- Close discovery with decisions: scope, migration-wave boundaries, cutover approach, and sign-offs.
Before collecting logs or conducting interviews, establish clear discovery boundaries.
Define the Dependency Map Before You Start Collecting Evidence
Before scanning servers or interviewing teams, draw the scope boundary. Decide what counts, where discovery starts and ends, and how findings roll into an inventory the business can trust.
Use this baseline checklist to set scope and avoid surprises:
- In-scope dependency types. Include systems and services (internal apps, microservices, third‑party platforms); APIs and event topics; queues and schedulers; databases and shared data stores; batch jobs; file exchanges; identity paths (SSO, LDAP, service accounts, tokens); vendors and managed services; downstream consumers; and manual operating steps.
- Business capability first. Anchor scope to the capability and change under consideration. Capture upstream inputs and triggers, downstream outputs and consumers, exception paths, and who supports each piece day and night.
- Treat docs as hypotheses. Treat CMDB records, diagrams, repositories, and prior documentation as hypotheses to validate. Reconcile them with runtime behavior, configuration, and workflow knowledge.
- Context for every app. For each related application, record its business purpose, typical usage patterns (volumes, peak windows, SLAs), accountable owner, and operating context. Without this, technical links get misread and real risks get missed.
- Decide ownership now. Name the discovery sponsor, technical lead, business owner, and the decision forum that will accept or challenge findings. This prevents stalled sign‑offs later.
Here’s a hypothetical. If the change is “move Billing to the cloud,” don’t stop at its database and API calls. Include the nightly EFT file drop from Treasury, the queue that retries failed invoice posts, the SSO path used by call center agents, the downstream data mart read by Finance, and the vendor that hosts tax calculation. Also note who gets paged when batch windows slip and what happens when a file is late.
Clear boundaries make dependency discovery faster and more accurate. With scope defined and governance in place, collect evidence across four complementary streams.
Use Four Evidence Streams to Find Hidden Integrations
Architecture diagrams rarely reveal all active paths. To build a credible dependency record, triangulate material dependencies across four core streams.
1) Observed runtime signals
Start with what the system really does. Parse application and web server logs for outbound calls, queue operations, file I/O, and auth flows. Where available, use distributed tracing to follow requests across services. Add network-connection evidence: flow logs, firewall allow/deny logs, DNS queries, TLS handshakes, and even short packet captures during test windows. Hypothetical: a "quiet" job opens a TCP session to an old licensing server at 2:00 a.m. you won’t see that on a diagram, but it shows up in flow logs and job logs.
2) Declared configuration and code
Scan the things the system says it depends on. Review code for client libraries and hardcoded endpoints. Check environment variables, connection strings, secrets references, and feature flags. Pull scheduled-task definitions (cron, schedulers), integration endpoint settings, and any deployment records that show what gets packaged together. These declarations often surface "sleeping" dependencies that only wake during certain jobs or modes.
3) Operational records and CMDB
Use CMDB entries, runbooks, on-call notes, and vendor support docs as seeds not truth. Confirm each item against the live environment and with accountable owners. When an entry is stale or ownerless, flag it and assign temporary stewardship so discovery doesn’t stall.
4) Business workflow observation
Watch how the business really uses the system. Sit with operations during close, billing, or fulfillment cycles; trigger known exception paths; and observe manual steps that kick off files, emails, or reprocessing. This is where "surprise" dependencies shared drives, ad hoc scripts, or sidecar reports reveal themselves.
- Plan the observation window. Include normal operations plus recurring peaks (seasonal spikes), period-end, scheduled jobs, and exception-driven activity. Don’t lock to a fixed duration; run long enough to see the known cycles for this app in this environment.
- Reconcile conflicting evidence. For every dependency, record the source(s), date observed, confidence level, accountable owner, and validation status. When sources disagree (e.g., logs show a call but config doesn’t), assign an owner to reproduce and resolve, and keep the lower confidence rating until validated.
If discovery exposes brittle API touchpoints, review design patterns in our guide on APIs in application modernization. Using these streams together ensures each catches what the others miss.
Map Runtime Calls, Data Stores, Batch Jobs, and File Transfers
Turn gathered evidence into normalized records for technical dependencies, forming the core of your inventory.
For every dependency, capture:
- Source and target: The calling system/process and the receiving system/process.
- Direction: Inbound to the app, outbound from it, or bidirectional.
- Interface/mechanism: HTTP API, RPC, JDBC/ODBC, message queue/topic, shared DB table, ETL job, scheduler, MFT/SFTP, SMB/NFS share, file drop/pickup.
- Trigger: User action, system event, schedule, upstream completion, or error path.
- Schedule/cadence: Cron expression, window, time-zone, and peak periods.
- Data exchanged: Payload shape, file naming pattern, schema/table, average/peak volume, and sensitivity level.
- Owner: Accountable team or vendor on both sides, with an escalation path.
- Expected failure behavior: How failure shows up (HTTP 5xx, queue backlog, file missing, lock timeout), timeouts, and built‑in backoff/retry.
Cover the full spectrum so your legacy application dependency mapping isn’t biased toward "what’s easy to see":
- Synchronous calls and APIs: Endpoints, methods, timeouts, idempotency, and dependency on API gateways or service meshes.
- Message queues and streams: Topics/queues, consumer groups, ordering, DLQs, and at‑least/exactly‑once delivery assumptions.
- Databases and shared data stores: Direct DB links, read replicas, linked servers, shared schemas, blob/object stores, and caching layers that act as integration points. If SQL Server is in scope, see our view on risk‑reduced paths in SQL Server modernization for legacy applications.
- ETL/ELT processes: Sources/targets, transformation steps, batch windows, late‑arrival handling, and dependency on staging areas.
- Scheduled jobs and schedulers: Job names, predecessors/successors, calendars/exceptions, and whether jobs live in app code, OS tasks, or enterprise schedulers.
- Managed file transfer and file shares: Protocol (MFT, SFTP, FTPS, SMB/NFS), credentials, file paths, naming/rotation, checksum/signature use, and purge/archival rules.
Document security and auth relationships that can block or delay change:
- Service accounts and secrets: Where credentials live (env vars, config files, vaults), rotation processes, and hardcoded references.
- Identity paths: Third‑party IdP flows, SSO dependencies, and cross‑realm trust (e.g., legacy domains).
- Certificates and trust: Mutual TLS, certificate pinning, keystore locations, and renewal cadence.
- Authorization dependencies: Roles/groups, database grants, queue ACLs, and filesystem permissions.
Capture recovery behavior so you can design safe cutovers:
- Retry and replay: Built‑in retries, idempotent operations, and replay procedures.
- Manual intervention: Who intervenes, runbooks, and tools needed.
- Duplicate‑processing risk: Markers/dedup logic and how to avoid double posts.
- Data consistency needs: Ordering guarantees, reconciliation steps, and tolerance for lag.
- Ops ownership: The team on call, SLAs, and escalation paths.
Finally, flag relationships that drive your change strategy:
- Co‑migration needed: Tight coupling, shared schemas, or brittle sync calls that must move together.
- Decoupling targets: Candidates for queues, caches, or APIs to break direct ties.
- Integration testing scope: End‑to‑end paths that must be proven in non‑prod with realistic data.
- Interim interfaces: Bridges, adapters, or dual‑run patterns to support phased cutovers.
This level of detail uncovers technical relationships before you lock migration waves or cutover plans.
Find Dependencies Hidden in Processes, Vendors, and User Workarounds
After mapping calls, data stores, jobs, and files, look where code can’t see: processes, vendors, and human workarounds. Integrations often live in calendars, inboxes, tickets, or portals, making them critical dependencies.
Run short, structured interviews or workshops with the people who move work through the system. Include application owners, support and operations, business users, security and identity owners, data owners, and (when relevant) vendor or partner contacts. Keep the room small enough to decide, but broad enough to see the whole flow.
Then do end‑to‑end walkthroughs. Follow a real transaction from start to finish and through its exceptions: normal processing, rework, manual approvals, exports, imports, reporting, and incident‑response handoffs. Don’t skip the "we just do this on the last Friday" steps. That’s where hidden integration discovery pays off.
As you probe, ask directly about:
- Vendor portals and partner APIs: Files uploaded or downloaded outside your integration platform.
- Contract or SLA constraints: Support windows, blackout periods, cutover notice.
- Calendar‑driven activity: Month‑end closes, payroll cycles, seasonal peaks, maintenance windows.
- Manually triggered jobs: Shell scripts, RPA bots, SSIS packages, ad‑hoc SQL, Excel macros.
- Downstream reports or consumers: Finance, compliance, data warehouse, audit extracts.
Record informal integrations even if they aren't in code or telemetry. Shared drives, mailbox rules, and chat approvals represent operational ties. When embedded or partner integrations fall outside your direct control, align scope with your build, partner, or buy strategies (see our analysis of embedded integrations for SaaS).
And treat recollection as evidence to validate, not final proof. Tag every finding with its evidence type (observed log, screenshot, document, ticket, calendar entry, or owner recollection). Where the only source is memory, create a validation task: capture an artifact, run a time‑boxed test, or observe the next cycle.
Checklist for non‑code dependencies
- Owner and actor: Who does it, who approves it, who’s on call?
- Trigger and timing: Event, schedule, business day/cycle, blackout windows.
- Mechanism: Portal, email, spreadsheet, script, RPA, phone call, chat, ticket, physical print/scan.
- Interfaces and identities: URLs, forms, file locations, service/user accounts, MFA needs, distribution lists.
- Data and format: What moves (fields/files), how it’s transformed, where it lands?
- Contract/SLA constraints: Notifications, response times, vendor support hours.
- Failure path: How breaks are detected, who fixes them, workarounds/replay steps?
- Evidence and status: Artifact links, "to validate" flag, next validation step and owner.
Feed confirmed and unconfirmed items into your inventory with an owner and a validation due date. These operational links frequently become hard blockers during cutover if left unmanaged.
Build a Modernization Dependency Inventory That Supports Real Decisions
The dependency inventory provides a structured record to sort, query, and defend when setting migration waves and cutover steps.
Maintain individual records for each relationship. Link technical connections to their business purpose, usage patterns, operational owners, and support paths to enable accurate impact analysis and wave planning.
Capture essential attributes across each relationship record:
- System attributes: Source, target, environment (prod/non-prod), interface protocol, endpoints, and direction (push/pull).
- Operational details: Data sensitivity, schedule, frequency, volume, auth methods, and failure behaviors (retries, timeouts, fallback).
- Governance & evidence: Criticality, evidence source, confidence level, validation state, named owner, and support escalation path.
(Example: "Billing Service → Tax API; REST over HTTPS; push; nightly at 01:00; PII present; OAuth client-cred; retries x3; manual invoice hold if failed; critical to revenue; evidence from prod trace; confidence medium; owner: Finance IT; validate failover in UAT.")
| Source / Target | Interface & Trigger | Data & Criticality | Evidence & Last Observed | Confidence & Validation State | Next Validation Action | Owner |
|---|---|---|---|---|---|---|
| Billing App → Tax API | REST / HTTPS (Nightly Batch) | Invoice Payload (High Impact) | Prod Traces & Config (Observed 2026-09-27) | Medium Confidence (Verified in UAT) | Execute UAT failover test during dry run | Finance IT |
Treat CMDB relationship and configuration records as inputs, not truth. Reconcile them before using as planning evidence:
- Freshness: Check last‑updated vs. recent logs/flows; prefer observed runtime over stale entries.
- Duplicates: De‑duplicate by stable IDs (endpoints/queues); merge notes and owners.
- Missing fields: Fill gaps via runtime observation, config review, or SME interviews.
- Conflicts: When records disagree, break ties with direct observation or a named owner’s sign‑off, and record the decision.
Maintain a controlled relationship model rather than a static diagram. Store relationships in a quarriable format, using a graph representation where scale and complexity justify it. This enables impact analysis, cutover simulation, and ongoing change support.
With this structure in place, you’re ready to rank dependencies and cutover risks before you commit to a plan.
Rank Dependencies and Cutover Risks Before Committing to a Plan
Translate inventory findings into actionable decisions: identify co-migration groups, isolate independent services, and establish safety nets. Build a lightweight decision matrix for the change window, review it with business and ops teams, and group apps based on migration affinity.
Prioritize each dependency against the factors below. Weight only what matters for this release. Avoid a fixed formula; use ranges and expert review.
- Business criticality: What revenue, cost, or safety impact occurs if this fails today?
- Coupling: How tightly does this rely on shared code, schemas, or synchronous calls?
- Data sensitivity: What’s the exposure if data leaks or is mishandled during cutover?
- Consistency need: Must data stay strongly consistent across systems during migration?
- Trigger pattern: Is it synchronous, event-driven, scheduled batch, or human-triggered?
- Interface fragility: How brittle are file formats, schemas, timeouts, and retries?
- Ownership: Is there a clear accountable owner, or is it cross-team/third-party?
- Change frequency: How often does it change in production (and break unexpectedly)?
- Recoverability: How fast and cleanly can we detect, repair, or replay failures?
- Evidence confidence: How solid is our proof from logs, traces, and operator knowledge?
- Testability: Can we test it end-to-end before go-live, or only in production?
- Use prioritization scores to spot co-migration candidates and wave boundaries, and walk through worked decisions to confirm cutover choices:
- Worked decision example: Billing App → Shared Tax DB | Evidence: DB connection pool logs & direct table writes | Risk: High impact, tight schema coupling | Wave Choice: Co-migrate in Wave 1 or deploy an intermediate API wrapper | Test: End-to-end transaction test in UAT with schema validation | Fallback: Roll back DB schema migrations via automated scripts within 30-minute window.
| Risk Profile | Dependency Context | Recommended Action |
|---|---|---|
| High Coupling / High Impact | Shared database write schemas or synchronous blocking calls. | Co-migrate in same wave or deploy decoupling shim first. |
| Time-Bound Batch Cycles | Nightly ETL jobs, period-end closes, or financial feeds. | Schedule waves around batch windows or build CDC / replay bridges. |
| Untested / Unconfirmed | Production-only triggers, rare calendar events, or external vendor links. | Log in untested-dependency register; assign telemetry and fallback plan. |
For each high-priority dependency, create a "cutover card" that the release team actually uses:
- Required tests: Functional, performance, data-reconciliation, and failure-injection scenarios.
- Accountable owner: One named person on call to decide and to fix.
- Cutover sequence: Step order, pre-reqs, holds, and guards for this dependency.
- Monitoring/detection: Exact signals, thresholds, and dashboards to watch.
- Rollback / fail-forward strategy: Distinguish between reversing changes (rollback) versus patching issues live (fail-forward), defining triggers and steps for each path.
Maintain an explicit untested-dependency register when a dependency is production-only, infrequent, partner-owned, or calendar-driven and cannot be validated before cutover. Track:
- Why untestable: Production-only pattern, partner blackout, rare trigger, or data risk.
- Last-seen evidence: Most recent prod run, volume, and success criteria.
- Owner and contact: Who’s accountable and who to page.
- Detection plan: Signals that confirm success or show drift during go-live.
- Contingency: Holdback, feature flag, queuing, manual workaround, or timed rollback.
This step uses dependency mapping to choose migration waves, decide where decoupling is needed, and prove cutover readiness. Ranking dependencies allows you to set scope and dates with confidence while identifying items that still need action.
Close Discovery With Acceptance Criteria and Change Control
After ranking dependencies and outlining cutover cards, close discovery with clear acceptance criteria and a simple change-control rhythm.
Discovery acceptance criteria
Use this checklist to decide if discovery is complete enough to enter planning:
- Named owners: Each critical flow and interface has an accountable owner (business or technical) who will answer for readiness and cutover decisions.
- Reconciled evidence: Material dependencies show aligned evidence across runtime observation, declared configuration, and SME knowledge; any mismatch is resolved or explicitly recorded.
- Validation state: Every dependency is labeled tested/observed, simulated, or unconfirmed, with links to the test or log evidence used.
- Treatment for unknowns: Unresolved or untested risks have an agreed treatment (defer, decouple, monitor, contingency). They sit in an untested/unknown register with owner, detection plan, and fallback.
Decision record and sign‑off
Create a short decision record for your inventory to keep findings readable and auditable:
- Scope boundaries: What’s in scope for the next wave and what’s out?
- Known exclusions: Interfaces, data stores, or jobs you will not touch now and why?
- Evidence gaps: Where proof is thin and how you’ll close or mitigate it?
- Test commitments: Specific tests each owner will execute pre‑cutover.
- Monitoring commitments: Signals and dashboards you’ll rely on during cutover and steady state.
- Escalation conditions: Clear triggers for stop/rollback or fail‑forward, with decision owners.
Have business, technical, operations, security, and change stakeholders review findings affecting their responsibilities to secure explicit sign-off.
Controlled updates after sign‑off
Discovery doesn’t freeze reality; it freezes the baseline. Use light change control so updates are traceable, not silent:
- Versioned inventory: Tag the signed baseline; log each change with date, owner, reason, and impact.
- Triage new facts: Treat newly found dependencies, configuration drift, vendor changes, and cutover discoveries as change requests; update risk ranking, tests, and monitoring as needed.
- Protect the plan: If a change alters wave boundaries or cutover steps, require approval from the change authority you named in the record.
For example, if you detect an unmapped SFTP feed to a partner two days before cutover: first verify the producer, consumer, schedule, file format, credentials, acknowledgement, replay process, and partner test window; assess CDC or dual-run only if data ownership or transfer design changes.
Effective dependency management establishes confidence through evidence and structured control.
Turn the Dependency Map Into a Modernization Roadmap
With discovery signed off, treat the dependency map as your baseline. Mapping proves what talks to what and why, serving as the foundation to select target architectures, platforms, and delivery models.
Use the validated inventory to drive planning decisions and translate dependencies into concrete roadmap moves:
- Scope boundaries: Decide what’s in, what’s out, and what’s deferred. Align to business value, risk, and cutover constraints.
- Co-migration groups: Treat shared writes or tightly coupled calls as candidates for the same wave; test whether an interim interface can safely separate them.
- Modernization waves: Group by affinity and risk, then order waves with clear entry/exit criteria. Respect blackout windows, partner calendars, and data seasons.
- Integration redesign: Flag brittle points (e.g., file drops with manual retries) for pattern upgrades. Use the inventory to plan message, API, identity, and data-integration changes especially where hidden integration discovery revealed one-off jobs.
- Test strategy: Derive end-to-end tests from real dependencies. Prioritize by risk rank and validation state, including negative paths and rollback checks.
- Cutover treatment: Choose big-bang, phased, or canary per interface. Define data freeze/replay rules, dual-run needs, monitoring, and backout triggers.
- Ownership and SLAs: Confirm owners for each flow post-move. Set SLOs and observability requirements into the target run model.
- Delivery plan: Sequence tasks, lead times, and "long poles" (certs, firewall changes, partner testing). Turn the application discovery checklist and inventory into backlog items with clear definitions of done.
Carry unresolved evidence and accepted risks into the roadmap as mitigations, proof points, or go/no-go gates with named owners. For an integration control pattern that complements this discipline, see our Order-to-Cash integration control blueprint.
If your estate is .NET-heavy, see Moltech’s overview of planning patterns in our legacy .NET modernization roadmap.
Conclusion
Modernization should move forward when dependency discovery produces a record that is evidenced, owned, validated, risk-ranked, and actively governed. Ask whether you can defend scope, co-migration groups, wave boundaries, and cutover treatments using reconciled runtime behavior, configuration, SME knowledge, and workflow traces.
If yes, proceed and track accepted risks with clear owners and gates. If not, pause to close gaps by running targeted discovery, refining checklists, or resolving conflicts across logs, configs, and operational knowledge.
When your inventory tells the same story from multiple angles and every critical dependency has a named owner and mitigation you’re ready to plan with conviction and cut over with known risks, owners, and contingencies.
If you want a second set of eyes before committing, talk with Moltech about an integration and migration assessment.










