diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml
index 90bb5eb22b..018d7ba8ee 100644
--- a/common/config/rush/pnpm-lock.yaml
+++ b/common/config/rush/pnpm-lock.yaml
@@ -851,6 +851,9 @@ dependencies:
   '@tiptap/suggestion':
     specifier: ^2.1.12
     version: 2.2.3(@tiptap/core@2.2.3)(@tiptap/pm@2.2.3)
+  '@types/apicache':
+    specifier: ^1.6.6
+    version: 1.6.6
   '@types/body-parser':
     specifier: ~1.19.2
     version: 1.19.5
@@ -956,6 +959,9 @@ dependencies:
   allure-playwright:
     specifier: ^2.9.2
     version: 2.12.2
+  apicache:
+    specifier: ^1.6.3
+    version: 1.6.3
   autolinker:
     specifier: 4.0.0
     version: 4.0.0
@@ -1070,9 +1076,6 @@ dependencies:
   express:
     specifier: ^4.18.3
     version: 4.18.3
-  express-fileupload:
-    specifier: ^1.4.3
-    version: 1.4.3
   express-static-gzip:
     specifier: ^2.1.7
     version: 2.1.7
@@ -6002,6 +6005,13 @@ packages:
       '@types/node': 20.11.19
     dev: false
 
+  /@types/apicache@1.6.6:
+    resolution: {integrity: sha512-RLeWpWG8QmXS2DshAMIm3HAtmUivFTSzdppppQgvNvbPYfi4871Ec4cXGySAlC9qqmciAZSVCWZPKAwNKwGATA==}
+    dependencies:
+      '@types/express': 4.17.21
+      '@types/redis': 2.8.32
+    dev: false
+
   /@types/aria-query@5.0.4:
     resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
     dev: false
@@ -6461,6 +6471,12 @@ packages:
       csstype: 3.1.3
     dev: false
 
+  /@types/redis@2.8.32:
+    resolution: {integrity: sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==}
+    dependencies:
+      '@types/node': 20.11.19
+    dev: false
+
   /@types/request@2.48.12:
     resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==}
     dependencies:
@@ -7133,6 +7149,11 @@ packages:
       picomatch: 2.3.1
     dev: false
 
+  /apicache@1.6.3:
+    resolution: {integrity: sha512-jS3VfUFpQ9BesFQZcdd1vVYg3ZsO2kGPmTJHqycIYPAQs54r74CRiyj8DuzJpwzLwIfCBYzh4dy9Jt8xYbo27w==}
+    engines: {node: '>=8'}
+    dev: false
+
   /app-root-dir@1.0.2:
     resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==}
     dev: false
@@ -9740,6 +9761,13 @@ packages:
       busboy: 1.6.0
     dev: false
 
+  /express-fileupload@1.5.0:
+    resolution: {integrity: sha512-jSW3w9evqM37VWkEPkL2Ck5wUo2a8qa03MH+Ou/0ZSTpNlQFBvSLjU12k2nYcHhaMPv4JVvv6+Ac1OuLgUZb7w==}
+    engines: {node: '>=12.0.0'}
+    dependencies:
+      busboy: 1.6.0
+    dev: false
+
   /express-static-gzip@2.1.7:
     resolution: {integrity: sha512-QOCZUC+lhPPCjIJKpQGu1Oa61Axg9Mq09Qvit8Of7kzpMuwDeMSqjjQteQS3OVw/GkENBoSBheuQDWPlngImvw==}
     dependencies:
@@ -18271,11 +18299,12 @@ packages:
     dev: false
 
   file:projects/front.tgz(esbuild@0.20.1):
