Skip to content

Find the workload’s bottleneck, not just a busy resource

A resource is busy. Another is quiet. The workload score looks reassuring.


Which one should the team investigate before approving more capacity?


Azure Monitor supplies the metric observations. Azure Resource Graph supplies the resource context. Azure Support Agent’s Performance Profiler brings them together with AMBA-aligned reference thresholds so operators can compare possible constraints across a workload, not just sort unrelated utilization percentages.


The useful outcome is a better next question: which resource, which metric, during which window, supported by what evidence? A high-ranked candidate directs attention. It does not establish the cause of slow bookings, justify a resize, or replace application telemetry.


This article follows a simulated review of Contoso Booking · synthetic, a fictional hotel booking workload using built-in Contoso hotel resource names. The readings were generated offline from built-in demo code and its reference, not collected from Azure. There is no recorded incident, executed capacity change, or measured improvement behind the story.



About the animations: the four GIFs use deterministic browser fixtures and synthetic demo data, not a live tenant or actual Azure calls. Collection, saved history, and workflow outcomes represented in them are modeled presentation states, not proof of backend execution, persistence, restart recovery, or external delivery. Displayed dates and statuses are illustrative labels, not a verified collection timeline.




Faster-paced synthetic native-component tour, approximately 60 seconds. It opens Cleanup without deleting a run. Editorial pacing is not Azure collection speed.


Begin with a workload question


Imagine a performance engineer reviewing Contoso Booking before approving capacity work. The application includes booking services, reservations SQL, a Redis session cache, and a legacy property-management VM with a managed disk. The question is not whether any one resource is busy. It is where resource pressure might constrain the booking path and what would justify investigating it.


A database working hard during legitimate demand may be behaving exactly as designed. A moderately loaded application can still wait on a dependency. Conversely, an alarming-looking percentage on a noncritical background component may be less urgent than a small but sustained constraint on the customer transaction path.


Workload context makes those differences discussable. It does not automatically establish which dependencies were on the critical path for a particular request. That still needs architecture knowledge and request-level evidence.


The saved synthetic profile has a workload score of 95 across 14 resources: 3 breaching, 3 approaching, and 8 healthy. Its leading examples are:


Synthetic resource Metric Observation and reference First interpretation
contoso-redis serverLoad 93.5% against an 85% threshold Breaching; leading ranked candidate
contoso-pms-vm-datadisk Disk IOPS saturation 83.2% against an 80% threshold Breaching; inspect provisioned IOPS
contoso-sql/reservations DTU utilization 76.5% against a 90% threshold Approaching, not breaching


These values come from the same synthetic dataset used in the GIFs; the thresholds come from its built-in reference. They are not universal recommendations. A real review uses the active reference, supported metric definition, and observations for its own resource and window.


Redis is now a plausible starting point. The managed disk is another candidate, while SQL offers an approaching rather than breaching contrast. None of those statements requires declaring an outage or pretending the team has found its cause.


That is the profiler’s role in the investigation: reduce a broad inventory into a small set of evidence-bearing questions. The engineer can then ask whether cache pressure coincides with booking latency, whether the activity is expected, and whether the reference fits the service tier. Those are more productive questions than “which resource has the biggest number?”


Set the evidence boundary before collecting


Open Performance Profiler and choose a workload or subscription. Workload mode is useful when the operational question concerns one application. Subscription mode is useful when the boundary is administrative or the workload definition needs review. Neither choice makes unsupported resource types measurable.


Confirm the connection as carefully as the scope. A workload uses its own connection unless an explicit connection is selected. The application permission is perfprofile.read; the enabled Azure connection also needs the relevant Resource Graph and Azure Monitor access. A visible workload name is not evidence that every underlying metric can be read.


Then choose exact start and end times. For Contoso Booking, define one business-relevant period and retain it throughout the first comparison. Record the time zone. A morning peak and an overnight quiet period answer different questions even when both reports say “one day.”


The current defaults are a one-day metric window, a configured 15-minute interval, and a resource scan cap of 200. Those are operating defaults, not a promise that the workload fits inside them or that every check uses the same aggregation grain. Review the actual settings and the result’s selected and eligible counts.


Resource discovery and metric eligibility are different steps. Resource Graph identifies the discovered footprint. The active reference determines which resource types and metrics the profiler can evaluate. All Resources includes inventory context without a supported metric definition; those entries do not become scored rows merely because discovery found them.


Before pressing Run profile, ask whether the scope actually represents the booking path. A shared dependency outside the workload definition can matter operationally while being absent from this report. An unrelated included resource can influence the aggregate without explaining the application question. Correct the boundary or document it; do not rely on the workload’s friendly name to settle membership.


