diff --git a/common/util.js b/common/util.js
index 9bf92e25986ce6b3a1e5650b550b1045a79e189b..9c66cad1bdf0964447c9e646b4035857efa24d14 100644
--- a/common/util.js
+++ b/common/util.js
@@ -47,6 +47,14 @@
     return true
   }
 
+  exports.arrayOrderedEql = function arrayOrderedEql(arr1, arr2) {
+    if (arr1.length !== arr2.length) return false
+    for (const idx in arr1) {
+      if (arr1[idx] !== arr2[idx]) return false
+    }
+    return true
+  }
+
   exports.strToRgb = str => {
     if (typeof str !== 'string') throw new Error(`strToRgb input must be typeof string !`)
 
diff --git a/common/util.spec.js b/common/util.spec.js
index 2af63766c202999af0a9ca2ccf57a341d947f0ee..b817b6607331d06fdb9373c20d70e1d4eb90e08a 100644
--- a/common/util.spec.js
+++ b/common/util.spec.js
@@ -1,4 +1,4 @@
-import { getIdFromFullId, strToRgb, verifyPositionArg } from './util'
+import { getIdFromFullId, strToRgb, verifyPositionArg, arrayOrderedEql } from './util'
 
 describe('common/util.js', () => {
   describe('getIdFromFullId', () => {
@@ -117,4 +117,37 @@ describe('common/util.js', () => {
       })
     })
   })
+
+  describe('> arrayOrderedEql', () => {
+    describe('> if array eql', () => {
+      it('> returns true', () => {
+        expect(
+          arrayOrderedEql(['foo', 3], ['foo', 3])
+        ).toBeTrue()
+      })
+    })
+    describe('> if array not eql', () => {
+      describe('> not ordered eql', () => {
+        it('> returns false', () => {
+          expect(
+            arrayOrderedEql(['foo', 'bar'], ['bar', 'foo'])
+          ).toBeFalse()
+        })
+      })
+      describe('> item not eql', () => {
+        it('> returns false', () => {
+          expect(
+            arrayOrderedEql(['foo', null], ['foo', undefined])
+          ).toBeFalse()
+        })
+      })
+      describe('> size not eql', () => {
+        it('> returns false', () => {
+          expect(
+            arrayOrderedEql([], [1])
+          ).toBeFalse()
+        })
+      })
+    })
+  })
 })
diff --git a/deploy/saneUrl/index.js b/deploy/saneUrl/index.js
index 2e9ab0b76528b999720781f7ff9cc913891f478d..72d0f9f9e2a8a13f98f96b7989c167ae61e2f47a 100644
--- a/deploy/saneUrl/index.js
+++ b/deploy/saneUrl/index.js
@@ -42,11 +42,16 @@ router.get('/:name', async (req, res) => {
       proxyStore.get(req, name)
     ])
 
-    const { queryString, hashPath } = json
+    const { queryString, hashPath, ...rest } = json
+
+    const xtraRoutes = []
+    for (const key in rest) {
+      if (/^x-/.test(key)) xtraRoutes.push(`${key}:${name}`)
+    }
 
     if (redirectFlag) {
       if (queryString) return res.redirect(`${REAL_HOSTNAME}?${queryString}`)
-      if (hashPath) return res.redirect(`${REAL_HOSTNAME}#${hashPath}`)
+      if (hashPath) return res.redirect(`${REAL_HOSTNAME}#${hashPath}/${xtraRoutes.join('/')}`)
     } else {
       return res.status(200).send(json)
     }
diff --git a/docs/releases/v2.5.8.md b/docs/releases/v2.5.8.md
new file mode 100644
index 0000000000000000000000000000000000000000..c9b68931c30f63fcbd0a5ab32686719e3cc92b1c
--- /dev/null
+++ b/docs/releases/v2.5.8.md
@@ -0,0 +1,9 @@
+# v2.5.8
+
+## Bugfix
+
+- fixed user annotation with saneurl
+
+## Under the hood
+
+- remove unnecessary UI refreshes
diff --git a/mkdocs.yml b/mkdocs.yml
index 300b8ee5f336e62adc328f83b4f602b5dc894cf5..a2ade830ee78908a40bb8dcd9ee1b7b489753329 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -40,6 +40,7 @@ pages:
     - Fetching datasets: 'advanced/datasets.md'
     - Display non-atlas volumes: 'advanced/otherVolumes.md'
   - Release notes:
+    - v2.5.8: 'releases/v2.5.8.md'
     - v2.5.7: 'releases/v2.5.7.md'
     - v2.5.6: 'releases/v2.5.6.md'
     - v2.5.5: 'releases/v2.5.5.md'