-    resolution: {integrity: sha512-45U9B+tClmwLaS//3A6OZ8G/qz3bZgupz+KUmPB53c7XuJ/+cs5piBgif7d67N/2mUJ6cRlY8Kd8UGRwX4EI6Q==, tarball: file:projects/front.tgz}
+    resolution: {integrity: sha512-JFdC8n6d9GwIhrZ/XYnaoTZsqNetJ7udjL85tuXg3Cayq6j2hDa1L2LXN0NcBwrt3kCzGLpnPZRVJepMjJsCAA==, tarball: file:projects/front.tgz}
     id: file:projects/front.tgz
     name: '@rush-temp/front'
     version: 0.0.0
     dependencies:
+      '@types/apicache': 1.6.6
       '@types/body-parser': 1.19.5
       '@types/compression': 1.7.5
       '@types/cors': 2.8.17
@@ -18288,6 +18317,7 @@ packages:
       '@types/uuid': 8.3.4
       '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3)
       '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
+      apicache: 1.6.3
       body-parser: 1.20.2
       compression: 1.7.4
       cors: 2.8.5
@@ -18298,7 +18328,7 @@ packages:
       eslint-plugin-n: 15.7.0(eslint@8.56.0)
       eslint-plugin-promise: 6.1.1(eslint@8.56.0)
       express: 4.18.3
-      express-fileupload: 1.4.3
+      express-fileupload: 1.5.0
       express-static-gzip: 2.1.7
       jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2)
       morgan: 1.10.0
diff --git a/server/front/package.json b/server/front/package.json
index 98426d7d36..4fd4eec637 100644
--- a/server/front/package.json
+++ b/server/front/package.json
@@ -39,7 +39,8 @@
     "jest": "^29.7.0",
     "ts-jest": "^29.1.1",
     "@types/jest": "^29.5.5",
-    "@types/morgan": "~1.9.9"
+    "@types/morgan": "~1.9.9",
+    "@types/apicache": "^1.6.6"
   },
   "dependencies": {
     "@hcengineering/core": "^0.6.28",
@@ -56,6 +57,7 @@
     "body-parser": "^1.20.2",
     "sharp": "~0.32.0",
     "@hcengineering/minio": "^0.6.0",
-    "morgan": "^1.10.0"
+    "morgan": "^1.10.0",
+    "apicache": "^1.6.3"
   }
 }
diff --git a/server/front/src/index.ts b/server/front/src/index.ts
index 6fc27b46cd..6e8ae3c1e2 100644
--- a/server/front/src/index.ts
+++ b/server/front/src/index.ts
@@ -17,6 +17,7 @@
 import { MeasureContext, WorkspaceId, metricsAggregate } from '@hcengineering/core'
 import { MinioService } from '@hcengineering/minio'
 import { Token, decodeToken } from '@hcengineering/server-token'
+import apicache from 'apicache'
 import bp from 'body-parser'
 import cors from 'cors'
 import express, { Request, Response } from 'express'
@@ -242,6 +243,10 @@ export function start (
 ): () => void {
   const app = express()
 
+  const cache = apicache.options({
+    respectCacheControl: true
+  }).middleware
+
   app.use(cors())
   app.use(fileUpload())
   app.use(bp.json())
@@ -275,7 +280,7 @@ export function start (
       LAST_NAME_FIRST: config.lastNameFirst,
       ...(extraConfig ?? {})
     }
-    res.set('Cache-Control', cacheControlValue)
+    res.set('Cache-Control', `${cacheControlValue}, must-revalidate`)
     res.status(200)
     res.json(data)
   })
@@ -294,6 +299,7 @@ export function start (
         },
         admin
       })
+      res.set('Cache-Control', 'private, no-cache')
       res.end(json)
     } catch (err) {
       console.error(err)
@@ -304,7 +310,9 @@ export function start (
 
   const dist = resolve(process.env.PUBLIC_DIR ?? cwd(), 'dist')
   console.log('serving static files from', dist)
+
   app.use(
+    cache('1 day'),
     expressStaticGzip(dist, {
       serveStatic: {
         maxAge: '365d',
@@ -723,7 +731,11 @@ export function start (
     response.sendFile(join(dist, 'index.html'), {
       maxAge: cacheControlMaxAge,
       etag: true,
-      lastModified: true
+      lastModified: true,
+      cacheControl: false,
+      headers: {
+        'Cache-Control': `${cacheControlValue}, must-revalidate`
+      }
     })
   })