Opening the feature reads stored history and results. It does not automatically start a new Azure scan. Selecting Run profile initiates collection; reviewing a saved attempt is a different action. This makes a read-first review possible when the first question is simply what evidence already exists.


The repeatable boundary is scope, connection, exact window, reference, and collection limits. Carry those inputs into subsequent comparisons so a changed denominator does not masquerade as a changed workload.


Read collection status before the score


The first result to inspect is not the largest circle or the reddest cell. It is the collection status and its counters.


An attempt records discovered, eligible, selected, and completed resources, together with metric-check and request information. Each count answers a different question. Discovery does not mean a resource had supported metrics. Selection does not mean every check returned observations. Completion does not mean those observations establish application health.


The practical distinctions are:


Result What the operator can conclude
Observed metric There is a value to compare with this metric’s reference and direction.
No data A request completed without observations; the displayed no-data state remains unknown.
Failed check The metric could not be evaluated after the applicable attempts; inspect the collection error.
Partial attempt Some evidence is available, but a check failed or the resource scan cap truncated the selection.
Succeeded attempt Collection completed without failed checks or scan-cap truncation; inspect remaining no-data cells.


Completeness measures checks that completed with observations or a valid no-data result. It is not the percentage of resources proven healthy. A run can therefore report 100% completeness and still have an unknown score if every supported metric lacks observations.


If a metric returns no observations in another review, leave its cell as an open question. Do not give it a perfect score. That rule is separate from the populated cells in this synthetic profile. Check metric support, window, aggregation, provider delay, and access before choosing the next collection. Replacing the blank with zero would invent a reading; replacing its score with 100 would invent confidence.


A failed check deserves a different response. Throttling, a timeout, an access failure, and a valid empty series are not interchangeable. The collector retries transient request failures within bounded limits, but retry exhaustion remains visible as failed collection. Inspect the error details rather than repeatedly submitting the same work without a diagnosis.


The resource cap deserves equal attention. If more resources are eligible than selected, finishing every selected row still leaves a partial attempt. Narrowing to a justified workload can make the next investigation manageable; silently treating the selected subset as the entire estate cannot.


Keep two conclusions separate in the review note: what the observed metrics suggest and what the collection could not establish. A cache candidate may deserve investigation even if another metric remains unknown. An unresolved cell is not a reason to discard all evidence, but it is a reason not to declare the workload comprehensively assessed.


Use the heatmap to choose the next question


The Heatmap organizes resource rows against metric columns. Its value is not simply color density: it places unlike resources beside the references that make their observations meaningful. The same percentage can mean very different things for CPU, availability, and provisioned I/O capacity.


Start with the full loaded result. Notice where breaching and approaching cells cluster, which resources have observations, and where the matrix remains unknown. Then inspect the ranked bottlenecks and the binding bottleneck callout. Read that label as the model’s leading candidate, not as a measured constraint on end-to-end application throughput.



Synthetic native heatmap: focus mode, Problems and At-risk filters, then a Redis search. These controls narrow the loaded result, not Azure resources, the original collection, or the completeness of its evidence.


Use a resource-type filter when comparing a candidate with relevant peers. Use region or search to isolate the intended resource, as the GIF does with Redis search. Posture and score filters answer different questions: a resource can contain a breaching cell even when its aggregate score is comparatively high. Sorting by score and sorting by the number of breaches therefore need not produce the same order.


Pruning empty columns can make a focused matrix easier to read. Hiding no-data rows can also reduce visual clutter, but it is a presentation choice, not evidence that those resources became healthy. Return to the unfiltered view before describing the result’s coverage.


For Contoso Booking, narrow to contoso-redis, then return to the managed disk and approaching SQL database. That contrast is deliberate. It tests whether attention is being directed by metric evidence rather than by the most familiar resource name or the most dramatic color.


Use All Resources to reconcile the picture with inventory. An entry without a supported reference helps explain what is outside scoring. It does not establish that the resource has no relevant performance signals elsewhere in Azure.


Finally, distinguish a filtered screen from a run-specific artifact. The PDF and Evidence actions address the run; do not assume a narrow heatmap view means the resulting report contains only visible rows. Review the artifact before sharing it. The visual is an entry point into the evidence, not a substitute for understanding its boundary.


Compare each metric on its own terms


AMBA-aligned thresholds provide a common reference for prioritization, not a universal performance contract. Azure Monitor Baseline Alerts supplies monitoring guidance; the profiler uses the active reference alongside metric semantics. It does not rewrite Azure alert rules when it calculates a score.


