Argo CD 3.6 in a Lab: The Release Post's 32 Claims, Checked
Overview
We ran Argo CD 3.5.7 and 3.6.1 side by side, tested all 32 claims in the 3.6 announcement and screenshot every new feature. Most hold; the SSA diff change is missing.
We tested all 32 claims in the Argo CD 3.6 announcement [1] on two kind clusters, one running 3.5.7 and one running 3.6.1. Twenty-six behaved as described, eight of them with a gap. Filtering in the UI got a third cheaper, as promised; search did not. Compression halved the controller’s cache in our lab, once switched on.
Seven details in the post do not match the software: three links (two to the wrong pull request, one broken), the sampling variable’s name, the count of new health checks (55, not about 20), a filter panel on the Projects page that does not exist, and the rollout condition names. Three and a half of its seven “notable bug fixes” already shipped in 3.5 patch releases.
The change most likely to surprise someone upgrading is not in the post. Applications with ServerSideApply=true now compute their diff with a dry-run apply against the API server. In our lab every manual refresh cost one dry-run request per managed resource, and an admission policy that used to fail the sync now failed the diff. After that failure, the next periodic reconcile reported the application Synced while the cluster still differed from Git, in 5 of 5 trials. [3] [4]
Checked 7 November 2026.
How we checked
Argo CD 3.6.0 was released on 3 November 2026 and 3.6.1, with two UI fixes, the next day. [2] The announcement’s URL still says “rc1”, but its page metadata shows it was first published on 16 September and last modified on 4 November, and the text now describes the final release. [1]
The lab ran kind v0.33.0 with Kubernetes v1.37.0 on an arm64 Mac. Both Argo CD versions were installed from their release install.yaml, with a Gitea container as the Git server and registry:2 for OCI artifacts. UI checks used Playwright with Chrome for Testing 156. Every application, namespace, ApplicationSet, OCI artifact and finalizer in the screenshots carries the maborak prefix: they are objects we created and clicked through ourselves, not images from the announcement. Where a claim is a count or a backport, we checked the Git tags. Every number below is computed by script from raw output, and the raw output and per-trial data sit in collapsed blocks beside each result. An AI coding agent built the lab, chose the follow-up runs and drafted this post; no model judged any result, and a separate agent reviewed the methods before publication. Each result says whether its analysis was planned before the data or chosen afterwards, and Limits lists them. If you are still below 3.5.6, read our October security post first.
The change the post leaves out: SSA now means Server-Side Diff
Before 3.6, an application with the ServerSideApply=true sync option compared Git with the cluster using Structured-Merge Diff, a local approximation. PR #29103, merged on 9 September 2026, removes that strategy: SSA now implies Server-Side Diff, which asks the API server to dry-run the apply. [4] The upgrade guide files this under “Behavioral Improvements” and says “No action is required”. [3]
We tested what “no action” means with a ValidatingAdmissionPolicy that rejects ConfigMaps carrying a lab-reject label (maborak-reject in the screenshots, which were taken later with renamed objects). A live ConfigMap existed without the label, and Git added it. Each arm got five hard refreshes and one sync attempt, with impersonation off.
| Version | Application status | Where the policy error appears |
|---|---|---|
| 3.5.7 | OutOfSync (5 of 5 refreshes) | only when you sync |
| 3.6.1 | Unknown, ComparisonError |
on every refresh (5 of 5): forbidden: ValidatingAdmissionPolicy 'lab-reject-label' ... denied request, and again at sync |
3.6.1 with ServerSideDiff=false |
OutOfSync (5 of 5 refreshes) | only when you sync |

3.5.7: the policy-blocked change is plain OutOfSync. Captured on our 3.5.7 instance on 7 November 2026, 23:59 UTC.

3.6.1, same Git commit and cluster state: Unknown with one error. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.

The error behind it: the admission policy rejected Argo CD’s dry run. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
Seeing the rejection before a sync is useful. A dashboard full of Unknown the morning after an upgrade is less so, if your clusters run policy engines that reject manifests teams have been syncing around.
The error does not stay
We then watched the same application without touching it. After each hard refresh it showed the error; after the next periodic reconcile, about three minutes later, it showed Synced with no condition, although the live ConfigMap still had data: {k: live} and no label while Git has k: from-git and the label.
| Application | After hard refresh | After the next periodic reconcile |
|---|---|---|
| 3.6.1, policy blocks the change | Unknown, ComparisonError (5 of 5) |
Synced, no condition (5 of 5) |
| 3.6.1, same drift, no policy | OutOfSync (5 of 5) | OutOfSync (5 of 5) |
| 3.5.7, policy blocks the change | OutOfSync (5 of 5) | OutOfSync (5 of 5) |
3.5.7 with ServerSideDiff=true, policy blocks the change |
Unknown, ComparisonError (3 of 3) |
Synced (3 of 3) |

