perf: optimize Container Apps deployment by reducing ARM round-trips#6888
perf: optimize Container Apps deployment by reducing ARM round-trips#6888spboyer wants to merge 4 commits intoAzure:mainfrom
Conversation
- Cache ARM SDK clients (ContainerAppsClient, RevisionsClient) by subscription ID using sync.Map, eliminating repeated client creation and TCP+TLS handshake overhead - Remove redundant revision GET call from AddRevision; use the container app's own template directly instead of fetching the revision separately - Combine template and traffic weight updates for multi-revision mode into a single PATCH call, eliminating one full update+poll cycle Before: 5-6 ARM clients created, 4-6+ network round-trips per deploy After: 1-2 cached clients, 3 network round-trips per deploy Addresses finding 6 from Azure#6886 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add tests that verify the optimized ARM call pattern and document before/after statistics: Single-rev no secrets: 4 -> 3 calls (saved 1: revision GET) Single-rev with secrets: 5 -> 4 calls (saved 1: revision GET) Multi-rev with secrets: 7 -> 4 calls (saved 3: revision GET + traffic PATCH + LRO poll) Also adds Benchmark_AddRevision for ongoing performance tracking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Live Deployment Benchmark ResultsTested against todo-nodejs-mongo-aca template (2 Container App services, single-revision mode, eastus2). Results
*Run 1 difference is inflated by container image layer caching -- the first deploy pushes all layers, subsequent deploys skip unchanged layers. Warm deploy comparison (Run 2 -- apples to apples)
This matches our expectation: ~0.5-1s saved per service from eliminating the revision GET + ARM client caching. With 2 services deployed serially, that's ~1-2s total.
Environment
|
There was a problem hiding this comment.
Pull request overview
This PR optimizes Container Apps deployment by reducing ARM API round-trips and implementing client caching. The changes eliminate redundant API calls (specifically the revision GET) and combine template + traffic updates into a single PATCH operation for multi-revision mode. The implementation correctly uses sync.Map for thread-safe client caching, which is appropriate since ContainerAppService is registered as a singleton in the IoC container.
Changes:
- Implements ARM SDK client caching using
sync.Mapto eliminate repeated client creation overhead - Refactors
AddRevisionto use the container app's own template directly, eliminating the redundant revision GET API call - Combines template and traffic weight updates into a single PATCH request for multi-revision container apps
- Adds comprehensive tests including ARM call counting tests and multi-revision combined PATCH validation
- Removes obsolete revision GET mock from service target tests
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cli/azd/pkg/containerapps/container_app.go | Adds sync.Map client caches, refactors AddRevision to eliminate revision GET and combine multi-revision updates |
| cli/azd/pkg/containerapps/container_app_test.go | Updates tests to remove revision mocks, adds multi-revision test and env var merging test |
| cli/azd/pkg/containerapps/container_app_benchmark_test.go | New file: adds ARM call counting tests and benchmark validating the optimization claims |
| cli/azd/pkg/project/service_target_containerapp_test.go | Removes obsolete revision GET mock that is no longer needed |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
GetString doesn't return an error, so wrapping the previous err variable was incorrect (could be nil or stale). Use a descriptive error message instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove unused revisionsClientCache field (revision GET eliminated) - Remove unused setTrafficWeights method (traffic now set inline) - Remove unused createRevisionsClient method (no longer called) - Fix line length >125 chars in test - Fix gofmt formatting issues (unicode chars in comments) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
Description
Optimizes the Container Apps
AddRevisiondeployment path to reduce unnecessary ARM API round-trips and eliminate repeated ARM SDK client creation.Closes: #6887
Parent: #6886 (Performance Review Audit -- Finding 6)
Before / After ARM Call Statistics
Measured via
Test_AddRevision_ARMCallCount(counted mock ARM calls):Call pattern comparison
Before (main branch):
After (this PR):
Benchmark results
Expected real-world impact
Changes
1. Cache ARM SDK clients (
sync.Mapby subscription ID)createContainerAppsClientandcreateRevisionsClientnow cache clients when no custom policy is neededapiVersionPolicyare always created fresh (the policy has per-request mutable state)2. Eliminate redundant revision GET
AddRevisionnow uses the container app's ownproperties.templatedirectlyGetRevisionAPI call was fetching the same template data already available in the container app response3. Combine template + traffic update for multi-revision mode
Test_AddRevision_MultiRevision_CombinedPatch-- the PATCH body contains both updated template AND traffic weightsTesting
All 9 tests pass:
Files changed
pkg/containerapps/container_app.go-- client caching, refactored AddRevisionpkg/containerapps/container_app_test.go-- updated existing tests + 2 new testspkg/containerapps/container_app_benchmark_test.go-- NEW: ARM call counting + benchmarkpkg/project/service_target_containerapp_test.go-- removed obsolete revision mock