The first distinction is direction. Higher CPU, latency, or utilization may be worse. Lower availability or available memory may be worse. Read the threshold or floor, unit, and comparison direction together. A lower numerical value is not automatically an improvement.


For higher-is-worse metrics, approaching begins at 70% of a nonzero threshold. Lower-is-worse metrics use proximity to the risk side of their supported operating range instead; applying the CPU rule to availability would make a misleading comparison. Metrics with zero-count thresholds also need their own semantics rather than division by zero.


In the displayed Redis example, server load of 93.5% against an 85% threshold is 110% of the threshold. It is not 110% of provisioned capacity. The normalized relationship helps rank the candidate; the original 93.5% observation and its definition remain essential evidence. For lower-is-worse cells, a percentage of the minimum achieved has a different meaning again.


The second distinction is aggregation. Average, Maximum, Total, and Count are not synonyms. The profiler honors the reference’s declared aggregation, with metric-specific fallback semantics when it is omitted. Comparing an average response time with a maximum response time will not verify the same claim. Neither is automatically a request-latency percentile.


There are also two time boundaries. The profile window describes the period under review. The effective interval describes how readings are bucketed within it. The collector uses the coarser of the configured interval and the reference alert’s window. An hourly capacity check can therefore use hourly buckets inside the same one-day profile whose other checks use 15-minute buckets.


The state is based on the worst observation in the direction of concern: the higher extreme for higher-is-worse readings, the lower extreme for lower-is-worse readings. A peak of 15-minute averages is not the highest instantaneous sample. A daily mean cannot reproduce either of those comparisons.


Dimensions matter too. A count restricted to particular response codes answers a different question from all requests. Storage service metrics may target the blob, queue, file, or table service beneath the account rather than the account resource itself.


When verifying a cell, match resource target, metric, dimensions, units, aggregation, effective interval, and exact window in Azure Monitor. Microsoft’s metrics aggregation guidance explains why changing these inputs can change the apparent story without changing the workload.


Open the resource, not just the red cell


Open the Redis row to inspect its resource detail. The drawer brings metric observations, thresholds, summary values, sparklines, and available headroom information into one place. Confirm the resource identity and region before interpreting the chart. A similar name in another environment is not corroborating evidence.



Synthetic Redis detail supports a hypothesis about cache pressure. These are modeled readings, not production telemetry, a tested capacity limit, or a verified explanation of latency.


Ask whether the concerning value is sustained, repeated, or isolated. Compare the observed worst value with the average and the later samples. A resource can have recovered by the end of the window while its earlier breach remains relevant. Conversely, one narrow peak should not be described as continuous saturation without looking at the series.


The compact chart is useful context, not an unlimited archive. Stored cell series are capped to their latest 60 samples, while the summary statistics are calculated over the collected series. A longer window can therefore retain a worst value whose original point is not visible in the compact sparkline. Use Azure Monitor for the full source comparison.


Treat trend direction with the same care as threshold direction. Rising available memory and rising CPU utilization do not carry the same operational meaning. A trend percentage describes change within the selected observations; it is not a forecast of when capacity will run out.


Headroom is another derived reading. For supported higher-is-worse metrics with a fixed ceiling, it expresses distance from that ceiling. It is not necessarily distance from the alert threshold. For managed disks, the collector derives IOPS and throughput saturation from read/write counters against provisioned limits, making the capacity denominator part of the evidence that must be checked.


An IOPS limit and a throughput limit constrain different workloads. Small random operations and large sequential transfers can stress different limits at similar operation counts. Inspect both where supported, and verify the provisioned values used by the profile.


For Contoso Booking, the next step would be to compare Redis server load with transaction demand, cache-operation latency, application dependency timing, and relevant deployment events. More capacity is one possible response, not the conclusion supplied by the drawer. A useful investigation can instead identify inefficient work, a changed request mix, or an inappropriate comparison window. The profiler makes the candidate inspectable; operators still have to test the explanation.


Do not let the workload average hide the constraint


Resource scores summarize observed metric states using severity weights. A breach applies the full metric weight as a penalty; an approaching state applies half. No-data cells are excluded rather than rewarded. A resource without observed cells has an unknown score.


The workload score is the average of resource rows with observations. It is not weighted by customer journeys, transaction counts, revenue, or dependency criticality. That makes it a useful summary of the evaluated rows, but not an application service-level indicator.


The displayed workload score is 95, yet three resource rows are breaching. Redis leads the bottleneck list while the managed disk also crosses its IOPS threshold. If that cache is essential to every booking, the reassuring score does not reduce its operational importance. Nor does it establish that the eight healthy rows have no unmeasured risks.


