In Dynatrace Classic, monitoring a call to an external dependency meant creating a dedicated third-party service. Classic sorted outbound calls by the resolved IP address of the target: calls to public IPs landed in Requests to public networks, and calls to private IPs in Requests to unmonitored hosts. From either bucket you could promote a domain to a standalone service, or turn an unmonitored host into a custom device. Either way, the dependency became an entity in your environment.
In the latest Dynatrace, external calls are measured on the calling service instead. Every outbound call your services make is already captured as a client span, so there's nothing to promote and no entity to create. This guide explains what changes, how each Classic capability maps to its replacement, and how to rebuild the views and alerts you rely on today.
Both models can run side by side. Your Classic configuration keeps working while you validate coverage and rebuild your dashboards and alerts, so you can upgrade at your own pace.
Classic only showed you what someone had configured. A third-party dependency was invisible until an administrator found it in the Requests to public networks bucket and promoted it, which meant coverage depended on who had been paying attention, and only new data was ever mapped to the promoted service.
Measuring on the calling service inverts this. Every outbound call is already captured as a client span—no promotion step, no entity to create—which means:
external_provider.name) on metrics and spans—you filter and group by it instead of navigating to a separate entity.| In Dynatrace Classic | In the latest Dynatrace |
|---|---|
Requests to public networks service in | The External providers view Coming soon in |
More (…) > Monitor as separate service on a top domain | Nothing to promote. A curated list of providers is measured automatically by the external provider metrics Coming soon |
Standalone third-party service entity—dashboard tile, classic Smartscape node, Service flow, alerting | No entity, but the Service Map shows an external provider as a separate node and the domain is a dimension ( |
Opaque web request detection rules that map requests to a standalone service, set through the service detection rules API | Ends-with domain patterns in the Provider breakdown setting Coming soon. |
More (…) > Revert to third-party service status | Not applicable—nothing was promoted, so there's nothing to revert |
Calculated service metrics on outgoing calls | Metric extraction from spans in OpenPipeline |
HTTP requests only—gRPC was never supported | Client spans cover HTTP and RPC calls. See Limitations for what non-HTTP coverage looks like today |
dt.security_context of the calling service. For details, see Set up Grail permissions for Distributed Tracing and Set up Grail permissions for Metrics.When your environment moves to a pure latest-Dynatrace experience, Dynatrace removes historical data for Classic external and opaque services, even for timeframes that already have data. Export or rebuild any long-term comparison you depend on before the transition, not after.
List the Classic configuration you depend on, so you know what needs a replacement:
For each entry, note its purpose as most usage falls into one of three categories, each rebuilt differently: external dependency performance views, dashboard tiles or reports, and alerts.
Start with the External providers view Coming soon in
Services, which replaces the Classic top domains table. The External providers view lists every provider your services call, with throughput, error rate, and response time per provider, and needs no configuration to populate. "External" here means the target isn't a service that Dynatrace monitors—it covers third-party APIs, content delivery networks, and first-party services outside your monitored estate.
For a single service, select the service and open the Outbound calls tab. The Outbound calls tab shows request rate, error rate, average duration, and cumulative duration per external call. For details, see Outbound calls.
Match each entry from your inventory against these two views. Anything you can't find is either a provider that isn't recognized yet, which you add in Recognize your providers, or a non-HTTP target—see Limitations. To hunt for targets that neither view surfaces, query client spans directly. See Find unrecognized targets.
Filter before you aggregate. An unfiltered query over all client spans in a large environment returns the loudest domains, not the ones you care about. Scope to a Kubernetes namespace, a cloud account, or a set of services first.
Permissions. Span queries return only the data you're allowed to see. Because outbound call spans carry the security context of the calling service, a user who can see a service can see that service's external calls—there's no second entity to grant access to. For details, see Set up Grail permissions for Distributed Tracing.
Segments. A segment can scope your outbound call analysis, but note that segments define their filters per signal type: an include block for Spans scopes span queries, and an include block for Metrics scopes metric queries. A segment written only against service metrics doesn't filter a span query, so add a Spans include block when you want provider discovery scoped the same way.
Recognized providers are measured automatically, so most of your inventory needs no work at all. This step covers the rest.
Dynatrace automatically detects more than 1,000 providers—including Google, Amazon, and Microsoft.
The setting classifies each provider as first-party, third-party, or CDN. To cover a provider that isn't recognized, add a custom entry. Each entry defines:
Stripe.stripe.com covers both api.stripe.com and files.stripe.com)Adding an entry is the closest counterpart to promoting a domain in Classic, and it's where discovery closes the loop: you find an unrecognized domain in your outbound calls, then add it as a provider so that it's measured from that point on. What you get differs from Classic, though—an entry in a provider list, not a service entity in your environment.
The setting currently allows up to 100 custom provider entries, each with up to 100 domain name patterns.
The external provider metrics are broken down by provider and by calling service. If you need a dimension they don't carry—a breakdown by calling endpoint, by URL path, or by a custom attribute—extract your own metric from client spans with OpenPipeline. The Extract metrics from spans tutorial covers exactly this case—see Response time for outbound calls to paypal.com per service, as measured by the caller, matching on server.address.
This is also the path for calculated service metrics you defined on outgoing calls in Classic, which aren't carried over.
URLs that contain identifiers in the path, such as /orders/abc-def-123, produce unusable aggregations and expensive metrics. Normalize them before you extract metrics. See Limit cardinality of external calls.
Build these on the external provider metrics Coming soon, which measure calls to external providers automatically.
The metrics are broken down by external_provider.name, the raw target domain of the call, and carry the same Kubernetes, cloud, and cost attributes as the other service metrics, so you can scope them the same way. To chart all providers in one query:
timeseries {calls = sum(dt.service.external_provider.count),responseTime = avg(dt.service.external_provider.response_time),errors = sum(dt.service.external_provider.error_count)},by: { external_provider.name },nonempty: true
From there:
Dashboards or
Notebooks, splitting by domain to reproduce the Classic per-service view.
Anomaly Detection. For guidance, see Configure a simple custom alert.If you extracted your own span metrics in the span metrics section, chart and alert on those the same way.
Dynatrace doesn't apply automatic baselining to external dependencies. Define your own alerts on external providers using thresholds or SLOs that reflect your agreement with the provider.
Run both models in parallel for at least one full traffic cycle, including a peak period.
Services > Explorer > External providers Coming soon and confirm that every provider you monitored in Classic appears with non-zero throughput.Expect the numbers to differ from Classic. error_count counts errors, not failures: full failure detection—which decides whether a call had business impact rather than merely a technical error—is not applied to these metrics, so this number is not directly comparable to the failure rate of a Classic promoted third-party service.
One override applies: if a span explicitly sets span.status_code to ok, the call counts as a success even when another error indicator, such as an HTTP status of 400 or above, is present. An explicit ok outweighs every other indicator.
The External providers view covers recognized providers. To find targets that aren't recognized yet, query client spans directly. This runs today, with no configuration. Run it in
Notebooks.
The query counts calls per target, extrapolated to account for sampling, and leaves out database and messaging calls, which have their own views in
Services.
fetch spans// keep outbound calls that have a target address| filter span.kind == "client" and isNotNull(server.address)// exclude database and messaging calls, which have their own views| filter isNull(db.system) and isNull(messaging.system)// calculate how frequently each span is sampled| fieldsAdd sampling.probability = (power(2, 56) - coalesce(sampling.threshold, 0)) * power(2, -56)| fieldsAdd sampling.multiplicity = 1/sampling.probability| fieldsAdd multiplicity = coalesce(sampling.multiplicity, 1)* coalesce(aggregation.count, 1)* dt.system.sampling_ratio| summarize calls = sum(multiplicity), by: { server.address }| sort calls desc| limit 50
The result covers more than third-party APIs. Internal hostnames, Kubernetes service names, localhost, and bare IP addresses all appear, because a client span records whatever address the call was made to. Classic sorted this out for you by resolving the address and splitting public from private IPs; that split isn't part of the data, so deciding which targets count as external is yours to make.
Exclude the internal names you recognize, for example:
| filter not matchesValue(server.address, "*.svc.cluster.local")| filter not matchesValue(server.address, "*.internal.example.com")
What's left that you don't recognize is the set of coverage gaps Classic never showed you unless someone went looking. Add the ones that matter to the Provider breakdown setting—see Recognize your providers.
They were removed, by design. External and opaque services weren't carried into the latest Dynatrace, because dependency data now lives on the service that calls the dependency. Open the service and go to the Outbound calls tab, or use the External providers view Coming soon, which lists every detected provider environment-wide.
If a service you expect doesn't appear, that's the reason—it isn't a permissions problem or a broken configuration.
No. Outbound calls are captured as client spans by OneAgent or your OpenTelemetry instrumentation, and recognized providers are measured automatically. Configuration only becomes relevant when a provider isn't recognized yet—see Recognize your providers—or when you need a dimension the built-in metrics don't carry.
Outbound call data is measured by the caller, so it includes network transit and TLS handshake time. A Classic promoted service also aggregated all callers into a single entity, whereas the new model keeps each calling service separate. Both differences are expected—see Verify before you switch off.
No, and there's no replacement planned. Outbound calls show you that the dependency exists and how it behaves from the caller's side. For visibility inside the target, monitor it directly with OneAgent, instrument it with OpenTelemetry, or use an extension.
They aren't carried over. Rebuild them as span metrics with OpenPipeline. See Extract metrics from spans and distributed traces and Upgrade from calculated service metrics to Grail.
Services