Azure Cloud Fundamentals Case Studies
Technical5 Case StudiesUpdated Sep 2026
These five cases follow one Azure estate through problems that tend to appear after the first production launch. Each starts with a situation most practitioners will recognize: a release that degrades a service, reports that disagree, a suspicious sign-in pattern, a platform that strains under growth, and an automation proposal that looks cheaper than it is. Every case returns to four concerns: what the system must do, what the measurements show, who may touch what, and whether the result can be maintained after the incident channel closes.
Case Study 1
Dispatch slowdown after a cache key release
Halvard Parcel Logistics, a regional software firm that runs dispatch and tracking for 340 carriers
The situation
Halvard's dispatch API runs on Azure App Service, backed by an Azure SQL Database and a Redis cache that holds route lookups. On a Tuesday afternoon in the second week of the quarter, a release changed how the cache keys were built for those lookups. Within forty minutes, p95 response time on the dispatch endpoint climbed from 310 milliseconds to 4,800 milliseconds, and about 12 percent of driver check-ins began timing out. The on-call engineer, Priya, saw the alerts first. The release had also changed a connection string setting in the same pipeline run, so the initial hypothesis pointed at the database.
The challenge
The team had to restore dispatch for drivers in the field without rolling back a fix that two large customers needed. Logs were split between App Service diagnostics and a Log Analytics workspace that captured only part of the traffic. Several engineers held contributor access to production resources, so it was unclear whether a configuration change came from the pipeline, a manual edit, or an older maintenance script.
Analysis
The requirements were specific: lookups under one second during check-in peaks, and stale route data acceptable for short periods but never wrong data. Application Insights showed database query duration flat across the incident, while time spent waiting on the cache client rose sharply. The cache hit ratio had held above 90 percent before the release and fell below 40 percent after it, which meant the new key format was missing entries the old format had covered. Teams grounded in Azure Cloud Fundamentals usually begin with this kind of requirement check, because it turns a vague slowdown into a measurable gap between expected and observed behavior.
Access review came next, and it carried as much weight as the performance numbers. The deployment identity held Owner rights on the resource group, which was broader than the pipeline needed, and two engineers had edited app settings by hand during the incident. The activity log recorded both edits, so the team could separate pipeline changes from human ones without guessing. They moved the cache key format into a versioned setting, limited production writes to the pipeline identity through role-based access control, and required a change record for any manual setting edit. Maintainability improved since the runbook names each setting, its owner, and the stage allowed to change it.
Actions taken
- Reverted the cache key setting in the App Service configuration while keeping the release's other changes, then confirmed the hit ratio recovered within twelve minutes.
- Narrowed the pipeline's deployment identity to Contributor on the app and database scope, removed Owner rights from the resource group, and logged the change in the activity log.
- Added alert rules for cache hit ratio below 70 percent and dispatch p95 above 800 milliseconds, routed to the on-call rotation with a five-minute evaluation window.
- Rewrote the runbook so every production setting lists its owner, default value, and the single pipeline stage allowed to change it, then walked the on-call group through it.
Results
Dispatch p95 returned to 320 milliseconds within the hour, and driver check-in timeouts fell below half a percent by the end of the afternoon. The corrected key format shipped the following week after a 15 percent canary ran clean for two days. Over the next month the team recorded no manual production setting edits outside the pipeline, and the new alerts caught a smaller cache regression during a planned load test before any customer saw it. The review found that no test covered cache key compatibility, and that gap now has one.
Questions for discussion
- Which settings in your own environment would you route only through the pipeline, and how would you keep emergency fixes from being slowed by that rule?
- What evidence would have ruled out the database earlier, and which tool in your stack would have shown it first?
- How should a runbook balance detail against speed when an on-call engineer is working under pressure?
Case Study 2
Board report figures that disagree by eighteen percent
Brackenridge Power Cooperative, a rural electricity distributor serving 86,000 meters across four counties
The situation
Board packs for the quarter showed outage minutes per customer that differed by 18 percent between the operations dashboard and the finance pack. Both figures drew on the same pipeline, which copied meter readings from an on-premises system into Azure Data Lake Storage, transformed them in Azure Databricks, and loaded a curated table in Azure Synapse Analytics. Two weeks before the meeting, the analytics lead found that about 2,300 meters had no readings for the final six hours of the month, and that a feeder reference table had been edited by hand. The reports were built correctly from their inputs, which made the gap harder to explain to the board.
The challenge
The board wanted one figure per feeder, while the finance team needed reconciliation to a billing system that used different month-end cutoffs. Lineage was partly recorded in a spreadsheet that had not been updated since the last platform migration. Operations had read access to the curated tables but no visibility into ingestion logs, so nobody on that side could see which files had arrived late.
Analysis
Start with the requirement, not the pipeline. The board needed outage minutes per feeder for each calendar month, with a written rule for late readings and a freshness standard that required each reading to land within six hours of its interval. Ingestion logs showed late file arrivals on three days, and row counts in the lake did not match the meter registry for the 2,300 affected meters. The Databricks job had filled those gaps with the previous reading, which hid the problem in the curated table. A check of completeness at each stage, not only at the end, would have caught the missing hours within a day.
Access controls explained part of the drift. The feeder reference table was edited directly in Synapse by two analysts with write rights, and no record showed who changed which assignment or why. The first fix was narrowing that: the table moved to a managed location, write access went to one service identity, and manual edits became pull requests in the repository that holds the transformation code. Lineage became maintainable once each curated dataset listed its source, owner, refresh time, and the monitoring rule that covers it, stored in a data catalog rather than a spreadsheet. Operations and finance could trace any figure to its inputs unaided.
Actions taken
- Added row count and checksum comparisons at three points: lake landing, after the Databricks transformation, and in the curated Synapse table. Mismatches now fail the pipeline instead of passing silently.
- Replaced the silent previous-reading fill with an explicit estimate flag, so every filled value carries a column that operations and finance can filter on.
- Limited write access to the feeder reference table to one service identity, required pull requests for any manual edit, and asked for the reason in each commit message.
- Published a lineage page for each curated table listing sources, owner, refresh time, and the monitoring rule, then linked those pages from both board report templates.
Results
Within a month, the gap between the operations dashboard and the finance pack for the board's reporting period fell below 0.4 percent, and the remaining difference traced to two feeders with known billing lag. The pipeline failed loudly three times in that stretch, each time over late landing files, and each failure was resolved before the next business morning. Finance accepted the estimate flag as the basis for disputed readings. The board received a corrected report with a note on what changed, and freshness alerts now appear in the weekly operations meeting rather than in an ad hoc thread.
Questions for discussion
- Which of your reports fills gaps without saying so, and who would notice if the fill were wrong?
- Should an estimated value share a column with measured values, or sit in a separate one, and what would you give up with each choice?
- What single control would give you the most confidence that a reference table edit reached production as intended?
Case Study 3
Suspicious sign-in and an unexpected role on guest exports
Thornbury Hospitality Group, an operator of 23 hotels with a central booking platform and nightly partner exports
The situation
On a Friday evening in the last week of the quarter, the cloud security monitoring service raised two linked alerts. The first flagged a sign-in by the workload identity used by the booking sync job, coming from an address range the company had never seen for that identity. The second reported a new role assignment on the storage account that holds the nightly guest export files. The sync job normally authenticates only from the hosted runtime's own addresses, and its exports carry names, stay dates, and payment card last four digits.
The challenge
The alerts could be a misconfigured automation account or a real intrusion, and the team had about two hours before the overnight batch sent files to partner systems. Disabling the identity would stop the batch and interrupt check-in data at several properties. Four people held Owner rights on the subscription, and the on-call roster still listed two who had left the company.
Analysis
Scoping began with what normal looks like: one nightly run, a fixed manifest of partner files, and no interactive use. Sign-in logs showed the identity authenticating from the new range at 19:40, about thirty-five minutes before the role assignment appeared. Storage analytics showed read operations on the export container at roughly forty times the usual overnight rate, including files from prior quarters. That pattern points to data access, not a misconfigured job, so the team treated the event as a probable compromise. Preserving the record came first, because every later decision depended on knowing which files were read and by which identity.
Access rules were both the cause and the constraint. The new role assignment gave the identity read rights on the export account, and Owner rights on the subscription sat with four people, two of whom had left. Containment had to stay narrow. The team removed the unexpected role, restricted the storage account to the job's known address ranges, and rotated the federated credential instead of shutting the job down. Every step went into the incident log with the time, the approver, and the reason, so the response could be audited. Maintainability was the longer problem since nobody could say which partner systems consumed each file.
- 1Triage the alertConfirm the sign-in and role change against known normal activity.
- 2Preserve evidenceExport logs to a locked container before changing any configuration.
- 3Contain accessRemove the unexpected role and narrow network access to known ranges.
- 4Verify before releaseHold the export and check its manifest against the previous week.
- 5Document and reviewRecord each step, approver, and time for the post incident review.
Actions taken
- Preserved evidence by exporting sign-in, activity, and storage analytics logs for the prior 72 hours into a locked container under legal hold, before any configuration changed.
- Removed the unexpected role, restricted the storage account to the job's known address ranges, and rotated the federated credential, with each change approved by the incident commander on a shared call.
- Held the nightly export for one run and checked its file manifest with the partner integration lead against the previous week before releasing it under the new restrictions.
- Cut standing Owner rights to two named administrators using just-in-time elevation, and rebuilt the on-call roster with a quarterly check against the staff directory.
Results
The review traced the event to a contractor's workstation and to a contractor account that was never disabled after the engagement ended. The manifest check confirmed that no guest records left the environment beyond the expected files, and the access logs matched that list file by file. The export ran on schedule the following night under the new restrictions. The privacy office assessed notification duties, and the team recorded that decision and its basis. Over the next quarter the export was split so each partner receives only its own files, and every read now writes to a central workspace.
Questions for discussion
- What would have changed in your scoping if the storage read spike had appeared two hours later, after the batch had already run?
- Which standing privileges in your environment would be hardest to justify to an auditor, and what is keeping them in place?
- How would you decide whether a containment step that interrupts a business process should wait for more evidence?
Case Study 4
Choosing a scaling path for a booking platform
Ferncliff Scheduling Systems, a company whose booking and reminder platform serves 310 outpatient clinics
The situation
Ferncliff's patient booking platform sits behind a single web API backed by an Azure SQL Database elastic pool in one region. Traffic peaks between seven and nine in the morning, when clinics open their schedules for the day, and the pool was sized two steps up to cover that window. The result is a pool that sits near 20 percent utilization for most of the rest of the day. Over the last several quarters the availability search endpoint has slowed each month as clinic count grew, and two large customers have asked in writing what happens if the primary region degrades.
The challenge
The engineering lead, Owen, had three options and a fixed monthly infrastructure increase that would not stretch. Each option traded latency, cost, failure behavior, and staffing differently. Patient records must stay in the contracted geography, and the team of seven had only two engineers who had run multi-region databases in production. The decision had to hold through the next planning cycle without a full rewrite.
Analysis
Begin with the workload. Availability search carries most of the reads, has a p95 target of 400 milliseconds, and tolerates availability that is up to two minutes stale, which opens a read-side design. Load tests replayed the morning peak at 2.5 times current volume and showed that CPU was not the constraint. Lock waits on the schedule table were. Scaling up would reduce those waits but leave idle capacity. A read replica with a cache for open slots cut p95 in the prototype to 180 milliseconds, though it added replication lag. A second region improves failover, but roughly doubles database cost for capacity that sits idle nearly all day.
Each option carries a different access and operations profile. A read replica adds a second credential surface, so the team would scope replica access to read-only database roles, keep connection secrets in Azure Key Vault behind managed identities, and retire the shared login the reporting team used. Cache entries must never hold patient identifiers, which becomes a standing review item. A second region doubles the configurations that must stay aligned, and the team cannot keep two sets of infrastructure definitions current by hand. The recommendation was the replica path, since the replica work would be needed for failover anyway and could be deployed from the same templates.
- Week oneLoad tests and query plans isolate the availability search as the bottleneck.
- Weeks two to fourRead replica and cache prototype tested against the morning peak profile.
- Month twoAccess model reviewed so replica credentials stay read only.
- Month fourStaged rollout to 40 clinics, with latency and cost compared weekly.
- End of quarterDecision recorded with a fallback plan if replica lag exceeds target.
Actions taken
- Ran load tests at 2.5 times current morning volume to locate the waits before committing to any option, and saved the query plans for the schedule table.
- Built the read replica and availability cache in staging with lag alerts at 90 seconds, then compared p95 latency and cost with the scaled-up pool over two weeks.
- Scoped replica credentials to read-only database roles, moved connection secrets into Azure Key Vault, and blocked the cache from storing any field that identifies a patient.
- Reduced the elastic pool by one size during off-peak hours on an automated schedule, and kept the scale-up option documented as the fallback if replica lag exceeded target.
Results
Morning p95 latency on availability search fell from 1,150 milliseconds to 210 milliseconds at peak, and the pool's monthly cost dropped by about a fifth once the off-peak schedule ran. During the staged rollout to 40 clinics, replica lag crossed the 90-second alert twice, both times during a bulk import, so the team added a throttle to that job. The quarter closed with a documented plan to add a second region after the replica pattern had run through a full cycle, with failover proven in a drill rather than assumed.
Questions for discussion
- Which of the three options would you choose if failover became a hard contractual term next quarter, and what would your plan change?
- How would you measure whether a read replica saves money, rather than moving cost from compute into operational attention?
- What belongs in a cache for availability data, and which fields should stay in the primary store only?
Case Study 5
Pilot review of a claims triage assistant
Greyhollow Claims Services, a claims administrator handling auto and property claims for eleven regional carriers
The situation
Greyhollow Claims Services handles auto and property claims for eleven regional carriers from two offices. A vendor proposed a triage assistant built on a hosted language model in Azure OpenAI Service. It would read incoming claim emails, assign a priority from one to five, and draft a first response for an adjuster to approve. The sales case rested on a projected 60 percent cut in triage time, which the vendor had demonstrated on a sample it chose. The pilot ran for six weeks across two regional queues covering about 4,200 claims, with output visible to adjusters but never sent automatically.
The challenge
Triage speed looked good, but the pilot log showed two problems the headline figure hid. Drafted responses quoted deductible amounts incorrectly on policies with endorsements. Priority scores also ran lower for claims written in short or non-native phrasing, which could delay care for some policyholders. The company had no labeled set of past claims with confirmed priorities, so nobody could yet say how large either problem was.
Analysis
The team wrote requirements in measurable form. A priority error on a bodily injury claim carries more risk than one on a windshield claim, so accuracy was split by category and severity. They drew a stratified sample of 1,200 past claims and had two senior adjusters label priorities blind to the model. Measures covered agreement, injury claims ranked low, and monetary drafting errors. Fairness was the gap in low-priority rates across correspondence language groups, with its limit set in advance. The vendor's headline accuracy did not survive the stratified sample, and injury-claim misses decided the outcome. Thresholds set after seeing the data tend to flatter the model.
The assistant could read claim files across every queue because the integration used a broad service identity, which broke the rule that adjusters see only their own assigned claims. The fix limited the identity to the queue each deployment served. Prompt and draft logs went into a restricted store with the same retention as the claim file. The vendor controlled prompt templates and model versions, so the team asked for version pinning, a 30-day change notice, and a regression set of 300 labeled examples to run before any update. Human oversight stayed firm: no draft left without adjuster approval, and any injury-tagged claim the model ranked below the top two levels went to a senior reviewer.
Actions taken
- Rebuilt the evaluation on a stratified sample of 1,200 past claims with blind adjuster labels, reporting results by category, severity, and correspondence language.
- Set a rollout gate requiring an injury-claim false low-priority rate under 3 percent and a language gap under 2 percentage points before any queue expanded beyond the pilot.
- Narrowed the integration identity to the queue each deployment served, kept prompt and draft logs in a restricted store, and required version pinning with a 30-day notice before any model change.
- Kept adjuster approval mandatory for every outgoing draft, routed low-ranked injury claims to a senior reviewer, and scheduled a monthly audit of 50 sampled decisions.
Results
Injury-claim false low-priority rate on the stratified sample came in at 5.1 percent, above the 3 percent gate, so the team did not expand. After the vendor revised the priority prompt and the company added a rule that injury keywords override model scores, the rate fell to 2.4 percent on a fresh sample. Drafting errors in monetary amounts dropped to zero in the audited set, because the policy system now supplies them. The assistant runs in one queue under named review, and the monthly audit has caught two regressions after approved updates, both before they reached outgoing mail.
Questions for discussion
- What injury-claim error rate would you accept in a triage pilot, and who in your organization should own that decision?
Learning Resources
Technical CASE STUDIES
China, India, United States, Indonesia, Pakistan, Nigeria, Brazil, Bangladesh, Russia, Japan, Mexico, Philippines, Vietnam, Egypt, Turkey, Germany, United Kingdom, France, Italy, Canada, South Korea, Australia, Spain.