The reverse also matters. A low score on a peripheral batch worker does not prove that interactive bookings are slow. The team must connect the observed pressure to the service objective under review.


Keep the score, the worst relevant cell, and collection completeness visible in the same conversation. For Contoso Booking, that means discussing the Redis candidate despite the score of 95, while distinguishing healthy observed rows from signals the profile never measured.


Use the score to organize attention and compare sufficiently similar runs. Use the metric evidence to explain the candidate. Use application SLOs, logs, dependency traces, and demand context to determine whether the workload actually experienced the behavior being investigated. Those are complementary layers, not competing dashboards.


Keep the latest attempt beside the latest success


Profile history records attempts, including partial and failed ones. Fleet’s trusted result, the successful-result cache, and score trends use complete successful runs instead. Fleet overlays the newest attempt status in its score cell. These are deliberately different views of the evidence.


When a complete result is followed by a partial attempt, keep both in the investigation. The partial attempt belongs in history, with its errors and available observations. It does not replace the cached complete result or add a trusted trend point simply because it is newer.


In the Fleet GIF, the partial badge occupies the score cell. To inspect the retained score of 95 and its metric evidence, open the prior complete run in history.


That behavior protects an earlier result from being overwritten by failed collection. It does not make the earlier result current. Read the successful run’s age and window alongside the newest-attempt status. The default successful-result freshness period is six hours; a stale badge is information, not an automatic scan request.



Synthetic Fleet states contrast a partial latest attempt with a never-profiled workload. Inspect prior complete history separately; this animation does not demonstrate collection, persistence, retry, cancellation, or restart recovery.


History also makes a before-and-after comparison possible, but only after establishing comparability. Hold membership, reference, metric semantics, and time-window characteristics steady. Record a change in service tier or provisioned capacity because the denominator may have changed along with utilization. Compare demand and user-impact evidence as well.


A better score after a quiet period is not proof that a tuning change worked. A missing trend point can reflect incomplete collection rather than stable performance. Open the underlying attempts when a trend seems unexpectedly smooth.


Preserve the specific run needed for a decision before cleanup. Current history retains at most 30 active attempts per tenant and scope; trashed attempts remain until restored or purged. Trash is reversible. Purge is not, and Cleanup selection can include more than the currently filtered rows, so review the complete selected count.


Evidence Locker snapshots are separate artifacts. Deleting a profile run does not turn an existing snapshot into a fresh result, and retaining a snapshot does not keep the original run in active history. Decide what must survive according to the investigation and the organization’s retention policy.


Use Fleet when the work must outlive the browser


A focused profile is appropriate when investigating one workload or subscription. Its browser stream shows per-resource progress and can remain active while navigating within the same browser tab. That convenience is not the durable Fleet queue.


If the focused stream disconnects, the interface reports the interruption and refreshes history and Fleet. The server task may still finish and save its attempt. Check history for the same scope and window before submitting another scan. A stopped progress display does not establish the final collection status.


Focused runs do not provide Fleet’s server-restart recovery. Choose Fleet when a selected workload set needs durable queue tracking. The server creates a SQL-backed batch, and its items progress independently of the original browser. On startup, an interrupted running item is re-queued while terminal items retain their results.


This extends the same investigation question rather than changing it. Select a bounded set of workloads and one shared time range, submit once, then open the candidates whose evidence merits attention. The maximum accepted submission is 500 workload IDs, not a statement that all 500 run simultaneously or finish within a particular duration.


Read queued and running states separately from succeeded, partial, failed, and cancelled. Cancel pending cancels queued items; the claimed workload is allowed to finish safely. Retry failed/partial creates a new batch for retryable failed, partial, and cancelled items. The backend retry preserves the original time window. Check the range if instead making a fresh selection and submission.


Concurrency remains bounded. Defaults are one Fleet workload at a time and two Azure Monitor requests in parallel through a shared process-wide gate. Increasing parallelism can increase throttling, partial attempts, and host load rather than improve useful throughput. Consult the profiler capacity settings before changing them; the gate is process-local, not a distributed quota across replicas.


Judge a Fleet review by reconciled batch and item states, matching windows, and inspectable results. A terminal batch control record and its completed profile runs have separate lifecycles. Deleting the former does not delete the latter, and neither proves that an operator has validated the leading performance candidate.


Carry the evidence into a real investigation


The useful handoff is not “Redis red, please scale.” It is a bounded observation with a testable question and enough context for another person to reproduce it.


For the simulated Booking review, an appropriate note would identify Redis serverLoad, the synthetic 93.5% observation, reference threshold of 85%, illustrative window, and collection limitations, then ask what workload behavior could explain that pressure. In a real case, replace every synthetic value with independently checked source evidence before sharing it as an operational finding.