diff --git a/package.json b/package.json
index 1b8c4de04b3f608d8cba63b6abc8f96120f17696..b538486fe3ccd90b081f90e8e2d462f80acbf90f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "interactive-viewer",
-  "version": "2.5.7",
+  "version": "2.5.8",
   "description": "HBP interactive atlas viewer. Integrating KG query, dataset previews & more. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular",
   "scripts": {
     "build-aot": "ng build && node ./third_party/matomo/processMatomo.js",
diff --git a/src/services/state/ngViewerState.store.ts b/src/services/state/ngViewerState.store.ts
index 4b30e79372125b271161308125f9835400ec7886..5b1758d60906076840930cafbf878ab834e7e88d 100644
--- a/src/services/state/ngViewerState.store.ts
+++ b/src/services/state/ngViewerState.store.ts
@@ -191,29 +191,6 @@ export class NgViewerUseEffect implements OnDestroy {
     private http: HttpClient,
   ){
 
-    // TODO either split backend user to be more granular, or combine the user config into a single subscription
-    this.subscriptions.push(
-      this.store$.pipe(
-        select('ngViewerState'),
-        debounceTime(200),
-        skip(1),
-        // Max frequency save once every second
-
-        // properties to be saved
-        map(({ panelMode, panelOrder }) => {
-          return { panelMode, panelOrder }
-        }),
-        distinctUntilChanged(),
-        throttleTime(1000)
-      ).subscribe(ngViewerState => {
-        this.http.post(`${this.pureConstantService.backendUrl}user/config`, JSON.stringify({ ngViewerState }),  {
-          headers: {
-            'Content-type': 'application/json'
-          }
-        })
-      })
-    )
-
     this.applySavedUserConfig$ = this.http.get<TUserConfigResp>(`${this.pureConstantService.backendUrl}user/config`).pipe(
       map(json => {
         if (json.error) {
diff --git a/src/ui/logoContainer/logoContainer.component.ts b/src/ui/logoContainer/logoContainer.component.ts
index b7a85fda32a4147929b64e02be4f72c8481066b4..6b3ce834c7ae34d1459fc1965ab51dec8c14b3a1 100644
--- a/src/ui/logoContainer/logoContainer.component.ts
+++ b/src/ui/logoContainer/logoContainer.component.ts
@@ -1,6 +1,7 @@
 import { Component } from "@angular/core";
 import { PureContantService } from "src/util";
 import { Subscription } from "rxjs";
+import { distinctUntilChanged } from "rxjs/operators";
 
 @Component({
   selector : 'logo-container',
@@ -23,7 +24,9 @@ export class LogoContainer {
     private pureConstantService: PureContantService
   ){
     this.subscriptions.push(
-      pureConstantService.darktheme$.subscribe(flag => {
+      pureConstantService.darktheme$.pipe(
+        distinctUntilChanged()
+      ).subscribe(flag => {
         this.containerStyle = {
           backgroundImage: `url('${this.pureConstantService.backendUrl}logo${!!flag ? '?darktheme=true' : ''}')`
         }
diff --git a/src/util/pureConstant.service.spec.ts b/src/util/pureConstant.service.spec.ts
index 82e3a591947131afe10f6449a06f7682f2211d3d..fa9ccf741bd443baf767d929d5786a08ecd190b7 100644
--- a/src/util/pureConstant.service.spec.ts
+++ b/src/util/pureConstant.service.spec.ts
@@ -5,7 +5,7 @@ import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { BS_ENDPOINT } from "src/atlasComponents/regionalFeatures/bsFeatures"
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service"
 import { viewerStateFetchedAtlasesSelector, viewerStateFetchedTemplatesSelector } from "src/services/state/viewerState/selectors"
-import { PureContantService, SIIBRA_API_VERSION_HEADER_KEY } from "./pureConstant.service"
+import { PureContantService, SIIBRA_API_VERSION_HEADER_KEY, SIIBRA_API_VERSION } from "./pureConstant.service"
 import { TAtlas } from "./siibraApiConstants/types"
 
 const MOCK_BS_ENDPOINT = `http://localhost:1234`
@@ -68,7 +68,7 @@ describe('> pureConstant.service.ts', () => {
         const exp = httpController.expectOne(`${MOCK_BS_ENDPOINT}/atlases`)
         exp.flush([mockAtlas], {
           headers: {
-            [SIIBRA_API_VERSION_HEADER_KEY]: '0.1.7'
+            [SIIBRA_API_VERSION_HEADER_KEY]: SIIBRA_API_VERSION
           }
         })
         service.allFetchingReady$.subscribe()
diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts
index 4a700df39a6eb9eded56a548e3051ec175d72058..ba33d3b9388d8acbde91776d3826230be0074487 100644
--- a/src/util/pureConstant.service.ts
+++ b/src/util/pureConstant.service.ts
@@ -442,7 +442,6 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
       const { EXPERIMENTAL_FEATURE_FLAG } = environment
       if (EXPERIMENTAL_FEATURE_FLAG) return arr
       return arr
-      // return arr.filter(atlas => !/pre.?release/i.test(atlas.name))
     }),
     shareReplay(1),
   )
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 84621341979625d6ee5c4b866f405e940b886fbc..248b72fe0285b2e5510e948bebbe5f23da1d1f07 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -1,12 +1,12 @@
 import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, Inject, Optional } from "@angular/core";
 import { fromEvent, Subscription, ReplaySubject, BehaviorSubject, Observable, race, timer, Subject } from 'rxjs'
-import { debounceTime, filter, map, scan, startWith, mapTo, switchMap, take, skip, tap } from "rxjs/operators";
+import { debounceTime, filter, map, scan, startWith, mapTo, switchMap, take, skip, tap, distinctUntilChanged } from "rxjs/operators";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
 import { StateInterface as ViewerConfiguration } from "src/services/state/viewerConfig.store";
 import { LoggingService } from "src/logging";
 import { bufferUntil, getExportNehuba, getViewer, setNehubaViewer, switchMapWaitFor } from "src/util/fn";
 import { NEHUBA_INSTANCE_INJTKN, scanSliceViewRenderFn } from "../util";
-import { deserialiseParcRegionId } from 'common/util'
+import { deserialiseParcRegionId, arrayOrderedEql } from 'common/util'
 import { IMeshesToLoad, SET_MESHES_TO_LOAD } from "../constants";
 import { IColorMap, SET_COLORMAP_OBS, SET_LAYER_VISIBILITY } from "../layerCtrl.service";
 
@@ -310,6 +310,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
       this.ondestroySubscriptions.push(
         this.layerVis$.pipe(
           switchMap(switchMapWaitFor({ condition: () => !!(this.nehubaViewer?.ngviewer) })),
+          distinctUntilChanged(arrayOrderedEql),
           debounceTime(160),
         ).subscribe((layerNames: string[]) => {
           /**