The false Synced, a few minutes after the error. At this moment kubectl get configmap maborak-guarded returned data: {"k":"live"} and no labels. Captured on our 3.6.1 instance on 8 November 2026, 00:03 UTC.
A drifted application with no policy stays OutOfSync, so the false Synced appears only after the server-side dry run has failed. 3.5.7 shows the same flip once Server-Side Diff is switched on, so this is not new code; what 3.6 changes is that every ServerSideApply=true application now takes this path by default. Five of five against zero of five gives Fisher’s exact p=0.008; with five trials per arm, the Wilson 95% interval for the flip rate is 57–100%. This was found while preparing screenshots, after the review, so treat it as an exploratory result. We did not find a matching upstream issue; the closest, #29348, reports the error itself, not the flip. If you run admission policies, do not trust a Synced badge on an SSA application until a hard refresh agrees.
Per-trial data: status after a hard refresh and after the next periodic reconcile (23 trials)
| version | app | trial | after_hard | after_periodic | periodic_at |
|---|---|---|---|---|---|
| 357 | maborak-drift | 1 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:43:03Z |
| 357 | maborak-drift | 2 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:47:13Z |
| 357 | maborak-drift | 3 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:51:14Z |
| 357 | maborak-drift | 4 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:55:08Z |
| 357 | maborak-drift | 5 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:57:20Z |
| 357 | maborak-policy-check | 1 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:42:54Z |
| 357 | maborak-policy-check | 2 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:45:18Z |
| 357 | maborak-policy-check | 3 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:48:44Z |
| 357 | maborak-policy-check | 4 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:51:02Z |
| 357 | maborak-policy-check | 5 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:54:33Z |
| 357 | maborak-policy-ssd | 1 | Unknown/ComparisonError | Synced/none | 2026-11-08T00:02:46Z |
| 357 | maborak-policy-ssd | 2 | Unknown/ComparisonError | Synced/none | 2026-11-08T00:04:51Z |
| 357 | maborak-policy-ssd | 3 | Unknown/ComparisonError | Synced/none | 2026-11-08T00:07:13Z |
| 361 | maborak-drift | 1 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:43:07Z |
| 361 | maborak-drift | 2 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:47:13Z |
| 361 | maborak-drift | 3 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:49:17Z |
| 361 | maborak-drift | 4 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:53:08Z |
| 361 | maborak-drift | 5 | OutOfSync/none | OutOfSync/none | 2026-11-07T23:56:59Z |
| 361 | maborak-policy-check | 1 | Unknown/ComparisonError | Synced/none | 2026-11-07T23:42:52Z |
| 361 | maborak-policy-check | 2 | Unknown/ComparisonError | Synced/none | 2026-11-07T23:45:03Z |
| 361 | maborak-policy-check | 3 | Unknown/ComparisonError | Synced/none | 2026-11-07T23:48:27Z |
| 361 | maborak-policy-check | 4 | Unknown/ComparisonError | Synced/none | 2026-11-07T23:51:12Z |
| 361 | maborak-policy-check | 5 | Unknown/ComparisonError | Synced/none | 2026-11-07T23:53:17Z |
We counted the API server’s apiserver_request_total{dry_run="All"} around single refreshes, with no other SSA application on the cluster. A 10-resource SSA application on 3.6.1 added exactly 10 dry-run requests per refresh, for 5 of 5 normal refreshes and 5 of 5 hard refreshes; a 3-resource application added 3. On 3.5.7 the same application added none. A periodic reconcile on 3.6.1 (its reconciledAt advanced during a 240-second idle window) added none either, because the diff result is cached until something changes. So the cost is one dry-run per managed resource for every refresh someone or something requests: a webhook, the UI button, argocd app get --refresh, or a new commit.
Raw output: dry-run requests per refresh, 10-resource and 3-resource applications
## SSD10 per-refresh dry-run deltas, 2026-11-07T21:43:25Z
### 357 SSA/SSD apps: ssa10 sync=Synced
357 normal refresh deltas: 0 0 0 0 0
357 hard refresh deltas: 0 0 0 0 0
357 idle 240 s: delta=0 reconciledAt before=2026-11-07T21:44:23Z after=2026-11-07T21:47:43Z
### 361 SSA/SSD apps: ssa10 sync=Synced
361 normal refresh deltas: 10 10 10 10 10
361 hard refresh deltas: 10 10 10 10 10
361 idle 240 s: delta=0 reconciledAt before=2026-11-07T21:49:26Z after=2026-11-07T21:51:43Z
## SSD apiserver dry-run requests per hard refresh of app ssa-plain (3 resources, ServerSideApply=true), 2026-11-07T20:20:11Z
dry_run=All verbs on 361: 4 APPLY; 4 POST;
357: dry-run requests before=2 after=2 delta=0 over 10 hard refreshes
361: dry-run requests before=13 after=43 delta=30 over 10 hard refreshes
361: normal (non-hard) refreshes x10: dry-run delta=30
361: idle 200 s (periodic reconcile only): dry-run delta=0
Raw output: admission policy runs, five hard refreshes per arm and sync attempts
## SSD default with ServerSideApply=true (not in the post), 2026-11-07T20:17:37Z
setup: VAP denies ConfigMaps labelled lab-reject in vap-ns; live ConfigMap vap-ns/guarded exists without the label; Git adds the label
### 357 ssa-vap
{"sync":"OutOfSync","conditions":[]}
### 357 ssa-vap-optout
{"sync":"OutOfSync","conditions":[]}
### 361 ssa-vap
{"sync":"Unknown","conditions":[{"type":"ComparisonError","message":"Failed to compare desired state to live state: StateDiffs error: diffConfig can not be nil"},{"type":"UnknownError","message":"no matching service account found for destination server https://kubernetes.default.svc and namespace vap-ns"}]}
### 361 ssa-vap-optout
{"sync":"OutOfSync","conditions":[]}
### impersonation disabled, 2026-11-07T20:18:58Z
### 357 ssa-vap
{"sync":"OutOfSync","conditions":[]}
### 357 ssa-vap-optout
{"sync":"OutOfSync","conditions":[]}
### 361 ssa-vap
{"sync":"Unknown","conditions":[{"type":"ComparisonError","message":"Failed to compare desired state to live state: failed to calculate diff: error calculating server side diff: serverSideDiff error: error running server side apply in dryrun mode for resource ConfigMap/guarded: configmaps \"guarded\" is forbidden: ValidatingAdmissionPolicy 'lab-reject-label' with bindi"}]}
### 361 ssa-vap-optout
{"sync":"OutOfSync","conditions":[]}
### sync attempt 3.5.7 ssa-vap
TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
2026-11-07T20:18:58+00:00 ConfigMap vap-ns guarded OutOfSync Healthy configmaps "guarded" is forbidden: ValidatingAdmissionPolicy 'lab-reject-label' with binding 'lab-reject-label' denied request: lab policy: ConfigMaps may not carry the lab-reject label
Message: one or more objects failed to apply, reason: configmaps "guarded" is forbidden: ValidatingAdmissionPolicy 'lab-reject-label' with binding 'lab-reject-label' denied request: lab policy: ConfigMaps may not carry the lab-reject label
## VAP5, impersonation off, 2026-11-07T21:54:04Z
357 ssa-vap statuses: OutOfSync/none OutOfSync/none OutOfSync/none OutOfSync/none OutOfSync/none
357 ssa-vap sync attempt: denied request: lab policy: ConfigMaps may not carry the lab-reject label
361 ssa-vap statuses: Unknown/ComparisonError Unknown/ComparisonError Unknown/ComparisonError Unknown/ComparisonError Unknown/ComparisonError
361 ssa-vap sync attempt: denied request: lab policy: ConfigMaps may not carry the lab-reject label
361 ssa-vap-optout statuses: OutOfSync/none OutOfSync/none OutOfSync/none OutOfSync/none OutOfSync/none
361 ssa-vap-optout sync attempt: denied request: lab policy: ConfigMaps may not carry the lab-reject label
The opt-out works per application:
metadata:
annotations:
argocd.argoproj.io/compare-options: ServerSideDiff=false
Impersonation interacts with this. The post lists PR #28821, “server-side diff respects impersonation”, as a notable fix, and we reproduced it: with a project mapped to a service account that has no RBAC, 3.5.7 reported OutOfSync with no error, while 3.6.1 reported configmaps "tiny" is forbidden: User "system:serviceaccount:imp-ns:limited" cannot patch resource "configmaps". [6] Since that account cannot patch anything, a successful dry run on 3.5.7 must have used other credentials, the controller’s own (an inference; we did not capture an audit log). With impersonation enabled and no service account mapped for a destination, an SSA application on 3.6.1 showed StateDiffs error: diffConfig can not be nil; on 3.5.7 it showed OutOfSync. If you enable impersonation, map every destination before upgrading.
Raw output: Server-Side Diff with impersonation (#28821), 3.5.7 and 3.6.1
## C32 #28821 Server-Side Diff and impersonation, 2026-11-07T20:16:28Z
setup: impersonation enabled; project imp maps imp-ns to SA imp-ns:limited (no RBAC); app imp-ssd uses ServerSideDiff=true + ServerSideApply=true
### 357
{"sync":"OutOfSync","conditions":[]}
### 361
{"sync":"OutOfSync","conditions":[]}
### can SA limited create configmaps in imp-ns?
no
### after creating live ConfigMap imp-ns/tiny (data k=live-value) so the diff needs a dry-run, 2026-11-07T20:16:52Z
### 357
{"sync":"OutOfSync","conditions":[]}
### 361
{"sync":"Unknown","conditions":[{"type":"ComparisonError","message":"Failed to compare desired state to live state: failed to calculate diff: error calculating server side diff: serverSideDiff error: error running server side apply in dryrun mode for resource ConfigMap/tiny: configmaps \"tiny\" is forbidden: User \"system:serviceaccount:imp-ns:limited\" cannot patch resource \"configmaps\" in API group \"\" in the namespace \"imp-ns\""}]}
What is new in 3.6, screen by screen
All screenshots in this section come from our 3.6.1 instance, captured with Playwright at three times device scale on 7 and 8 November 2026. Where 3.5.7 lacks the feature we say what it shows instead.
Resources page
A new top-level Resources page lists every managed resource across all applications, with health, sync status, cluster and owning application, and the same filters as the application list. Searching maborak below returns our demo objects across eight applications; a Deployment does not drag its ReplicaSets and Pods along, as the post says. Search, filters, the summary view and the open resource panel are all written to the URL, so a filtered view can be shared as a link. A sidebar filter survived navigating away and back; the search text did not. With RBAC limited to one project, our test user saw only that project’s resources. 3.5.7 has no such page; the route renders blank. It can be switched off with ui.view.resources.disabled: "true".
Raw output: Resources page with an RBAC-limited user
C1 RBAC user=admin rows for search imp-: ["ConfigMap imp-ns tiny"] apps visible via API: 1019
C1 RBAC user=dev rows for search imp-: [] apps visible via API: 1018

Resources page filtered to our maborak objects. Captured on our 3.6.1 instance on 7 November 2026, 23:58 UTC.
Settings: search, filters and the Advanced page
Repositories, Clusters, Projects, Accounts, GPG Keys and Certificates gained a search box whose text goes into the URL. All of them except Projects also gained a filter sidebar with counts, although the post includes Projects. A new Settings → Advanced page shows the instance configuration as a form and, on the JSON tab, as raw JSON, including our Maborak Lab IdP connector.

The new Advanced page, JSON tab. Captured on our 3.6.1 instance on 7 November 2026, 23:58 UTC.
Regex search
The .* button next to the search box turns the query into a regular expression, in the Applications and ApplicationSets lists and on the Resources page. ^maborak-(web|api)$ matches nothing as plain text and exactly two applications as a regex.

Regex search on. Captured on our 3.6.1 instance on 7 November 2026, 23:58 UTC.
Faster lists: virtual scrolling and lazy loading
These two do not show in a screenshot, so we counted. With “Items per page: all” and 1,011 applications, 3.5.7 rendered 1,011 tiles and 60,349 DOM nodes; 3.6.1 rendered 33 tiles and 3,469 nodes. Virtualization starts above 50 matching applications (VIRTUAL_THRESHOLD = 50): a regex matching exactly 50 rendered 50 rows, one matching 51 rendered 30.
Raw output: rendered tiles, rows and DOM nodes with "all" selected
C8 357 tiles load1: {"tiles":1011,"rows":0,"domNodes":60349} ms_to_first_render_after_click=773
C8 357 tiles load2: {"tiles":1011,"rows":0,"domNodes":60349} ms_to_first_render_after_click=297
C8 357 tiles load3: {"tiles":1011,"rows":0,"domNodes":60349} ms_to_first_render_after_click=243
C8 357 list load1: {"tiles":0,"rows":1011,"domNodes":53219} ms_to_first_render_after_click=232
C8 357 list load2: {"tiles":0,"rows":1011,"domNodes":53219} ms_to_first_render_after_click=241
C8 357 list load3: {"tiles":0,"rows":1011,"domNodes":53219} ms_to_first_render_after_click=254
C8 361 tiles load1: {"tiles":33,"rows":0,"domNodes":3464} ms_to_first_render_after_click=67
C8 361 tiles load2: {"tiles":33,"rows":0,"domNodes":3469} ms_to_first_render_after_click=27
C8 361 tiles load3: {"tiles":33,"rows":0,"domNodes":3469} ms_to_first_render_after_click=48
C8 361 list load1: {"tiles":0,"rows":29,"domNodes":3096} ms_to_first_render_after_click=32
C8 361 list load2: {"tiles":0,"rows":29,"domNodes":3096} ms_to_first_render_after_click=28
C8 361 list load3: {"tiles":0,"rows":29,"domNodes":3096} ms_to_first_render_after_click=46
C8 threshold 50 apps (^load-00([0-4][0-9]|50)$): rendered rows=50
C8 threshold 51 apps (^load-00([0-4][0-9]|5[01])$): rendered rows=30
ERR page.click: Timeout 30000ms exceeded. | Call log: | [2m - waiting for locator('[qe-id="paginate-items-per-page-applications-list"]')[22m | [2m - locator resolved to <div class="argo-dropdown__anchor" qe-id="paginate-items-per-page-applications-list">…</div>[22m
Lazy loading shows up in the network panel, though not for every view the post lists. 3.5.7 downloads one 3,478,669-byte main.js before anything renders; it already loaded the Monaco editor separately when the log viewer opened. 3.6.1 downloads 2,600,195 bytes in 12 files, then fetches a 251,239-byte settings bundle the first time you open Settings and a pod-logs chunk for the log viewer. Opening an application’s tree view fetched nothing new, and we did not test the terminal or the diff view. Applications and ApplicationSets tiles, rows and sidebar items are now real <a href> links (3.5.7 used <div>), so middle-click and “open in new tab” work.
Raw output: JavaScript files fetched per navigation, 3.5.7 and 3.6.1
C7 357 initial load of /user-info: new_js_files=2 decoded_bytes=3478669 ["main.2cde79b47a6b020c2119.js:3478669","extensions.js:0"]
C7 357 -> Applications list: new_js_files=0 decoded_bytes=0 []
C7 357 -> app tree: new_js_files=0 decoded_bytes=0 []
C7 357 -> pod logs tab: new_js_files=3 decoded_bytes=3203599 ["4614.785b00342aa638828e0d.chunk.js:2998345","1817.35bc2595ef84f99b2501.chunk.js:3668","editor.worker.js:201586"]
C7 357 -> Settings: new_js_files=0 decoded_bytes=0 []
C7 357 -> ApplicationSets: new_js_files=0 decoded_bytes=0 []
C7 361 initial load of /user-info: new_js_files=12 decoded_bytes=2600195 ["main.c25be9770a9983c81271.js:206427","runtime.d265cbbcc504ea212795.js:7459","extensions.js:0","vendors.1a64bfbed4f625c48d2f.js:1431764","1864.0a62e980d3a4535627c6.chunk.js:11058","1391.8d4d757f0ee82837c27f.chunk.js:218165","4720.569c27eb7e1ae91fe4d2.chunk.js:59761","8532.875f96ccb46f7f4e065a.chunk.js:18958","login.a327baee153060901109.chunk.js:13050","9394.098318ad28f8f5cffa40.chunk.js:479797","applications.c0b51ee668346620f6a8.chunk.js:149075","user-info.4169aa64d197b445b669.chunk.js:4681"]
C7 361 -> Applications list: new_js_files=0 decoded_bytes=0 []
C7 361 -> app tree: new_js_files=0 decoded_bytes=0 []
C7 361 -> pod logs tab: new_js_files=5 decoded_bytes=3261661 ["5857.516678390fb517b0025c.chunk.js:2997667","1817.35bc2595ef84f99b2501.chunk.js:3668","editor.worker.js:201588","7689.78a782fc9d00f3625ea0.chunk.js:21343","pod-logs.3729c09629c850c29dc8.chunk.js:37395"]
C7 361 -> Settings: new_js_files=2 decoded_bytes=251239 ["7973.856aeb69764db7e07fe4.chunk.js:62301","settings.83e13d827d143f607420.chunk.js:188938"]
C7 361 -> ApplicationSets: new_js_files=0 decoded_bytes=0 []
Log viewer and events
The pod log viewer has a Clear displayed logs button (the eraser). It empties the view; new lines keep streaming in. Event lists gained a Component column with the reporting component, here default-scheduler and kubelet. 3.5.7 has neither.

Our maborak-web pod writes “verified by Maborak lab” on every line. Captured on our 3.6.1 instance on 7 November 2026, 23:58 UTC.

The new Component column. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
SSO button label
ui.loginButtonText in argocd-cm replaces the SSO button text. With the same setting, 3.5.7 kept its default “LOG IN VIA MABORAK LAB IDP”; 3.6.1 shows our text. The response also carries X-Robots-Tag: noindex, nofollow, so a public instance asks search engines not to index it.
Raw output: response headers, 3.5.7 and 3.6.1
## C10 X-Robots-Tag, 2026-11-07T19:05:52Z
### port 8357
HTTP/1.1 200 OK
HTTP/1.1 200 OK
### port 8361
HTTP/1.1 200 OK
X-Robots-Tag: noindex, nofollow
HTTP/1.1 200 OK

Our button text from ui.loginButtonText: "Sign in with Maborak SSO". Captured on our 3.6.1 instance on 8 November 2026, 00:00 UTC.
Health: deletion messages and the resource that caused it
A resource stuck on a finalizer used to read only “Pending deletion”. 3.6.1 lists the finalizers, and a Lua health check can return a deletionMessage that explains them. We deleted a Service and a ConfigMap that carry our maborak.com/hold finalizer: the Service reads “Pending deletion; blocked by finalizers: maborak.com/hold”, and the ConfigMap shows the message from our Lua check. 3.5.7 shows “Pending deletion” for both. The application header also names the resource behind its health (“Caused by Service:maborak-held/maborak-held-svc”), a 3.6 change (#28455) the post does not mention.
Raw output: health of resources pending deletion, 3.5.7 and 3.6.1
## C30 deletion health (Service with finalizer), 2026-11-07T19:07:45Z
### 357
{"kind":"Service","name":"held-svc","health":null}
### 361
{"kind":"Service","name":"held-svc","health":null}
### 357
### 361
### resource-tree health, 2026-11-07T19:08:12Z
### 357
{"kind":"ConfigMap","name":"held","health":{"status":"Progressing","message":"Pending deletion"}}
{"kind":"Service","name":"held-svc","health":{"status":"Progressing","message":"Pending deletion"}}
### 361
{"kind":"ConfigMap","name":"held","health":{"status":"Progressing","message":"Pending deletion; blocked by finalizers: lab.maborak.com/hold"}}
{"kind":"Service","name":"held-svc","health":{"status":"Progressing","message":"Pending deletion; blocked by finalizers: lab.maborak.com/hold"}}
### custom Lua deletionMessage, 2026-11-07T19:09:11Z
### 357
{"kind":"ConfigMap","name":"held","health":{"status":"Progressing","message":"Pending deletion"}}
{"kind":"Service","name":"held-svc","health":{"status":"Progressing","message":"Pending deletion"}}
### 361
{"kind":"ConfigMap","name":"held","health":{"status":"Degraded","message":"lab.maborak.com/hold: lab finalizer; removing it by hand skips the cleanup step."}}
{"kind":"Service","name":"held-svc","health":{"status":"Progressing","message":"Pending deletion; blocked by finalizers: lab.maborak.com/hold"}}

The health panel names the resource that caused it. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.

Our custom deletionMessage from a Lua health check. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
Source hydrator
The hydrator renders manifests from a “dry” branch and commits them to an environment branch. In the application header you see the hydration state with both commits, and the new hydrator_status label on argocd_app_info reports the same state to Prometheus (hydrator_status="Hydrated" for this application).
Raw output: argocd_app_info labels, 3.5.7 and 3.6.1
## C28 argocd_app_info hydrator_status, 2026-11-07T19:34:35Z
### 361 hydrated app
argocd_app_info{autosync_enabled="false",dest_namespace="hydrated",dest_server="https://kubernetes.default.svc",health_status="Missing",hydrator_status="Hydrated",name="hydrated",namespace="argocd",operation="",phase="",project="default",repo="http://argolab-gitea:3000/lab/apps",sync_status="OutOfSync"} 1
argocd_app_info{autosync_enabled="true",dest_namespace="plain",dest_server="https://kubernetes.default.svc",health_status="Healthy",hydrator_status="",name="plain",namespace="argocd",operation="",phase="Succeeded",project="default",repo="http://argolab-gitea:3000/lab/apps",sync_status="Synced"} 1
### 357 plain app (label set)
argocd_app_info{autosync_enabled="true",dest_namespace="plain",dest_server="https://kubernetes.default.svc",health_status="Healthy",name="plain",namespace="argocd",operation="",project="default",repo="http://argolab-gitea:3000/lab/apps",sync_status="Synced"} 1

A hydrated application, writing to environments/maborak-prod. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
“20–30% less rendering work”
The post credits the React Compiler with “roughly 20–30% less rendering work” when filtering and searching large installations. We measured page script time in Chrome while toggling a health filter on and off, and while typing a search and clearing it, on both versions with about 1,000 applications in list view, 20 per page. The filter matched 1,003 applications on 3.5.7 and 1,005 on 3.6.1.
The first, pre-registered run was noisy. Background reconciliation of the 1,000 applications kept each UI busy with its own cluster’s updates, at different moments on each version. Its unpaired comparison favoured 3.6.1 for filtering (median 75.2 ms against 50.1 ms, Mann-Whitney p=0.008), but the 95% intervals of both ratios included no change. We reran with periodic reconciliation off on both clusters, three fresh browser sessions per version, and an idle cycle subtracted from each session (idle cost about 0.3 ms):
| Action | 3.5.7, three sessions | 3.6.1, three sessions | Ratio of medians |
|---|---|---|---|
| Toggle a health filter on and off | 48.3, 49.0, 49.7 ms | 34.6, 28.9, 31.2 ms | 0.64 |
| Type a search and clear it | 47.4, 45.7, 48.4 ms | 45.6, 51.6, 49.3 ms | 1.04 |
Filtering got about a third cheaper, and every 3.6.1 session beat every 3.5.7 session. Search did not change in the quiet run. Three sessions per version give a direction rather than a precise size, and the comparison is “3.6.1 UI against 3.5.7 UI”: the React Compiler is not the only thing that changed between them.
Analysis output: rendering, pre-registered run and quiet rerun
filter ScriptDuration_ms n=20/20 median 3.5.7= 75.20 3.6.1= 50.12 ratio=0.666 CI95=[0.291,1.372] change=-33.4% MWU p=0.0077
filter TaskDuration_ms n=20/20 median 3.5.7= 111.18 3.6.1= 78.08 ratio=0.702 CI95=[0.408,1.250] change=-29.8% MWU p=0.0098
filter LayoutDuration_ms n=20/20 median 3.5.7= 2.96 3.6.1= 1.82 ratio=0.615 CI95=[0.432,0.919] change=-38.5% MWU p=0.00012
filter RecalcStyleDuration_ms n=20/20 median 3.5.7= 2.93 3.6.1= 1.40 ratio=0.479 CI95=[0.398,0.617] change=-52.1% MWU p=9.1e-08
search ScriptDuration_ms n=20/20 median 3.5.7= 49.45 3.6.1= 43.27 ratio=0.875 CI95=[0.461,1.154] change=-12.5% MWU p=0.036
search TaskDuration_ms n=20/20 median 3.5.7= 111.06 3.6.1= 90.95 ratio=0.819 CI95=[0.626,1.120] change=-18.1% MWU p=0.044
search LayoutDuration_ms n=20/20 median 3.5.7= 9.23 3.6.1= 8.84 ratio=0.957 CI95=[0.875,1.024] change=-4.3% MWU p=0.35
search RecalcStyleDuration_ms n=20/20 median 3.5.7= 8.43 3.6.1= 7.21 ratio=0.856 CI95=[0.829,0.928] change=-14.4% MWU p=7.5e-06
filter ScriptDuration_ms pairs=20 median paired ratio=0.637 CI95=[0.594,0.715] 3.6.1 lower in 18/20 pairs, Wilcoxon p=3.6e-05
filter TaskDuration_ms pairs=20 median paired ratio=0.717 CI95=[0.657,0.807] 3.6.1 lower in 17/20 pairs, Wilcoxon p=6.3e-05
search ScriptDuration_ms pairs=20 median paired ratio=0.854 CI95=[0.708,0.932] 3.6.1 lower in 15/20 pairs, Wilcoxon p=0.001
search TaskDuration_ms pairs=20 median paired ratio=0.787 CI95=[0.740,0.970] 3.6.1 lower in 15/20 pairs, Wilcoxon p=0.012
filter 357 idle-corrected session medians: [48.3, 49.0, 49.7] (idle medians: [0.3, 0.3, 0.3])
filter 361 idle-corrected session medians: [34.6, 28.9, 31.2] (idle medians: [0.3, 0.4, 0.3])
filter ratio of medians of session medians 3.6.1/3.5.7 = 0.636; every 3.6.1 session below every 3.5.7 session: True
search 357 idle-corrected session medians: [47.4, 45.7, 48.4] (idle medians: [0.3, 0.3, 0.3])
search 361 idle-corrected session medians: [45.6, 51.6, 49.3] (idle medians: [0.3, 0.4, 0.3])
search ratio of medians of session medians 3.6.1/3.5.7 = 1.040; every 3.6.1 session below every 3.5.7 session: False
Per-cycle data: quiet rerun, script and task time per cycle (216 cycles)
version,session,action,cycle,ScriptDuration_ms,TaskDuration_ms
357,1,filter,1,51.91,84.04
357,1,search,1,45.70,106.85
357,1,idle,1,0.27,8.02
357,1,filter,2,53.78,92.40
357,1,search,2,46.69,113.96
357,1,idle,2,0.21,7.75
357,1,filter,3,43.93,72.69
357,1,search,3,45.75,113.34
357,1,idle,3,0.39,10.44
357,1,filter,4,48.66,80.52
357,1,search,4,54.78,120.93
357,1,idle,4,0.23,7.60
357,1,filter,5,48.44,92.59
357,1,search,5,48.08,110.51
357,1,idle,5,0.43,9.01
357,1,filter,6,46.75,88.70
357,1,search,6,50.55,122.16
357,1,idle,6,0.27,10.70
357,1,filter,7,53.88,96.03
357,1,search,7,45.35,117.99
357,1,idle,7,0.37,8.85
357,1,filter,8,44.89,83.47
357,1,search,8,50.15,114.29
357,1,idle,8,0.31,9.88
357,1,filter,9,49.39,94.24
357,1,search,9,55.19,125.52
357,1,idle,9,0.29,7.97
357,1,filter,10,54.09,100.83
357,1,search,10,47.37,112.60
357,1,idle,10,0.26,6.87
357,1,filter,11,47.47,83.08
357,1,search,11,45.38,113.37
357,1,idle,11,0.27,7.73
357,1,filter,12,51.88,86.73
357,1,search,12,43.31,102.92
357,1,idle,12,0.24,8.66
361,1,filter,1,29.13,51.73
361,1,search,1,46.96,114.23
361,1,idle,1,0.44,2.06
361,1,filter,2,29.68,62.33
361,1,search,2,51.96,128.61
361,1,idle,2,0.38,2.26
361,1,filter,3,35.28,70.31
361,1,search,3,41.06,109.79
361,1,idle,3,0.33,1.81
361,1,filter,4,28.16,60.90
361,1,search,4,43.41,107.12
361,1,idle,4,0.35,1.98
361,1,filter,5,36.60,90.42
361,1,search,5,57.15,122.17
361,1,idle,5,0.34,2.03
361,1,filter,6,40.12,85.17
361,1,search,6,49.79,113.64
361,1,idle,6,0.32,3.74
361,1,filter,7,35.35,79.25
361,1,search,7,43.75,110.10
361,1,idle,7,0.30,2.99
361,1,filter,8,25.36,72.59
361,1,search,8,55.61,122.64
361,1,idle,8,0.40,2.09
361,1,filter,9,28.48,62.91
361,1,search,9,45.41,104.37
361,1,idle,9,0.37,2.16
361,1,filter,10,35.15,84.89
361,1,search,10,37.95,96.65
361,1,idle,10,0.35,1.96
361,1,filter,11,26.44,71.69
361,1,search,11,52.81,117.57
361,1,idle,11,0.38,1.94
361,1,filter,12,34.69,79.00
361,1,search,12,46.44,104.40
361,1,idle,12,0.37,2.33
361,2,filter,1,35.15,71.80
361,2,search,1,50.09,118.94
361,2,idle,1,0.38,2.13
361,2,filter,2,30.82,71.07
361,2,search,2,54.18,127.57
361,2,idle,2,0.38,2.03
361,2,filter,3,30.35,60.60
361,2,search,3,53.56,129.72
361,2,idle,3,0.39,1.92
361,2,filter,4,27.58,57.26
361,2,search,4,50.43,119.87
361,2,idle,4,0.34,1.74
361,2,filter,5,28.82,83.48
361,2,search,5,56.17,118.88
361,2,idle,5,0.40,2.13
361,2,filter,6,38.42,78.55
361,2,search,6,46.39,107.51
361,2,idle,6,0.48,5.54
361,2,filter,7,30.92,71.84
361,2,search,7,49.69,120.15
361,2,idle,7,0.44,2.33
361,2,filter,8,27.06,75.48
361,2,search,8,58.34,123.58
361,2,idle,8,0.34,1.93
361,2,filter,9,36.80,80.83
361,2,search,9,58.24,124.71
361,2,idle,9,0.34,2.27
361,2,filter,10,28.22,75.62
361,2,search,10,41.73,111.81
361,2,idle,10,0.33,1.97
361,2,filter,11,27.30,80.45
361,2,search,11,55.38,124.53
361,2,idle,11,0.42,2.54
361,2,filter,12,29.68,67.05
361,2,search,12,43.59,101.39
361,2,idle,12,0.34,2.20
357,2,filter,1,53.84,96.33
357,2,search,1,54.31,117.47
357,2,idle,1,0.28,9.02
357,2,filter,2,49.51,89.10
357,2,search,2,57.02,127.17
357,2,idle,2,0.33,7.96
357,2,filter,3,47.88,79.84
357,2,search,3,47.38,114.86
357,2,idle,3,0.23,8.18
357,2,filter,4,48.55,81.65
357,2,search,4,46.41,115.97
357,2,idle,4,0.44,10.03
357,2,filter,5,48.03,86.77
357,2,search,5,46.26,110.12
357,2,idle,5,0.22,8.29
357,2,filter,6,53.88,100.32
357,2,search,6,45.48,104.84
357,2,idle,6,0.28,11.19
357,2,filter,7,49.97,91.83
357,2,search,7,43.36,111.07
357,2,idle,7,0.28,8.13
357,2,filter,8,55.39,97.17
357,2,search,8,45.99,111.39
357,2,idle,8,0.22,8.23
357,2,filter,9,55.29,99.35
357,2,search,9,39.47,97.60
357,2,idle,9,0.28,7.65
357,2,filter,10,55.26,102.26
357,2,search,10,54.06,116.55
357,2,idle,10,0.28,7.48
357,2,filter,11,44.07,80.83
357,2,search,11,45.96,114.48
357,2,idle,11,0.23,7.20
357,2,filter,12,46.26,82.78
357,2,search,12,41.23,105.13
357,2,idle,12,0.27,7.99
357,3,filter,1,51.91,87.82
357,3,search,1,48.69,108.55
357,3,idle,1,0.26,8.25
357,3,filter,2,56.71,102.80
357,3,search,2,58.70,130.70
357,3,idle,2,0.29,8.93
357,3,filter,3,50.59,83.35
357,3,search,3,48.99,117.00
357,3,idle,3,0.29,8.98
357,3,filter,4,59.93,105.04
357,3,search,4,56.05,127.25
357,3,idle,4,0.26,7.21
357,3,filter,5,51.84,85.18
357,3,search,5,48.88,110.84
357,3,idle,5,0.27,9.21
357,3,filter,6,46.71,90.92
357,3,search,6,47.90,105.72
357,3,idle,6,0.22,9.44
357,3,filter,7,54.76,99.46
357,3,search,7,56.78,127.95
357,3,idle,7,0.40,8.91
357,3,filter,8,48.56,85.90
357,3,search,8,43.89,116.65
357,3,idle,8,0.22,6.91
357,3,filter,9,49.30,88.89
357,3,search,9,41.87,104.57
357,3,idle,9,0.26,7.75
357,3,filter,10,49.32,95.54
357,3,search,10,46.37,109.57
357,3,idle,10,0.22,5.95
357,3,filter,11,48.40,96.96
357,3,search,11,48.53,114.73
357,3,idle,11,0.26,9.10
357,3,filter,12,55.88,94.66
357,3,search,12,50.67,125.25
357,3,idle,12,0.30,10.38
361,3,filter,1,35.90,72.85
361,3,search,1,58.12,133.73
361,3,idle,1,0.37,1.93
361,3,filter,2,34.82,68.28
361,3,search,2,43.18,111.67
361,3,idle,2,0.38,2.09
361,3,filter,3,32.63,70.39
361,3,search,3,47.75,117.28
361,3,idle,3,0.55,2.25
361,3,filter,4,35.46,74.11
361,3,search,4,41.26,112.04
361,3,idle,4,0.38,1.79
361,3,filter,5,28.13,58.51
361,3,search,5,50.09,117.02
361,3,idle,5,0.35,2.12
361,3,filter,6,31.73,92.78
361,3,search,6,53.91,116.54
361,3,idle,6,0.33,4.81
361,3,filter,7,31.31,71.90
361,3,search,7,54.95,117.66
361,3,idle,7,0.35,1.85
361,3,filter,8,28.52,70.46
361,3,search,8,49.29,113.60
361,3,idle,8,0.31,1.77
361,3,filter,9,25.79,86.27
361,3,search,9,58.54,128.84
361,3,idle,9,0.28,1.81
361,3,filter,10,37.55,82.55
361,3,search,10,45.14,105.71
361,3,idle,10,0.57,2.67
361,3,filter,11,33.24,80.17
361,3,search,11,42.41,105.64
361,3,idle,11,0.33,2.23
361,3,filter,12,26.61,79.70
361,3,search,12,55.27,119.34
361,3,idle,12,0.48,2.27
Per-cycle data: first, pre-registered run (88 cycles)
version,action,cycle,ScriptDuration_ms,TaskDuration_ms,LayoutDuration_ms,RecalcStyleDuration_ms
357,filter,1,49.36,82.90,2.77,3.39
361,filter,1,33.25,69.11,2.07,2.50
361,filter,2,38.43,57.67,1.75,1.43
357,filter,2,47.35,72.68,2.12,2.13
357,filter,3,42.95,59.60,2.08,1.83
361,filter,3,42.37,63.04,1.80,1.37
361,filter,4,63.22,100.33,2.25,1.62
357,filter,4,98.21,139.69,3.59,3.16
357,filter,5,110.33,142.30,3.51,3.07
361,filter,5,84.47,131.87,2.69,1.84
361,filter,6,87.15,127.05,2.54,1.71
357,filter,6,104.14,144.60,3.35,3.46
357,filter,7,97.84,136.24,3.72,3.18
361,filter,7,71.12,101.03,2.20,1.58
361,filter,8,74.37,105.29,2.00,1.51
357,filter,8,121.16,158.34,3.91,3.70
357,filter,9,120.78,163.89,3.83,3.87
361,filter,9,84.84,126.56,2.65,1.91
361,filter,10,80.23,113.78,2.49,1.67
357,filter,10,129.85,172.00,3.74,3.42
357,filter,11,127.54,168.91,4.19,3.53
361,filter,11,85.79,122.09,2.36,1.66
361,filter,12,39.98,65.25,1.60,1.29
357,filter,12,129.54,174.41,3.88,3.46
357,filter,13,135.96,182.07,3.92,3.69
361,filter,13,29.28,51.25,1.39,1.23
361,filter,14,28.84,58.87,1.27,1.29
357,filter,14,47.38,82.36,2.21,2.53
357,filter,15,51.88,78.41,2.57,2.52
361,filter,15,29.17,48.26,1.65,1.29
361,filter,16,27.18,53.65,1.42,1.23
357,filter,16,41.15,63.74,1.99,2.15
357,filter,17,49.75,74.85,2.29,2.43
361,filter,17,28.79,48.83,1.32,1.28
361,filter,18,30.90,60.01,1.51,1.38
357,filter,18,49.08,86.12,2.12,2.24
357,filter,19,45.89,73.25,2.28,2.51
361,filter,19,26.14,40.58,1.11,1.12
361,filter,20,25.82,39.94,1.13,1.11
357,filter,20,52.56,79.66,2.25,2.80
357,filter,21,49.57,81.77,2.04,2.33
361,filter,21,57.87,90.91,1.84,1.54
361,filter,22,68.04,102.01,1.95,1.43
357,filter,22,50.45,80.60,2.26,2.32
357,search,1,46.11,110.31,14.59,13.25
361,search,1,90.20,167.51,15.80,13.71
361,search,2,63.27,106.03,8.49,7.19
357,search,2,97.86,152.45,9.69,8.40
357,search,3,109.51,167.31,9.46,8.80
361,search,3,77.00,130.91,8.91,7.37
361,search,4,63.20,106.22,8.18,7.24
357,search,4,101.68,158.03,9.40,8.52
357,search,5,88.68,141.13,9.13,8.52
361,search,5,91.01,140.09,8.45,7.10
361,search,6,69.00,111.83,8.07,7.06
357,search,6,96.73,150.28,9.35,8.52
357,search,7,123.88,178.10,9.16,8.69
361,search,7,60.94,106.79,7.88,7.01
361,search,8,73.44,115.97,8.26,7.18
357,search,8,87.66,140.37,9.24,8.42
357,search,9,88.03,139.92,9.13,8.44
361,search,9,40.70,82.32,7.40,6.66
361,search,10,32.74,67.63,7.20,6.62
357,search,10,87.29,140.73,9.23,8.64
357,search,11,87.18,139.02,9.12,8.40
361,search,11,36.54,88.27,9.22,7.88
361,search,12,43.31,87.91,11.01,8.38
357,search,12,41.96,92.73,7.80,8.04
357,search,13,41.29,85.86,7.80,8.21
361,search,13,49.50,114.24,10.67,7.96
361,search,14,48.13,93.42,9.37,7.92
357,search,14,51.04,114.72,9.94,9.16
357,search,15,42.83,84.95,10.11,8.78
361,search,15,43.23,105.22,10.74,8.17
361,search,16,42.59,84.94,10.30,7.71
357,search,16,47.85,107.39,9.55,9.65
357,search,17,42.71,79.59,9.46,7.42
361,search,17,43.55,118.81,10.84,8.31
361,search,18,36.40,72.24,7.48,6.86
357,search,18,42.84,98.27,9.29,8.04
357,search,19,41.00,81.08,8.35,7.60
361,search,19,37.77,88.49,9.45,7.19
361,search,20,36.57,72.70,7.63,6.93
357,search,20,42.91,94.23,9.12,8.21
357,search,21,41.38,77.80,9.66,7.41
361,search,21,37.25,87.19,9.32,7.52
361,search,22,36.68,71.60,8.76,6.94
357,search,22,42.89,95.40,9.20,8.32
Memory: compression halves the cache, if you turn it on
The post’s headline memory claim, 3.27 GB down to under 1 GB, comes from a benchmark in PR #28600, which the post mislinks as #29570. [5] The feature is off by default: nothing changes until you set resource.manifest.compression.enabled: "true" in argocd-cm.
We tested it on a third cluster running only 3.6.1, with one application managing 5,000 ConfigMaps of about 2.3 KB each, and restarted the controller five times with compression off and five times on. Our registered measurement, the controller’s working set and Go heap sampled over a minute, found no difference: median working set 858 MiB off and 936 MiB on (Mann-Whitney p=0.69). Those readings were dominated by memory from reconciling 5,000 resources that the garbage collector had not freed yet, not by the cache.
A follow-up, chosen after that result, turned off periodic reconciliation and forced a garbage collection before each reading (/debug/pprof/heap?gc=1). It measures the memory the controller keeps, which is where the cache lives:
| Compression | Live heap after garbage collection, five controller starts each |
|---|---|
| off | 90.6–90.7 MiB |
| on | 45.1–45.3 MiB |
Compression halved the controller’s live heap at this load (ratio 0.50, Mann-Whitney p=0.008, the smallest p possible with five starts per arm). That is 45 MiB for 5,000 resources, about 9.5 KB per resource. It is not the same quantity as the post’s 70% of total controller memory, and we did not measure the CPU cost. On a controller whose memory is dominated by reconciliation, as in our first run, the saving may not show in the container’s memory graph.
Analysis output: memory, registered run and live-heap follow-up
off start 1: working_set=1185 MiB heap_inuse=912 MiB cpu_s_over_window=0.10 samples=7
off start 2: working_set=1079 MiB heap_inuse=735 MiB cpu_s_over_window=4.27 samples=7
off start 3: working_set=858 MiB heap_inuse=223 MiB cpu_s_over_window=0.11 samples=7
off start 4: working_set=828 MiB heap_inuse=228 MiB cpu_s_over_window=0.09 samples=7
off start 5: working_set=690 MiB heap_inuse=229 MiB cpu_s_over_window=4.42 samples=7
on start 1: working_set=935 MiB heap_inuse=174 MiB cpu_s_over_window=0.17 samples=7
on start 2: working_set=622 MiB heap_inuse=173 MiB cpu_s_over_window=0.09 samples=7
on start 3: working_set=1164 MiB heap_inuse=762 MiB cpu_s_over_window=0.09 samples=7
on start 4: working_set=525 MiB heap_inuse=171 MiB cpu_s_over_window=0.08 samples=7
on start 5: working_set=1027 MiB heap_inuse=872 MiB cpu_s_over_window=4.54 samples=7
excluded: none
working_set: n=5/5 median off=858.4 on=935.5 ratio=1.090 CI95=[0.525,1.406] change=+9.0% MWU p=0.69
heap_inuse: n=5/5 median off=228.9 on=174.2 ratio=0.761 CI95=[0.191,3.809] change=-23.9% MWU p=0.42
cpu_seconds: n=5/5 median off=0.1 on=0.1 ratio=0.818 CI95=[0.020,41.273] change=-18.2% MWU p=0.6
working_set: n=4/5 median off=843.2 on=935.5 ratio=1.109 CI95=[0.576,1.406] change=+10.9% MWU p=1
heap_inuse: n=4/5 median off=228.6 on=174.2 ratio=0.762 CI95=[0.237,3.814] change=-23.8% MWU p=0.73
cpu_seconds: n=4/5 median off=2.2 on=0.1 ratio=0.041 CI95=[0.020,2.073] change=-95.9% MWU p=0.62
off start 1: live heap 90.6 MiB (samples 5, cache 5406)
off start 2: live heap 90.6 MiB (samples 5, cache 5406)
off start 3: live heap 90.7 MiB (samples 5, cache 5406)
off start 4: live heap 90.6 MiB (samples 5, cache 5406)
off start 5: live heap 90.6 MiB (samples 5, cache 5406)
on start 1: live heap 45.3 MiB (samples 5, cache 5406)
on start 2: live heap 45.2 MiB (samples 5, cache 5406)
on start 3: live heap 45.3 MiB (samples 5, cache 5406)
on start 4: live heap 45.3 MiB (samples 5, cache 5406)
on start 5: live heap 45.1 MiB (samples 5, cache 5406)
excluded: none
live heap after GC: off median 90.6 MiB (range 90.6-90.7), on median 45.3 MiB (range 45.1-45.3); ratio 0.500 CI95 [0.498,0.500]; diff 45.3 MiB; MWU p=0.00794
Per-sample data: live heap after forced garbage collection (50 samples)
arm,start,sample,utc,heap_alloc_after_gc_bytes,heap_inuse_after_gc_bytes,cache_objects,app_sync
off,1,1,2026-11-07T21:23:01Z,93926904,122748928,5406,Synced
off,1,2,2026-11-07T21:32:38Z,95014616,123551744,5406,Synced
off,1,3,2026-11-07T21:32:48Z,95008800,123494400,5406,Synced
off,1,4,2026-11-07T21:32:59Z,95016376,123543552,5406,Synced
off,1,5,2026-11-07T21:33:09Z,95056064,123535360,5406,Synced
on,1,1,2026-11-07T21:39:43Z,48687304,67149824,5406,Synced
on,1,2,2026-11-07T21:39:53Z,47504960,65888256,5406,Synced
on,1,3,2026-11-07T21:40:04Z,47506232,65871872,5406,Synced
on,1,4,2026-11-07T21:40:14Z,47502232,65830912,5406,Synced
on,1,5,2026-11-07T21:40:25Z,47541488,65822720,5406,Synced
off,2,1,2026-11-07T21:46:59Z,98497160,126861312,5406,Synced
off,2,2,2026-11-07T21:47:09Z,95004064,123215872,5406,Synced
off,2,3,2026-11-07T21:47:20Z,95008264,123207680,5406,Synced
off,2,4,2026-11-07T21:47:30Z,95045840,123232256,5406,Synced
off,2,5,2026-11-07T21:47:40Z,95038848,123125760,5406,Synced
on,2,1,2026-11-07T21:54:16Z,46345448,64667648,5406,Synced
on,2,2,2026-11-07T21:54:26Z,47415840,65650688,5406,Synced
on,2,3,2026-11-07T21:54:36Z,47415912,65634304,5406,Synced
on,2,4,2026-11-07T21:54:47Z,47415360,65626112,5406,Synced
on,2,5,2026-11-07T21:54:57Z,47455472,65617920,5406,Synced
off,3,1,2026-11-07T22:01:33Z,97436448,127451136,5406,Synced
off,3,2,2026-11-07T22:01:43Z,95036648,124682240,5406,Synced
off,3,3,2026-11-07T22:01:53Z,95034360,124674048,5406,Synced
off,3,4,2026-11-07T22:02:04Z,95077816,124682240,5406,Synced
off,3,5,2026-11-07T22:02:14Z,95111056,124690432,5406,Synced
on,3,1,2026-11-07T22:08:48Z,46401304,65175552,5406,Synced
on,3,2,2026-11-07T22:08:58Z,47528640,66281472,5406,Synced
on,3,3,2026-11-07T22:09:08Z,47486688,66232320,5406,Synced
on,3,4,2026-11-07T22:09:19Z,47494888,66273280,5406,Synced
on,3,5,2026-11-07T22:09:29Z,47523528,66281472,5406,Synced
off,4,1,2026-11-07T22:16:04Z,93917056,123666432,5406,Synced
off,4,2,2026-11-07T22:16:15Z,95006248,124657664,5406,Synced
off,4,3,2026-11-07T22:16:25Z,95001176,124665856,5406,Synced
off,4,4,2026-11-07T22:16:35Z,95008632,124657664,5406,Synced
off,4,5,2026-11-07T22:16:46Z,95044808,124674048,5406,Synced
on,4,1,2026-11-07T22:23:21Z,49860840,67936256,5406,Synced
on,4,2,2026-11-07T22:23:31Z,47497048,65413120,5406,Synced
on,4,3,2026-11-07T22:23:42Z,47539024,65404928,5406,Synced
on,4,4,2026-11-07T22:23:52Z,47493384,65347584,5406,Synced
on,4,5,2026-11-07T22:24:03Z,47572344,65355776,5406,Synced
off,5,1,2026-11-07T22:30:38Z,93927288,123625472,5406,Synced
off,5,2,2026-11-07T22:30:48Z,95013456,124370944,5406,Synced
off,5,3,2026-11-07T22:30:59Z,95010912,124362752,5406,Synced
off,5,4,2026-11-07T22:31:09Z,95005544,124362752,5406,Synced
off,5,5,2026-11-07T22:31:19Z,95053656,124379136,5406,Synced
on,5,1,2026-11-07T22:37:54Z,46200208,64110592,5406,Synced
on,5,2,2026-11-07T22:38:04Z,47326936,65134592,5406,Synced
on,5,3,2026-11-07T22:38:14Z,47307000,65085440,5406,Synced
on,5,4,2026-11-07T22:38:25Z,47306768,65085440,5406,Synced
on,5,5,2026-11-07T22:38:36Z,47342576,65085440,5406,Synced
Per-sample data: registered run, working set and heap in use (70 samples)
arm,start,sample,utc,working_set_bytes,heap_inuse_bytes,cpu_seconds_total,cache_objects,app_sync
off,1,1,2026-11-07T20:18:42Z,1.24286976e+09,9.51369728e+08,12.39,5397,Synced
off,1,2,2026-11-07T20:18:52Z,1.24286976e+09,9.53720832e+08,12.41,5397,Synced
off,1,3,2026-11-07T20:19:02Z,1.24286976e+09,9.53950208e+08,12.42,5397,Synced
off,1,4,2026-11-07T20:19:12Z,1.24286976e+09,9.566208e+08,12.43,5397,Synced
off,1,5,2026-11-07T20:19:23Z,1.243000832e+09,9.56850176e+08,12.45,5397,Synced
off,1,6,2026-11-07T20:19:33Z,1.243000832e+09,9.58447616e+08,12.47,5397,Synced
off,1,7,2026-11-07T20:19:43Z,1.243131904e+09,9.59848448e+08,12.49,5397,Synced
on,1,1,2026-11-07T20:24:12Z,9.8076672e+08,1.81395456e+08,8.49,5398,Synced
on,1,2,2026-11-07T20:24:23Z,9.80905984e+08,1.82673408e+08,8.52,5398,Synced
on,1,3,2026-11-07T20:24:33Z,9.8093056e+08,1.85106432e+08,8.53,5398,Synced
on,1,4,2026-11-07T20:24:43Z,9.80975616e+08,1.86458112e+08,8.54,5398,Synced
on,1,5,2026-11-07T20:24:53Z,9.80979712e+08,1.87670528e+08,8.56,5398,Synced
on,1,6,2026-11-07T20:25:04Z,9.80979712e+08,1.7547264e+08,8.65,5398,Synced
on,1,7,2026-11-07T20:25:14Z,2.292736e+08,1.76693248e+08,8.66,5398,Synced
off,2,1,2026-11-07T20:29:48Z,1.13139712e+09,2.36331008e+08,12.61,5399,Synced
off,2,2,2026-11-07T20:29:58Z,6.97073664e+08,2.36494848e+08,12.62,5399,Synced
off,2,3,2026-11-07T20:30:08Z,6.97073664e+08,5.50199296e+08,14.44,5399,Synced
off,2,4,2026-11-07T20:30:19Z,7.35473664e+08,7.702528e+08,16.83,5399,Synced
off,2,5,2026-11-07T20:30:29Z,1.255038976e+09,7.72972544e+08,16.85,5399,Synced
off,2,6,2026-11-07T20:30:39Z,1.255038976e+09,7.74356992e+08,16.86,5399,Synced
off,2,7,2026-11-07T20:30:50Z,1.255038976e+09,7.76716288e+08,16.88,5399,Synced
on,2,1,2026-11-07T20:36:10Z,6.52005376e+08,1.77012736e+08,8.85,5400,Synced
on,2,2,2026-11-07T20:36:21Z,6.52005376e+08,1.78274304e+08,8.86,5400,Synced
on,2,3,2026-11-07T20:36:31Z,6.52038144e+08,1.80641792e+08,8.88,5400,Synced
on,2,4,2026-11-07T20:36:42Z,6.52038144e+08,1.81854208e+08,8.89,5400,Synced
on,2,5,2026-11-07T20:36:52Z,6.52038144e+08,1.82099968e+08,8.91,5400,Synced
on,2,6,2026-11-07T20:37:02Z,6.52161024e+08,1.84672256e+08,8.92,5400,Synced
on,2,7,2026-11-07T20:37:12Z,6.52161024e+08,1.87219968e+08,8.94,5400,Synced
off,3,1,2026-11-07T20:41:57Z,1.193869312e+09,2.29187584e+08,13.03,5401,Synced
off,3,2,2026-11-07T20:42:07Z,9.00059136e+08,2.31555072e+08,13.04,5401,Synced
off,3,3,2026-11-07T20:42:18Z,9.00059136e+08,2.32890368e+08,13.06,5401,Synced
off,3,4,2026-11-07T20:42:28Z,9.00059136e+08,2.34266624e+08,13.08,5401,Synced
off,3,5,2026-11-07T20:42:38Z,9.00059136e+08,2.36609536e+08,13.1,5401,Synced
off,3,6,2026-11-07T20:42:48Z,9.00059136e+08,2.3916544e+08,13.12,5401,Synced
off,3,7,2026-11-07T20:42:59Z,9.00059136e+08,2.39403008e+08,13.14,5401,Synced
on,3,1,2026-11-07T20:48:10Z,6.80771584e+08,7.94976256e+08,18.83,5402,Synced
on,3,2,2026-11-07T20:48:21Z,6.80771584e+08,7.96532736e+08,18.85,5402,Synced
on,3,3,2026-11-07T20:48:31Z,1.218936832e+09,7.9896576e+08,18.87,5402,Synced
on,3,4,2026-11-07T20:48:41Z,1.221025792e+09,7.99178752e+08,18.88,5402,Synced
on,3,5,2026-11-07T20:48:52Z,1.221025792e+09,8.0203776e+08,18.89,5402,Synced
on,3,6,2026-11-07T20:49:02Z,1.221025792e+09,8.034304e+08,18.91,5402,Synced
on,3,7,2026-11-07T20:49:12Z,1.221025792e+09,8.03766272e+08,18.92,5402,Synced
off,4,1,2026-11-07T20:54:07Z,8.68265984e+08,2.34397696e+08,8.58,5403,Synced
off,4,2,2026-11-07T20:54:17Z,8.68265984e+08,2.3560192e+08,8.6,5403,Synced
off,4,3,2026-11-07T20:54:28Z,8.68265984e+08,2.37985792e+08,8.62,5403,Synced
off,4,4,2026-11-07T20:54:38Z,8.68265984e+08,2.3937024e+08,8.63,5403,Synced
off,4,5,2026-11-07T20:54:48Z,8.68278272e+08,2.4174592e+08,8.65,5403,Synced
off,4,6,2026-11-07T20:54:59Z,8.68282368e+08,2.41860608e+08,8.66,5403,Synced
off,4,7,2026-11-07T20:55:09Z,8.68282368e+08,2.4305664e+08,8.67,5403,Synced
on,4,1,2026-11-07T21:00:10Z,5.50518784e+08,1.74792704e+08,13.58,5404,Synced
on,4,2,2026-11-07T21:00:20Z,5.50518784e+08,1.77143808e+08,13.59,5404,Synced
on,4,3,2026-11-07T21:00:31Z,5.50518784e+08,1.7948672e+08,13.62,5404,Synced
on,4,4,2026-11-07T21:00:41Z,5.50518784e+08,1.79658752e+08,13.63,5404,Synced
on,4,5,2026-11-07T21:00:52Z,5.50518784e+08,1.80994048e+08,13.64,5404,Synced
on,4,6,2026-11-07T21:01:02Z,5.50518784e+08,1.83468032e+08,13.65,5404,Synced
on,4,7,2026-11-07T21:01:12Z,5.50518784e+08,1.83713792e+08,13.66,5404,Synced
off,5,1,2026-11-07T21:05:35Z,1.148686336e+09,2.35012096e+08,12.5,5405,Synced
off,5,2,2026-11-07T21:05:45Z,7.23697664e+08,2.36249088e+08,12.51,5405,Synced
off,5,3,2026-11-07T21:05:56Z,7.23697664e+08,2.37600768e+08,12.53,5405,Synced
off,5,4,2026-11-07T21:06:06Z,7.23697664e+08,2.40001024e+08,12.54,5405,Synced
off,5,5,2026-11-07T21:06:16Z,7.23697664e+08,7.636992e+08,16.89,5405,Synced
off,5,6,2026-11-07T21:06:27Z,1.29941504e+09,7.66263296e+08,16.91,5405,Synced
off,5,7,2026-11-07T21:06:37Z,1.29941504e+09,7.67557632e+08,16.92,5405,Synced
on,5,1,2026-11-07T21:11:26Z,1.204215808e+09,1.77733632e+08,9.09,5406,Synced
on,5,2,2026-11-07T21:11:36Z,7.98937088e+08,1.80027392e+08,9.11,5406,Synced
on,5,3,2026-11-07T21:11:46Z,7.98941184e+08,3.84671744e+08,11.82,5406,Synced
on,5,4,2026-11-07T21:11:57Z,1.076989952e+09,9.1418624e+08,13.58,5406,Synced
on,5,5,2026-11-07T21:12:07Z,1.076989952e+09,9.15644416e+08,13.6,5406,Synced
on,5,6,2026-11-07T21:12:17Z,1.077796864e+09,9.18011904e+08,13.61,5406,Synced
on,5,7,2026-11-07T21:12:28Z,1.077796864e+09,9.18298624e+08,13.63,5406,Synced
The post’s other memory items (partial JSON unmarshalling, fewer application copies, counting applications per cluster in one pass) are merged in 3.6.0. We checked them in the source tree, not in the lab.
ApplicationSets
The OCI generator reads directories and files from an OCI artifact instead of a Git repository. We pushed maborak/platform:v1.0.0 with three directories to a local registry and excluded platform/maborak-legacy: the ApplicationSet created maborak-ingress and maborak-monitoring, both Synced. 3.5.7 rejects the manifest with unknown field "spec.generators[0].oci".

An ApplicationSet fed by an OCI artifact. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
With tpl, a value read from a Git file, maborak team {{ .team }} verified, rendered as maborak team payments verified in the generated application’s annotation; 3.5.7 fails with function "tpl" not defined. Of the new workqueue flags, --wq-maxdelay defaults to 16m40s, the “roughly 16 minutes” in the post.
Raw output: `tpl` rendering and ApplicationSet controller flags
## C17 tpl, 2026-11-07T19:11:57Z
### 357 apps
### 357 appset conditions
{"type":"ErrorOccurred","status":"True","reason":"RenderTemplateParamsError","message":"failed to parse template {{ tpl .greeting . }}: template: base:1: function \"tpl\" not defined"}
{"type":"ParametersGenerated","status":"False","reason":"ErrorOccurred","message":"failed to parse template {{ tpl .greeting . }}: template: base:1: function \"tpl\" not defined"}
{"type":"ResourcesUpToDate","status":"False","reason":"ErrorOccurred","message":"failed to parse template {{ tpl .greeting . }}: template: base:1: function \"tpl\" not defined"}
### 361 apps
tpl-team-a greeting=hello from team-a
tpl-team-b greeting=hello from team-b
### 361 appset conditions
{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"}
{"type":"ParametersGenerated","status":"True","reason":"ParametersGenerated","message":"All parameters have been generated successfully"}
{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"}
## C18 appset controller flags, 2026-11-07T19:10:41Z
### 357
(no wq-* or refresh-grace flags)
### 361
--refresh-grace-period-seconds int The minimum grace period before a progressive sync may start refreshing outdated applications (default 30)
--wq-backoff-factor float Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5 (default 1.5)
--wq-basedelay duration Set Workqueue Per Item Rate Limiter Base Delay duration, default 1ms (default 1ms)
--wq-bucket-qps float Set Workqueue Rate Limiter Bucket QPS, default set to MaxFloat64 which disables the bucket limiter (default 1.7976931348623157e+308)
--wq-bucket-size int Set Workqueue Rate Limiter Bucket Size, default 500 (default 500)
--wq-cooldown duration Set Workqueue Per Item Rate Limiter Cooldown duration, default 0 (per item rate limiter disabled)
--wq-maxdelay duration Set Workqueue Per Item Rate Limiter Max Delay duration, default 16m40s (matches controller-runtime default) (default 16m40s)
Raw output: OCI generator, 3.5.7 and 3.6.1
## C13 OCI generator, 2026-11-07T19:19:49Z
### 357 apply
Error from server (BadRequest): error when creating "manifests/appset-oci.yaml": ApplicationSet in version "v1alpha1" cannot be handled as a ApplicationSet: strict decoding error: unknown field "spec.generators[0].oci"
### 361 apply
applicationset.argoproj.io/oci-platform created
### 357 apps
### 361 apps
oci-alpha sync=Synced health=Healthy
oci-beta sync=Synced health=Healthy
[{"type":"ErrorOccurred","status":"False","message":"All applications have been generated successfully"},{"type":"ParametersGenerated","status":"True","message":"All parameters have been generated successfully"},{"type":"ResourcesUpToDate","status":"True","message":"All applications have been generated successfully"}]
Progressive sync now refreshes the applications itself before it moves. In three trials we pushed a change and refreshed only rolling-dev; on 3.6.1 the ApplicationSet controller refreshed the other two (its new argocd_appset_app_refresh_total counter rose by 2 each time), and all three were on the new revision within 45 seconds. On 3.5.7, one of the two was still on the old revision after 45 seconds in 2 of the 3 trials.
Raw output: progressive sync refresh mechanism, three trials per version
357 trial 1: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 0->0 at45s_revision_current: dev=true,prod=true,staging=true
357 trial 2: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 0->0 at45s_revision_current: dev=true,prod=true,staging=false
357 trial 3: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 0->0 at45s_revision_current: dev=true,prod=false,staging=true
361 trial 1: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 2->4 at45s_revision_current: dev=true,prod=true,staging=true
361 trial 2: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 5->7 at45s_revision_current: dev=true,prod=true,staging=true
361 trial 3: annotations_seen_on_unrefreshed_apps=[] app_refresh_total 8->10 at45s_revision_current: dev=true,prod=true,staging=true
The same change adds a wait. With a push followed by a refresh of all three applications, step 1 was deployed 0–1 seconds after the push on 3.5.7 and 30–31 seconds after it on 3.6.1, in 5 of 5 trials each (Wilson 95% interval 57–100%). The new --refresh-grace-period-seconds flag defaults to 30; setting it to 0 brought 3.6.1 back to 0–1 seconds. Later steps followed within 2 seconds in every arm. [9] The post presents the flag as a way to give webhooks time; it does not say the default adds about 30 seconds before the first step of a rollout. We measured one three-step ApplicationSet; a larger one may wait for longer reconciles.
Per-trial data: seconds from push to deploy per step (15 trials)
| arm | trial | push_utc | rev | dev_s | staging_s | prod_s |
|---|---|---|---|---|---|---|
| v357 | 1 | 2026-11-07T21:16:47Z | e66ed01 | 1 | 1 | 2 |
| v357 | 2 | 2026-11-07T21:17:10Z | c5e6bb8 | 0 | 1 | 2 |
| v357 | 3 | 2026-11-07T21:17:32Z | a0c9926 | 1 | 2 | 3 |
| v357 | 4 | 2026-11-07T21:17:57Z | a3f968f | 1 | 2 | 3 |
| v357 | 5 | 2026-11-07T21:18:22Z | 9343ea4 | 1 | 2 | 3 |
| v361-grace30 | 1 | 2026-11-07T21:18:47Z | b8e2c57 | 31 | 32 | 33 |
| v361-grace30 | 2 | 2026-11-07T21:19:41Z | 4094976 | 30 | 31 | 32 |
| v361-grace30 | 3 | 2026-11-07T21:20:35Z | 7342c6e | 30 | 31 | 32 |
| v361-grace30 | 4 | 2026-11-07T21:21:29Z | c50da64 | 30 | 31 | 32 |
| v361-grace30 | 5 | 2026-11-07T21:22:23Z | c5fff87 | 30 | 31 | 32 |
| v361-grace0 | 1 | 2026-11-07T21:33:29Z | 296e87b | 1 | 1 | 2 |
| v361-grace0 | 2 | 2026-11-07T21:33:52Z | 7434a51 | 0 | 1 | 2 |
| v361-grace0 | 3 | 2026-11-07T21:34:15Z | 64d698b | 0 | 1 | 2 |
| v361-grace0 | 4 | 2026-11-07T21:34:38Z | 9835a85 | 0 | 1 | 2 |
| v361-grace0 | 5 | 2026-11-07T21:35:00Z | 6cebcab | 1 | 1 | 2 |
The rollout conditions fix a real ambiguity. A RollingSync with no steps reports Healthy and “ApplicationSet Rollout has completed” on 3.5.7, while its applications are never synced. On 3.6.1 the ApplicationSet is Degraded with reason ApplicationSetRolloutError and “No steps defined for rollout”.

3.5.7: “completed”, while both applications were never synced. Captured on our 3.5.7 instance on 7 November 2026, 23:59 UTC.

3.6.1: the same ApplicationSet is Degraded and says why. Captured on our 3.6.1 instance on 7 November 2026, 23:59 UTC.
The post’s names are Go constants: on the object, the new condition type is InvalidRolloutConfig and its reason is ApplicationSetInvalidRolloutConfig, which we triggered with maxUpdate: "lots". [12]
Raw output: rollout conditions, 3.5.7 and 3.6.1
## C16 RollingSync with no steps, 2026-11-07T19:11:57Z
### 357
{"health":{"message":"All applications have been generated successfully","status":"Healthy"},"conditions":[{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"ParametersGenerated","status":"True","reason":"ParametersGenerated","message":"Successfully generated parameters for all Applications"},{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"RolloutProgressing","status":"False","reason":"ApplicationSetRolloutComplete","message":"ApplicationSet Rollout has completed"}]}
### 361
{"health":{"message":"No steps defined for rollout","status":"Degraded"},"conditions":[{"type":"ErrorOccurred","status":"True","reason":"ApplicationSetRolloutError","message":"No steps defined for rollout"},{"type":"ParametersGenerated","status":"True","reason":"ParametersGenerated","message":"All parameters have been generated successfully"},{"type":"ResourcesUpToDate","status":"False","reason":"ErrorOccurred","message":"No steps defined for rollout"}]}
## C16 invalid rollout configs, 2026-11-07T19:27:19Z
### 357 badmax
{"health":{"message":"All applications have been generated successfully","status":"Healthy"},"conditions":[{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"RolloutProgressing","status":"False","reason":"ApplicationSetRolloutComplete","message":"ApplicationSet Rollout has completed"}]}
### 357 unmatched
{"health":{"message":"All applications have been generated successfully","status":"Healthy"},"conditions":[{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"RolloutProgressing","status":"False","reason":"ApplicationSetRolloutComplete","message":"ApplicationSet Rollout has completed"}]}
### 361 badmax
{"health":{"message":"All applications have been generated successfully","status":"Healthy"},"conditions":[{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"InvalidRolloutConfig","status":"True","reason":"ApplicationSetInvalidRolloutConfig","message":"Step 1 has an invalid maxUpdate value: lots"},{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"RolloutProgressing","status":"False","reason":"ApplicationSetRolloutComplete","message":"ApplicationSet Rollout has completed"}]}
### 361 unmatched
{"health":{"message":"All applications have been generated successfully","status":"Healthy"},"conditions":[{"type":"ErrorOccurred","status":"False","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"InvalidRolloutConfig","status":"False","reason":"ApplicationSetValidRolloutConfig","message":"Rolling Sync Configured correctly"},{"type":"ResourcesUpToDate","status":"True","reason":"ApplicationSetUpToDate","message":"All applications have been generated successfully"},{"type":"RolloutProgressing","status":"False","reason":"ApplicationSetRolloutComplete","message":"ApplicationSet Rollout has completed"}]}
All four new progressive sync metrics appeared on 3.6.1. argocd_appset_app_refresh_total shows up only once the controller has refreshed something itself, which never happened while we refreshed every application by hand.
Controller and CLI
- Rollback permission. We tested the permission, not every restriction the post lists. By default,
syncpermission still allows a rollback. Withserver.rbac.rollback.enforce.enable: "true", a user without the newrollbackaction gotPermissionDenied, and the same user with it succeeded. Rolling back an auto-sync application failed withFailedPrecondition. 3.5.7 rejectsrollbackas an RBAC action. - Label selectors. With
resource.selectorsset to!lab-noisefor ConfigMaps, the 3.6.1 controller cache dropped from 3,452 to 453 objects, which accounts for our 3,000 labelled noise ConfigMaps. 3.5.7 ignored the key. - Custom file extensions. With
disableExtensionFilter: true, a file namedone.manifestrendered. With the filter on,include: '*.manifest'rendered nothing. --server-proxy-url. The CLI created its RBAC objects over a direct connection; the server then failed withproxyconnect tcp: dial tcp: lookup server-proxy.lab ... no such host, so it used the proxy we passed. Adding--proxy-urlsent the CLI’s own call through that second proxy.admin export --strip-status. The export lost all status blocks, andkubectl apply -n argocdre-created two deleted Applications from it. The objects carry no namespace, so pass-n.- Deletion messages. A Service stuck on a finalizer reads “Pending deletion” on 3.5.7 and “Pending deletion; blocked by finalizers: lab.maborak.com/hold” on 3.6.1. A Lua
deletionMessagereplaced both the status and the message. - Tracing. 3.6.1 emits
controller.Refresh,CompareAppState,sync.*andreposerver.GenerateManifestspans, and 59 of our traces ran from the controller into the repo server; 3.5.7 sent only gRPC spans. The post names the sampling variable<COMPONENT_NAME>_OTLP_SAMPLE_RATIO. Read literally,APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO=0is ignored; the documented keyotlp.sample.ratio, which setsARGOCD_APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO, stopped every controller span. [8] - Hydrator metric.
argocd_app_infogainedhydrator_status="Hydrated"for a hydrated application. - CLI interrupts. The post says interrupted commands “could hang more than a minute”. Against an API server that accepts connections and never answers, both versions exit at once on Ctrl-C: 3.5.7 is simply killed by the signal. The hang appears in
--coremode, where the CLI runs an API server in-process. We found that by looking further after the planned test showed no hang, so treat it as exploratory. After Ctrl-C,argocd app wait --coreon 3.5.7 was still running at 150 seconds, when our script killed it, in 10 of 10 trials (Wilson 95% interval 72–100%), andargocd app logs --follow --corein 5 of 5. 3.6.1 exited within 0.01 seconds in all 15 (Fisher’s exact test, 15 of 15 against 0 of 15: p < 0.0001). Both CLIs ran against the same cluster. On 3.6.1,app waitreportstimed out (600s) waiting for appwhen interrupted, which is misleading. Two earlier attempts were discarded because the CLI talked to the wrong cluster; see Limits. [7]
Raw output: rollback permission matrix
## C22 rollback RBAC action (3.6.1), 2026-11-07T19:09:40Z
policy: dev has applications get+sync on default/*, no rollback
### A: server.rbac.rollback.enforce.enable unset (default)
yes
ConfigMap rb rb OutOfSync Healthy configmap/rb configured
### B: enforce=true, no rollback grant
no
{"level":"fatal","msg":"rpc error: code = PermissionDenied desc = permission denied","time":"2026-11-07T19:09:48Z"}
### C: enforce=true, rollback granted
yes
ConfigMap rb rb Synced Healthy configmap/rb configured
### D: enforce=true, rollback granted, but app has automated sync
{"level":"fatal","msg":"rpc error: code = FailedPrecondition desc = rollback cannot be initiated when auto-sync is enabled","time":"2026-11-07T19:09:56Z"}
### E: 3.5.7 CLI can-i rollback
{"level":"fatal","msg":"rpc error: code = InvalidArgument desc = [get create update delete sync override action invoke] does not contain rollback","time":"2026-11-07T19:09:57Z"}
Raw output: controller cache with `resource.selectors`
## C23 resource.selectors, 2026-11-07T19:21:32Z
3000 ConfigMaps labelled lab-noise=1 in ns noise
### 357 before: {"resourcesCount":3437,"apisCount":60}
### 361 before: {"resourcesCount":3452,"apisCount":60}
### 357 after resource.selectors '!lab-noise' on ConfigMap: {"resourcesCount":3438,"apisCount":60}
### 361 after resource.selectors '!lab-noise' on ConfigMap: {"resourcesCount":453,"apisCount":60}
Raw output: custom file extensions
## C26 custom extensions, 2026-11-07T19:05:21Z
### 3.6.1: disableExtensionFilter=true include={*.manifest,*.yaml}
application 'ext-on' created
### 3.6.1: filter on (default) include=*.manifest
application 'ext-off' created
### 3.5.7 CLI flag
Error: unknown flag: --directory-disable-extension-filter
### a361 manifests ext-on
source: one.manifest
name: from-manifest-ext
source: two.yaml
name: from-yaml-ext
### a361 manifests ext-off
### stored spec ext-on (3.6.1)
{"disableExtensionFilter":true,"include":"{*.manifest,*.yaml}"}
### CRD field present? 3.5.7 / 3.6.1
0
15
Raw output: `--server-proxy-url`
## C19 cluster add --server-proxy-url, 2026-11-07T19:18:21Z
### 3.5.7 CLI
Error: unknown flag: --server-proxy-url
### 3.6.1 CLI: --server-proxy-url only (CLI connects directly)
{"level":"info","msg":"Created bearer token secret \"argocd-manager-long-lived-token\" for ServiceAccount \"argocd-manager\"","time":"2026-11-07T19:18:21Z"}
{"level":"fatal","msg":"rpc error: code = Unknown desc = error getting server version: failed to get server version: Get \"https://127.0.0.1:50093/version?timeout=32s\": proxyconnect tcp: dial tcp: lookup server-proxy.lab on 10.96.0.10:53: no such host","time":"2026-11-07T19:18:22Z"}
### stored cluster secret
### 3.6.1 CLI: --proxy-url to an unreachable proxy (CLI side) with a different --server-proxy-url
{"level":"fatal","msg":"failed to create service account \"argocd-manager\" in namespace \"kube-system\": Post \"https://127.0.0.1:50093/api/v1/namespaces/kube-system/serviceaccounts\": proxyconnect tcp: dial tcp 127.0.0.1:9: connect: connection refused","time":"2026-11-07T19:18:22Z"}
Raw output: `admin export --strip-status`
## C20 admin export --strip-status (rerun with --context), 2026-11-07T19:06:30Z
### 3.5.7 CLI
Error: unknown flag: --strip-status
### Applications exported: 3
### top-level status: blocks full=4 stripped=0
18437 out/export-full.yaml
14232 out/export-strip.yaml
32669 total
### delete Applications, re-create from stripped export with kubectl apply -n argocd
application.argoproj.io "ext-off" deleted from argocd namespace
application.argoproj.io "ext-on" deleted from argocd namespace
application.argoproj.io/ext-off created
application.argoproj.io/ext-on created
Warning: resource applications/plain is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
application.argoproj.io/plain configured
same Application set restored
Raw output: sampling variable names
## C27 sample-ratio env var name, 2026-11-07T19:27:30Z
### arm=post-name since=2026-11-07T19:27:42Z env=[{"name":"ARGOCD_APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO","valueFrom":{"configMapKeyRef":{"key":"otlp.sample.ratio","name":"argocd-cmd-params-cm","optional":true}}},{"name":"APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO","value":"0"}]
3 | argocd-controller | controller.CompareAppState
3 | argocd-controller | controller.Refresh
### arm=doc-key-ratio0 since=2026-11-07T19:29:25Z env=[{"name":"ARGOCD_APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO","valueFrom":{"configMapKeyRef":{"key":"otlp.sample.ratio","name":"argocd-cmd-params-cm","optional":true}}}]
0 controller spans
### arm=unset since=2026-11-07T19:31:09Z env=[{"name":"ARGOCD_APPLICATION_CONTROLLER_OTLP_SAMPLE_RATIO","valueFrom":{"configMapKeyRef":{"key":"otlp.sample.ratio","name":"argocd-cmd-params-cm","optional":true}}}]
3 | argocd-controller | controller.CompareAppState
3 | argocd-controller | controller.Refresh
Per-trial data: CLI exit after Ctrl-C (42 trials)
| label | cli | trial | exit_code | seconds | last_stderr |
|---|---|---|---|---|---|
| server-silent-tcp | argocd-3.5.7 | 1 | -2 | 0.01 | |
| server-silent-tcp | argocd-3.6.1 | 1 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 2 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 2 | 1 | 0.01 | |
| server-silent-tcp | argocd-3.5.7 | 3 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 3 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 4 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 4 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 5 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 5 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 6 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 6 | 1 | 0.01 | |
| server-silent-tcp | argocd-3.5.7 | 7 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 7 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 8 | -2 | 0.00 | |
| server-silent-tcp | argocd-3.6.1 | 8 | 1 | 0.01 | |
| server-silent-tcp | argocd-3.5.7 | 9 | -2 | 0.01 | |
| server-silent-tcp | argocd-3.6.1 | 9 | 1 | 0.00 | |
| server-silent-tcp | argocd-3.5.7 | 10 | -2 | 0.01 | |
| server-silent-tcp | argocd-3.6.1 | 10 | 1 | 0.00 | |
| core-app-wait | argocd-3.5.7 | 1 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 1 | 20 | 0.01 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 2 | killed | 150.00 | {“level”:“error” |
| core-app-wait | argocd-3.5.7 | 3 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 3 | 20 | 0.01 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 4 | killed | 150.00 | {“level”:“error” |
| core-app-wait | argocd-3.6.1 | 4 | 20 | 0.01 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 5 | killed | 150.00 | {“level”:“error” |
| core-app-wait | argocd-3.5.7 | 6 | killed | 150.00 | {“level”:“error” |
| core-app-wait | argocd-3.5.7 | 7 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 7 | 20 | 0.01 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 8 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 8 | 20 | 0.01 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 9 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 9 | 20 | 0.00 | {“level”:“fatal” |
| core-app-wait | argocd-3.5.7 | 10 | killed | 150.00 | |
| core-app-wait | argocd-3.6.1 | 10 | 20 | 0.01 | {“level”:“fatal” |
| core-app-logs-follow | argocd-3.5.7 | 1 | killed | 150.00 | {“level”:“error” |
| core-app-logs-follow | argocd-3.5.7 | 2 | killed | 150.00 | {“level”:“error” |
| core-app-logs-follow | argocd-3.5.7 | 3 | killed | 150.00 | {“level”:“error” |
| core-app-logs-follow | argocd-3.5.7 | 4 | killed | 150.00 | {“level”:“error” |
| core-app-logs-follow | argocd-3.5.7 | 5 | killed | 150.00 | {“level”:“error” |
Discarded batch: CLI trials that reached the wrong cluster
label,cli,trial,exit_code,seconds,last_stderr
server-silent-tcp,argocd-3.5.7,1,-2,0.01,
server-silent-tcp,argocd-3.6.1,1,1,0.00,
server-silent-tcp,argocd-3.5.7,2,-2,0.00,
server-silent-tcp,argocd-3.6.1,2,1,0.01,
server-silent-tcp,argocd-3.5.7,3,-2,0.00,
server-silent-tcp,argocd-3.6.1,3,1,0.00,
server-silent-tcp,argocd-3.5.7,4,-2,0.00,
server-silent-tcp,argocd-3.6.1,4,1,0.00,
server-silent-tcp,argocd-3.5.7,5,-2,0.00,
server-silent-tcp,argocd-3.6.1,5,1,0.00,
server-silent-tcp,argocd-3.5.7,6,-2,0.00,
server-silent-tcp,argocd-3.6.1,6,1,0.01,
server-silent-tcp,argocd-3.5.7,7,-2,0.00,
server-silent-tcp,argocd-3.6.1,7,1,0.00,
server-silent-tcp,argocd-3.5.7,8,-2,0.00,
server-silent-tcp,argocd-3.6.1,8,1,0.01,
server-silent-tcp,argocd-3.5.7,9,-2,0.01,
server-silent-tcp,argocd-3.6.1,9,1,0.00,
server-silent-tcp,argocd-3.5.7,10,-2,0.01,
server-silent-tcp,argocd-3.6.1,10,1,0.00,
core-app-wait,argocd-3.5.7,1,killed,150.00,{"level":"error","msg":"Error shutting down http server: close tcp 127.0.0.1:64772: use of closed network connection","t
core-app-wait,argocd-3.6.1,1,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:06:13Z"}
core-app-wait,argocd-3.5.7,2,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:06:23Z"}
core-app-wait,argocd-3.6.1,2,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:06:33Z"}
core-app-wait,argocd-3.5.7,3,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:06:43Z"}
core-app-wait,argocd-3.6.1,3,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:06:54Z"}
core-app-wait,argocd-3.5.7,4,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:03Z"}
core-app-wait,argocd-3.6.1,4,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:13Z"}
core-app-wait,argocd-3.5.7,5,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:24Z"}
core-app-wait,argocd-3.6.1,5,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:34Z"}
core-app-wait,argocd-3.5.7,6,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:44Z"}
core-app-wait,argocd-3.6.1,6,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:07:54Z"}
core-app-wait,argocd-3.5.7,7,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:04Z"}
core-app-wait,argocd-3.6.1,7,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:14Z"}
core-app-wait,argocd-3.5.7,8,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:24Z"}
core-app-wait,argocd-3.6.1,8,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:34Z"}
core-app-wait,argocd-3.5.7,9,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:44Z"}
core-app-wait,argocd-3.6.1,9,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:08:54Z"}
core-app-wait,argocd-3.5.7,10,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:04Z"}
core-app-wait,argocd-3.6.1,10,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:14Z"}
core-app-logs-follow,argocd-3.5.7,1,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:24Z"}
core-app-logs-follow,argocd-3.6.1,1,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:34Z"}
core-app-logs-follow,argocd-3.5.7,2,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:44Z"}
core-app-logs-follow,argocd-3.6.1,2,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:09:54Z"}
core-app-logs-follow,argocd-3.5.7,3,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:04Z"}
core-app-logs-follow,argocd-3.6.1,3,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:14Z"}
core-app-logs-follow,argocd-3.5.7,4,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:24Z"}
core-app-logs-follow,argocd-3.6.1,4,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:34Z"}
core-app-logs-follow,argocd-3.5.7,5,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:44Z"}
core-app-logs-follow,argocd-3.6.1,5,20,0.00,{"level":"fatal","msg":"configmap \"argocd-cm\" not found","time":"2026-11-07T20:10:54Z"}
The tracing change is the easiest to see. We sent the controller’s spans to Jaeger; one refresh of maborak-web is a single trace that runs from controller.Refresh through manifest generation in the repo server to the diff and the status update:

One reconcile of maborak-web as a trace across the controller and the repo server. Captured from Jaeger on 8 November 2026, 00:00 UTC.
Raw output: span names per service after one hard refresh, 3.5.7 and 3.6.1
## C27 OTel span names by service (collector up ~3 min, includes one hard refresh of app plain), 2026-11-07T19:24:59Z
### 357 (count | service | span name)
51 | argocd-controller | repository.RepoServerService/GenerateManifest
4 | argocd-repo-server | grpc.health.v1.Health/Check
3 | argocd-server | server.ArgoCDServer.Authenticate
3 | argocd-server | server.ArgoCDServer.getClaims
3 | argocd-server | session.SessionManager.VerifyToken
1 | argocd-repo-server | repository.RepoServerService/GenerateManifest
1 | argocd-repo-server | repository.RepoServerService/GetAppDetails
1 | argocd-server | application.ApplicationService/Get
1 | argocd-server | cluster.SettingsService/Get
1 | argocd-server | project.ProjectService/Get
1 | argocd-server | repository.RepoServerService/GetAppDetails
### 361 (count | service | span name)
198 | argocd-controller | controller.CompareAppState
198 | argocd-controller | controller.GetRepoObjs
198 | argocd-controller | controller.GetRepoObjs.source
198 | argocd-controller | controller.diff
198 | argocd-controller | repository.RepoServerService/GenerateManifest
176 | argocd-controller | sync.apply
176 | argocd-controller | sync.runTasks
109 | argocd-controller | controller.Refresh
109 | argocd-controller | controller.autoSync
109 | argocd-controller | controller.handleRefreshAnnotations
109 | argocd-controller | controller.persistAppStatus
107 | argocd-repo-server | reposerver.GenerateManifest
107 | argocd-repo-server | repository.RepoServerService/GenerateManifest
89 | argocd-controller | sync.getSyncTasks
88 | argocd-controller | controller.Operation
88 | argocd-controller | controller.SyncAppState
88 | argocd-controller | sync.Sync
12 | argocd-server | server.ArgoCDServer.Authenticate
12 | argocd-server | server.ArgoCDServer.getClaims
12 | argocd-server | session.SessionManager.VerifyToken
7 | argocd-repo-server | reposerver.GenerateManifests
4 | argocd-repo-server | grpc.health.v1.Health/Check
4 | argocd-repo-server | reposerver.checkoutRevision
4 | argocd-server | application.ApplicationService/Get
4 | argocd-server | cluster.SettingsService/Get
4 | argocd-server | project.ProjectService/Get
1 | argocd-repo-server | repository.RepoServerService/GetAppDetails
1 | argocd-repo-server | repository.RepoServerService/GetGitFiles
1 | argocd-repo-server | repository.RepoServerService/GetOciDirectories
1 | argocd-server | repository.RepoServerService/GetAppDetails
traces=214 with controller.Refresh=109 spanning controller+repo-server=59
example trace b35948db5a22a90a201b018a5b197966
argocd-repo-server | reposerver.checkoutRevision
argocd-repo-server | reposerver.GenerateManifests
argocd-repo-server | reposerver.GenerateManifest
argocd-repo-server | repository.RepoServerService/GenerateManifest
argocd-controller | repository.RepoServerService/GenerateManifest
argocd-controller | controller.GetRepoObjs.source
argocd-controller | controller.GetRepoObjs
argocd-controller | controller.diff
argocd-controller | controller.CompareAppState
argocd-controller | controller.autoSync
argocd-controller | controller.persistAppStatus
argocd-controller | controller.handleRefreshAnnotations
argocd-controller | controller.Refresh
Counts and bug fixes
The post promises “about 20 new custom healthchecks”. At v3.5.7 the resource_customizations tree has 238 health.lua files; at v3.6.0 it has 293, and 55 of the 3.6.0 files do not exist at v3.5.7. [10] It says “more than 170 bugfixes”: the v3.6.0 release notes list 206 entries under Bug fixes, 190 without CI, docs and flaky-test fixes. [2]
Three of the seven “notable” fixes were backported before 3.6 shipped: the OIDC refresh fix (#27777) is in v3.5.0, #29070 in v3.5.2 and #28771 in v3.5.3. The repository-normalization item covers two fixes, and one of them (#28904) is also in v3.5.2. [11] On a current 3.5 patch release you already have those. New in 3.6 are #28414 (lost refresh requests), #28821 (impersonation), #28518 (oci:// without credentials) and #28619 (fewer repeated sync operations). Of these, we reproduced only #28821. #28619 was not tested; in progressive sync rollouts we saw six to ten sync operations per application within two seconds on both versions, which is a different code path.
All 32 claims
| # | Claim | What we found |
|---|---|---|
| 1 | Resources Explorer | Works, RBAC included; search is not kept in view preferences |
| 2 | Settings list search, filters, sort | Works; no filter sidebar on Projects |
| 3 | Advanced settings page | Works |
| 4 | Open rows in a new tab | Works (<a href>) |
| 5 | Regex search | Works |
| 6 | 20–30% less rendering work | Filtering about a third less script time; search unchanged |
| 7 | Lazy loading | Works for routes and Settings; tree view not split; terminal and diff not tested |
| 8 | Virtual scrolling above 50 apps | Works; threshold confirmed |
| 9 | Clear logs | Works |
| 10 | X-Robots-Tag | Works |
| 11 | ui.loginButtonText |
Works |
| 12 | Event component column | Works |
| 13 | OCI generator | Works (directory generator, one exclude) |
| 14 | Progressive sync refreshes apps first | Works; default adds about 30 s before step 1 |
| 15 | Four progressive sync metrics | Works |
| 16 | New rollout conditions | Works; names differ on the object |
| 17 | tpl in go-templates |
Works |
| 18 | Workqueue flags, ~16 min cap | Works |
| 19 | --server-proxy-url |
Works |
| 20 | --strip-status |
Works |
| 21 | CLI interrupt handling | Works; the hang was in --core mode |
| 22 | rollback RBAC action |
Works (permission; auto-sync refusal) |
| 23 | resource.selectors |
Works |
| 24 | Manifest compression, ~70% | Live heap halved in a follow-up run; registered working-set test showed no difference; opt-in; post links wrong PR |
| 25 | Three CPU and memory changes | In source |
| 26 | Custom file extensions | Works |
| 27 | Spans and sample ratio | Works; variable name wrong in post |
| 28 | hydrator_status label |
Works |
| 29 | About 20 new health checks | 55 new health.lua files |
| 30 | Deletion messages | Works |
| 31 | More than 170 bug fixes | 206 |
| 32 | Seven notable fixes | Three and a half already in 3.5.x; #28821 reproduced; others not tested |
Limits
- One host, small scale. Everything ran on one arm64 Mac: three kind clusters in one Colima VM, sharing one Gitea and one registry. Timings and memory are relative comparisons at lab scale, not capacity numbers.
- Planned and unplanned analyses. The rendering and memory protocols were written down before their first runs. The quiet rendering rerun, the live-heap memory run, the
--coreinterrupt tests, the 10-resource dry-run count and the progressive sync mechanism check were added afterwards, after a first result or a method review; they are labelled where they appear. - Discarded runs. Two batches of CLI interrupt trials were discarded because the CLI talked to the wrong cluster (
configmap "argocd-cm" not found, andpods ... not foundwith the command exiting before Ctrl-C). The first batch is shown in a collapsed block under the CLI results; the second was overwritten when the rerun started. A first progressive sync timing run overlapped controller restarts for other checks; its numbers matched the clean rerun, which is the one reported. - Partial tests of compound claims. Where the post lists several behaviours in one claim (rollback restrictions, OCI include and exclude patterns, lazy-loaded views), the table says which part we tested.
- Screenshots and measurements are separate. The
maborak-*objects were created after the measured runs, on the same clusters with the lab objects removed, to show each feature. The false-Synced result was found during that step, after the method review. - The writer ran the lab. The same AI agent designed the checks, ran them and wrote this post. Scoring is by script, but the choice of which follow-ups to run was the agent’s.
Sources
- “Argo CD v3.6 Less Memory, Faster UI, Better Rollout Visibility”, Eugene Doudine, Argo Project blog. Published 16 September 2026, modified 4 November 2026. https://blog.argoproj.io/argo-cd-v3-6-rc1-is-here-c0b562dc78d1 (opens in a new tab). The claims we tested.
- Argo CD releases v3.6.0 (3 November 2026) and v3.6.1 (4 November 2026), argoproj/argo-cd on GitHub. https://github.com/argoproj/argo-cd/releases/tag/v3.6.0 (opens in a new tab) and https://github.com/argoproj/argo-cd/releases/tag/v3.6.1 (opens in a new tab). Release dates, changelog, bug fix count.
- “v3.5 to 3.6” upgrade guide,
docs/operator-manual/upgrading/3.5-3.6.mdat tag v3.6.1. https://github.com/argoproj/argo-cd/blob/v3.6.1/docs/operator-manual/upgrading/3.5-3.6.md (opens in a new tab). SSA implies SSD, extra API server load, OTel changes. - PR #29103 “Default to SSD with SSA and remove SMD”, merged 9 September 2026, closes issue #24134. https://github.com/argoproj/argo-cd/pull/29103 (opens in a new tab). The diff strategy change.
- PR #28600 “configurable serialization and compression for cached manifests”, merged 10 September 2026. https://github.com/argoproj/argo-cd/pull/28600 (opens in a new tab). Configuration keys and the 3.27 GB benchmark.
- PR #28821 “Server-Side diff should respect impersonation”. https://github.com/argoproj/argo-cd/pull/28821 (opens in a new tab). The impersonation fix.
- Issue #28732 “argocd CLI does not propagate SIGINT/SIGTERM”, opened 15 July 2026, and PRs #28734 and #29226. https://github.com/argoproj/argo-cd/issues/28732 (opens in a new tab). CLI signal handling.
- Observability documentation,
docs/operator-manual/observability.mdat v3.6.1. https://github.com/argoproj/argo-cd/blob/v3.6.1/docs/operator-manual/observability.md (opens in a new tab).otlp.sample.ratioandARGOCD_<COMPONENT>_OTLP_*names. argocd-applicationset-controllercommand reference at v3.6.1. https://github.com/argoproj/argo-cd/blob/v3.6.1/docs/operator-manual/server-commands/argocd-applicationset-controller.md (opens in a new tab).--refresh-grace-period-secondsdefault 30,--wq-*flags.- Source tree at v3.5.7 and v3.6.1:
resource_customizations/**/health.lua,ui/src/app/applications/components/applications-list/virtual-scroll.ts,util/settings/settings.go. https://github.com/argoproj/argo-cd/tree/v3.6.1 (opens in a new tab). Health check count, virtual scroll threshold, settings keys. - Backports on release-3.5: #28689 (#27777), #29195 (#29070), #29399 (#28904), #29486 (#28771). https://github.com/argoproj/argo-cd/commits/release-3.5 (opens in a new tab). Which “notable” fixes are already in 3.5.x.
- PR #27820 rollout conditions, and
pkg/apis/application/v1alpha1/applicationset_types.goat v3.6.1. https://github.com/argoproj/argo-cd/pull/27820 (opens in a new tab). Condition type and reason names.