Performance Profiler offers several destinations, each with a different purpose.


PDF creates a portable report for the displayed or selected historical run. Prefer the run-specific report when preserving a decision; a latest-success fallback can refer to a different attempt. Open the generated document and confirm the scope, run time, window, resource, and metric. A report is a representation of saved evidence, not a fresh Azure query.


Evidence captures a run as an immutable Evidence Locker snapshot. Use it to retain the profile you actually reviewed. This profiler-specific capture is distinct from assuming the generic Evidence Locker metrics checkbox gathered a new metric series. Inspect the snapshot’s contents and notes. Immutability preserves what was captured; it does not make a partial attempt complete or certify the source observations as true.


Register findings creates a lightweight Performance-pillar assessment run from the displayed bottlenecks. It is workload-only and has no overall assessment score. It is not a complete Well-Architected Framework assessment and should not be ranked as one.


There is a scope check worth making explicit: opening a historical run does not mean the current workload selector has been aligned for every action. Before registering findings or using War Room, confirm the selected workload matches the report. PDF and Evidence can target the saved run by ID directly.


War Room carries a bottleneck into chat for investigation. Review and supplement the handoff with the original time window, run reference, collection gaps, and source-verification notes. Do not assume the short generated prompt contains the whole report. The optional AI narrative is a hypothesis to compare with the matrix; scores and collection status do not depend on an AI provider.


Ticket is a real external handoff through a configured Jira or ServiceNow connector. Profiling reads Azure; ticket creation writes to another system. Finding registration and Evidence also create application artifacts. The permission name perfprofile.read should not be interpreted as a guarantee that every profiler action has no side effects.


Choose the intended destination and approved audience before sending. After a real submission, open the destination ticket and confirm what arrived. Add the run link, window, aggregation, resource context, and unresolved questions where the generated text omits them. A notification or success message alone is not evidence that the correct team received a usable investigation.


None of those deliveries is performed by this article’s synthetic animations. For actual operations, keep the candidate separate from the corrective decision. Capacity or tuning changes require the appropriate review and execution process outside this profiling workflow, followed by comparable metric and application-level verification.


The Evidence Locker reference and Assessments guide explain the receiving surfaces. Preserve the question along with the artifact: the next reviewer should understand both why this resource deserves attention and what evidence would support or reject the proposed explanation.


How it’s judged


A useful Performance Profiler review leaves another operator able to answer:



  • What was examined? The workload or subscription, connection, membership, exact window, and collection limits are explicit.

  • What was actually observed? The candidate has a metric, unit, direction, aggregation, reference, and source comparison, not just a score.

  • What remains unknown? No-data cells, failed checks, unsupported resources, and truncated scope remain visible in the conclusion.

  • Why investigate this resource? The candidate is relevant to the workload question even if the average score looks acceptable.

  • Which result is being used? The latest attempt is distinguished from the latest success, and any historical comparison accounts for changed inputs.

  • What survives the handoff? The receiving report, evidence record, finding, or ticket retains enough context to reproduce the observation and continue the investigation.


The standard is not that the heatmap becomes green. It is that the team can explain its next decision and the evidence still needed. Rejecting an attractive but unsupported capacity hypothesis is a useful outcome too.


Try a read-first review of one candidate


Start with one known workload and existing history, not an estate-wide collection:



  1. Confirm the scope, connection, time window, and age of a saved successful run. Read any newer partial or failed attempt alongside it.

  2. Inspect completeness and inventory membership before choosing a ranked metric.

  3. Open one candidate and one contrasting healthy or no-data resource. Explain their states using the actual direction, threshold, units, and aggregation.

  4. If authorized to read the source, reproduce the important observation in Azure Monitor using the same target and effective interval.

  5. Record a hypothesis, the missing evidence, and the next verification. Stop before sending tickets or making capacity changes unless those actions are separately intended and authorized.


The Performance Profiler reference and step-by-step operations guide cover collection, Fleet recovery, history, and handoffs in detail. Microsoft’s Azure Monitor metrics overview provides the platform context for the observations being compared.


Azure Support Agent is open source. Review the repository and documentation before deployment or expanding a connection’s access. Hosting and connected services can incur costs; this read-first exercise does not require an AI narrative or an external ticket.


The next useful decision is not “find the busiest resource.” It is find the candidate whose evidence explains why it deserves investigation, and carry that evidence forward without losing its scope, time, or uncertainty.

Microsoft Tech Community originally posted this article on 16 September 2026 at 4:43 PM.

Leave a Reply