diff --git a/spec/file_caching_test.js b/spec/file_caching_test.js
index 94490a492879cc48abfa1a5c4098384dea48a33f..e25c1bbf2521c8717a0e293d0eba18a97a473a3d 100644
--- a/spec/file_caching_test.js
+++ b/spec/file_caching_test.js
@@ -394,24 +394,41 @@ describe('File caching service', function () {
     })
   })
 
-  it('serves files as gzip', async function () {
+  it('serves index.html gzip compressed', async function () {
     mockFetch({
       'http://ui-server': {
         '/manifest.json': generateSimpleViteManifest({}),
-        '/large.js': () => new Response([...new Array(2500)].join(' '), { headers: { 'content-type': 'application/javascript' } })
+        '/index.html': () => new Response([...new Array(2500)].join(' '), { headers: { 'content-type': 'text/html' } })
       }
     })
     app = await mockApp()
 
-    const response = await request(app.server).get('/large.js')
+    const response = await request(app.server).get('/index.html')
     expect(response.statusCode).to.equal(200)
     expect(response.headers['content-encoding']).to.equal('gzip')
 
     // check for files in redis
-    expect(zlib.gunzipSync(await redis.client.getBuffer('ui-middleware:554855300:/large.js:body')).toString()).to.equal(response.text)
+    expect(zlib.gunzipSync(await redis.client.getBuffer('ui-middleware:554855300:/index.html:body')).toString()).to.equal(response.text)
   })
 
-  it('does not serve small files with gzip', async function () {
+  it('serves files as brotli compressed', async function () {
+    mockFetch({
+      'http://ui-server': {
+        '/manifest.json': generateSimpleViteManifest({}),
+        '/large.js': () => new Response([...new Array(2500)].join('a'), { headers: { 'content-type': 'application/javascript' } })
+      }
+    })
+    app = await mockApp()
+
+    const response = await request(app.server).get('/large.js')
+    expect(response.statusCode).to.equal(200)
+    expect(response.headers['content-encoding']).to.equal('br')
+
+    // check for files in redis
+    expect((await redis.client.getBuffer('ui-middleware:554855300:/large.js:body')).toString()).to.equal(response.text)
+  })
+
+  it('does not serve small files with compression', async function () {
     mockFetch({
       'http://ui-server': {
         '/manifest.json': generateSimpleViteManifest({}),
@@ -428,7 +445,7 @@ describe('File caching service', function () {
     expect((await redis.client.getBuffer('ui-middleware:554855300:/small.js:body')).toString()).to.equal(response.text)
   })
 
-  it('does not serve other mime types with gzip', async function () {
+  it('does not serve other mime types with compression', async function () {
     mockFetch({
       'http://ui-server': {
         '/manifest.json': generateSimpleViteManifest({}),
@@ -445,7 +462,7 @@ describe('File caching service', function () {
     expect(await redis.client.getBuffer('ui-middleware:554855300:/file.mp3:body')).to.deep.equal(response.body)
   })
 
-  it('does server svg as gzip (also escapes chars in regex)', async function () {
+  it('does serve svg with brotli compression (also escapes chars in regex)', async function () {
     mockFetch({
       'http://ui-server': {
         '/manifest.json': generateSimpleViteManifest({}),
@@ -456,9 +473,9 @@ describe('File caching service', function () {
 
     const response = await request(app.server).get('/file.svg')
     expect(response.statusCode).to.equal(200)
-    expect(response.headers['content-encoding']).to.equal('gzip')
+    expect(response.headers['content-encoding']).to.equal('br')
 
     // check for files in redis
-    expect(zlib.gunzipSync(await redis.client.getBuffer('ui-middleware:554855300:/file.svg:body'))).to.deep.equal(response.body)
+    expect(await redis.client.getBuffer('ui-middleware:554855300:/file.svg:body')).to.deep.equal(response.body)
   })
 })
diff --git a/src/files.js b/src/files.js
index 7fbdfb91e0d7cfe3e16718180174a55fed750045..757ff49260c8ee5ed4a041c005ffd5403704ccb1 100644
--- a/src/files.js
+++ b/src/files.js
@@ -8,6 +8,7 @@ import zlib from 'node:zlib'
 import { promisify } from 'node:util'
 
 const gzip = promisify(zlib.gzip)
+const brotliCompress = promisify(zlib.brotliCompress)
 
 const compressFileSize = Number(process.env.COMPRESS_FILE_SIZE)
 const compressionMimeTypes = (process.env.COMPRESS_FILE_TYPES || '').replace(/([.+*?^$()[\]{}|])/g, '\\$1').split(' ')
@@ -52,8 +53,13 @@ export async function fetchFileWithHeadersFromBaseUrl (path, baseUrl, version) {
   }
 
   if (result.body.length > compressFileSize && compressionWhitelistRegex.test(result.headers['content-type'])) {
-    result.body = await gzip(result.body)
-    result.headers['content-encoding'] = 'gzip'
+    if (path === '/index.html') {
+      result.body = await gzip(result.body)
+      result.headers['content-encoding'] = 'gzip'
+    } else {
+      result.body = await brotliCompress(result.body)
+      result.headers['content-encoding'] = 'br'
+    }
   }
 
   return result