diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml
index 67204a64caecd0976cb9274a5f7d83b25d3cc1d8..54b7b8edbbe0652379fc74c5a81a58ada8a57e3a 100644
--- a/.docker/docker-compose.yml
+++ b/.docker/docker-compose.yml
@@ -277,6 +277,7 @@ services:
     image: registry.datalab.tuwien.ac.at/dbrepo/ui:1.4.5
     environment:
       NUXT_PUBLIC_API_CLIENT: "${BASE_URL:-http://localhost}"
+      NUXT_PUBLIC_API_SERVER: "${BASE_URL:-http://localhost}"
       NUXT_PUBLIC_UPLOAD_CLIENT: "${BASE_URL:-http://localhost}/api/upload/files"
     depends_on:
       dbrepo-search-service:
diff --git a/.docs/api/gateway-service.md b/.docs/api/gateway-service.md
index 923b95a9f30ac9af06bb029682bd67bc7f2f0961..26ad76f092c599fbb865648577eba7b1a283ba72 100644
--- a/.docs/api/gateway-service.md
+++ b/.docs/api/gateway-service.md
@@ -39,6 +39,12 @@ services:
 
 If your TLS private key as a password, you need to specify it in the `dbrepo.conf` file.
 
+### Connection Timeouts
+
+The reverse proxy has a defined timeout of 90 seconds on all requests (these are also enforced in the 
+[User Interface](../ui) using the [`axios`](https://www.npmjs.com/package/axios) module). For large databases these
+timeouts may need to be increased, e.g. the timeout for creating subsets is by default already increased to 600 seconds.
+
 ### User Interface
 
 To serve the [User Interface](../ui/) under different port than `80`, change the port mapping in
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
index 8f5f4a821484d23a51dd5c60a6bba658278fdb14..a7c74946923a36f639ae692e6d153881bcc2401f 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
@@ -86,19 +86,11 @@ public class SubsetEndpoint {
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<List<QueryDto>> list(@NotNull @PathVariable("databaseId") Long databaseId,
-                                               @RequestParam(name = "persisted", required = false) Boolean filterPersisted,
-                                               Principal principal)
+                                               @RequestParam(name = "persisted", required = false) Boolean filterPersisted)
             throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException,
             QueryNotFoundException, NotAllowedException, MetadataServiceException {
         log.debug("endpoint find subsets in database, databaseId={}, filterPersisted={}", databaseId, filterPersisted);
         final PrivilegedDatabaseDto database = metadataServiceGateway.getDatabaseById(databaseId);
-        if (!database.getIsPublic()) {
-            if (principal == null) {
-                log.error("Failed to find subsets in database: no access");
-                throw new NotAllowedException("Failed to find subsets in database: no access");
-            }
-            metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal));
-        }
         final List<QueryDto> queries;
         try {
             queries = subsetService.findAll(database, filterPersisted);
@@ -151,8 +143,7 @@ public class SubsetEndpoint {
     public ResponseEntity<?> findById(@NotNull @PathVariable("databaseId") Long databaseId,
                                       @NotNull @PathVariable("subsetId") Long subsetId,
                                       @NotNull HttpServletRequest httpServletRequest,
-                                      @RequestParam(required = false) Instant timestamp,
-                                      Principal principal)
+                                      @RequestParam(required = false) Instant timestamp)
             throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException,
             QueryNotFoundException, FormatNotAvailableException, StorageUnavailableException, QueryMalformedException,
             SidecarExportException, StorageNotFoundException, NotAllowedException, UserNotFoundException,
@@ -161,13 +152,6 @@ public class SubsetEndpoint {
         log.debug("endpoint find subset in database, databaseId={}, subsetId={}, accept={}, timestamp={}", databaseId,
                 subsetId, accept, timestamp);
         final PrivilegedDatabaseDto database = metadataServiceGateway.getDatabaseById(databaseId);
-        if (!database.getIsPublic()) {
-            if (principal == null) {
-                log.error("Failed to find subsets in database: no access");
-                throw new NotAllowedException("Failed to find subsets in database: no access");
-            }
-            metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal));
-        }
         final QueryDto query;
         try {
             query = subsetService.findById(database, subsetId);
@@ -262,7 +246,7 @@ public class SubsetEndpoint {
             StorageNotFoundException, QueryStoreInsertException, TableMalformedException, PaginationException,
             QueryNotSupportedException, NotAllowedException, UserNotFoundException, MetadataServiceException {
         log.debug("endpoint create subset in database, databaseId={}, data.statement={}, principal.name={}, " +
-                "page={}, size={}, timestamp={}", databaseId, data.getStatement(), principal.getName(), page, size,
+                        "page={}, size={}, timestamp={}", databaseId, data.getStatement(), principal.getName(), page, size,
                 timestamp);
         /* check */
         endpointValidator.validateDataParams(page, size);
@@ -360,21 +344,21 @@ public class SubsetEndpoint {
         }
         try {
             final QueryDto query = subsetService.findById(database, subsetId);
-            final Long count = subsetService.reExecuteCount(database, query);
             final HttpHeaders headers = new HttpHeaders();
-            headers.set("X-Count", "" + count);
             headers.set("Access-Control-Expose-Headers", "X-Count");
-            if (request.getMethod().equals("GET")) {
-                final QueryResultDto result = subsetService.reExecute(database, query, page, size, null, null);
-                result.setId(subsetId);
-                log.trace("re-execute query resulted in result {}", result);
+            if (request.getMethod().equals("HEAD")) {
+                final Long count = subsetService.reExecuteCount(database, query);
+                headers.set("X-Count", "" + count);
                 return ResponseEntity.ok()
                         .headers(headers)
-                        .body(result);
+                        .build();
             }
+            final QueryResultDto result = subsetService.reExecute(database, query, page, size, null, null);
+            result.setId(subsetId);
+            log.trace("re-execute query resulted in result {}", result);
             return ResponseEntity.ok()
                     .headers(headers)
-                    .build();
+                    .body(result);
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
index 7bc3a2aa5058abb664bc950e12cb502870266ac3..e26a37b43aaa1b5307cf87d294e1dedc5cef87c4 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
@@ -224,8 +224,8 @@ public class TableEndpoint {
         final HttpHeaders headers = new HttpHeaders();
         headers.set("Access-Control-Expose-Headers", "X-Count");
         try {
-            headers.set("X-Count", "" + tableService.getCount(table, timestamp));
             if (request.getMethod().equals("HEAD")) {
+                headers.set("X-Count", "" + tableService.getCount(table, timestamp));
                 return ResponseEntity.ok()
                         .headers(headers)
                         .build();
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
index e9dbfd5c3a7f3d59088f048398cd2c4f9d9d8f45..e4ddab603685103027dcb6dfad936b882c987294 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
@@ -92,8 +92,7 @@ public class ViewEndpoint {
     })
     public ResponseEntity<List<ViewDto>> getSchema(@NotBlank @PathVariable("databaseId") Long databaseId)
             throws DatabaseUnavailableException, DatabaseNotFoundException, RemoteUnavailableException,
-            ViewMalformedException, ViewNotFoundException, DatabaseMalformedException, ViewSchemaException,
-            MetadataServiceException {
+            ViewNotFoundException, DatabaseMalformedException, MetadataServiceException {
         log.debug("endpoint inspect view schemas, databaseId={}", databaseId);
         final PrivilegedDatabaseDto database = metadataServiceGateway.getDatabaseById(databaseId);
         try {
@@ -265,20 +264,19 @@ public class ViewEndpoint {
             metadataServiceGateway.getAccess(databaseId, UserUtil.getId(principal));
         }
         try {
-            final Long count = viewService.count(view, timestamp);
             final HttpHeaders headers = new HttpHeaders();
-            headers.set("X-Count", "" + count);
             headers.set("Access-Control-Expose-Headers", "X-Count");
-            if (request.getMethod().equals("GET")) {
-                final QueryResultDto result = viewService.data(view, timestamp, page, size);
-                log.trace("get view data resulted in result {}", result);
+            if (request.getMethod().equals("HEAD")) {
+                headers.set("X-Count", "" + viewService.count(view, timestamp));
                 return ResponseEntity.ok()
                         .headers(headers)
-                        .body(result);
+                        .build();
             }
+            final QueryResultDto result = viewService.data(view, timestamp, page, size);
+            log.trace("get view data resulted in result {}", result);
             return ResponseEntity.ok()
                     .headers(headers)
-                    .build();
+                    .body(result);
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
index d554667467009b396caee8f2800b522f21f8ace6..6a0015b6f61e567fbf65f2e8f97f6c568fe142fa 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
@@ -29,7 +29,6 @@ import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import java.io.InputStream;
-import java.security.Principal;
 import java.sql.SQLException;
 import java.time.Instant;
 import java.util.List;
@@ -69,7 +68,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
             DatabaseNotFoundException, RemoteUnavailableException, SQLException, MetadataServiceException {
 
         /* test */
-        final List<QueryDto> response = generic_findAllById(DATABASE_3_ID, DATABASE_3_PRIVILEGED_DTO, null);
+        final List<QueryDto> response = generic_findAllById(DATABASE_3_ID, DATABASE_3_PRIVILEGED_DTO);
         assertEquals(6, response.size());
     }
 
@@ -79,17 +78,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(DatabaseNotFoundException.class, () -> {
-            generic_findAllById(null, null, null);
-        });
-    }
-
-    @Test
-    @WithAnonymousUser
-    public void findAllById_privateNoAccess_fails() {
-
-        /* test */
-        assertThrows(NotAllowedException.class, () -> {
-            generic_findAllById(DATABASE_1_ID, DATABASE_1_PRIVILEGED_DTO, null);
+            generic_findAllById(null, null);
         });
     }
 
@@ -105,7 +94,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_3_PRIVILEGED_DTO);
 
         /* test */
-        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.APPLICATION_JSON, null, null);
+        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.APPLICATION_JSON, null);
     }
 
     @Test
@@ -126,7 +115,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(mock);
 
         /* test */
-        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.parseMediaType("text/csv"), null, null);
+        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.parseMediaType("text/csv"), null);
     }
 
     @Test
@@ -147,7 +136,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(mock);
 
         /* test */
-        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.parseMediaType("text/csv"), Instant.now(), null);
+        generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.parseMediaType("text/csv"), Instant.now());
     }
 
     @Test
@@ -161,7 +150,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(DatabaseNotFoundException.class, () -> {
-            generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.APPLICATION_JSON, null, null);
+            generic_findById(QUERY_5_ID, QUERY_5_DTO, MediaType.APPLICATION_JSON, null);
         });
     }
 
@@ -272,9 +261,6 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         /* test */
         final ResponseEntity<QueryResultDto> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
-        assertNotNull(response.getHeaders().get("X-Count"));
-        assertEquals(1, response.getHeaders().get("X-Count").size());
-        assertEquals(QUERY_5_RESULT_NUMBER, Long.parseLong(response.getHeaders().get("X-Count").get(0)));
         assertNotNull(response.getHeaders().get("Access-Control-Expose-Headers"));
         assertEquals(1, response.getHeaders().get("Access-Control-Expose-Headers").size());
         assertEquals("X-Count", response.getHeaders().get("Access-Control-Expose-Headers").get(0));
@@ -325,9 +311,6 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         /* test */
         final ResponseEntity<QueryResultDto> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
-        assertNotNull(response.getHeaders().get("X-Count"));
-        assertEquals(1, response.getHeaders().get("X-Count").size());
-        assertEquals(QUERY_1_RESULT_NUMBER, Long.parseLong(response.getHeaders().get("X-Count").get(0)));
         assertNotNull(response.getBody());
     }
 
@@ -464,7 +447,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         });
     }
 
-    protected List<QueryDto> generic_findAllById(Long databaseId, PrivilegedDatabaseDto database, Principal principal)
+    protected List<QueryDto> generic_findAllById(Long databaseId, PrivilegedDatabaseDto database)
             throws DatabaseUnavailableException, NotAllowedException, QueryNotFoundException, DatabaseNotFoundException,
             RemoteUnavailableException, SQLException, MetadataServiceException {
 
@@ -481,16 +464,16 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         }
 
         /* test */
-        final ResponseEntity<List<QueryDto>> response = subsetEndpoint.list(databaseId, null, principal);
+        final ResponseEntity<List<QueryDto>> response = subsetEndpoint.list(databaseId, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         return response.getBody();
     }
 
-    protected void generic_findById(Long subsetId, QueryDto subset, MediaType accept, Instant timestamp,
-                                    Principal principal) throws UserNotFoundException, DatabaseUnavailableException,
-            StorageUnavailableException, NotAllowedException, QueryMalformedException, QueryNotFoundException,
-            DatabaseNotFoundException, SidecarExportException, RemoteUnavailableException, FormatNotAvailableException,
-            StorageNotFoundException, SQLException, MetadataServiceException {
+    protected void generic_findById(Long subsetId, QueryDto subset, MediaType accept, Instant timestamp)
+            throws UserNotFoundException, DatabaseUnavailableException, StorageUnavailableException,
+            NotAllowedException, QueryMalformedException, QueryNotFoundException, DatabaseNotFoundException,
+            SidecarExportException, RemoteUnavailableException, FormatNotAvailableException, StorageNotFoundException,
+            SQLException, MetadataServiceException {
 
         /* mock */
         when(queryService.findById(DATABASE_3_PRIVILEGED_DTO, subsetId))
@@ -499,7 +482,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(accept.toString());
 
         /* test */
-        final ResponseEntity<?> response = subsetEndpoint.findById(DATABASE_3_ID, subsetId, mockHttpServletRequest, timestamp, principal);
+        final ResponseEntity<?> response = subsetEndpoint.findById(DATABASE_3_ID, subsetId, mockHttpServletRequest, timestamp);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
index 22da53c0a908cef6ccd9b387fdbce2214320b626..76c34ef47cd2d13f698f3d552b9aebbbb4175492 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
@@ -158,9 +158,6 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         /* test */
         final ResponseEntity<QueryResultDto> response = tableEndpoint.getData(DATABASE_3_ID, TABLE_8_ID, null, null, null, httpServletRequest, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
-        assertNotNull(response.getHeaders().get("X-Count"));
-        assertEquals(1, response.getHeaders().get("X-Count").size());
-        assertEquals(QUERY_5_RESULT_NUMBER, Long.parseLong(response.getHeaders().get("X-Count").get(0)));
         assertNotNull(response.getHeaders().get("Access-Control-Expose-Headers"));
         assertEquals(1, response.getHeaders().get("Access-Control-Expose-Headers").size());
         assertEquals("X-Count", response.getHeaders().get("Access-Control-Expose-Headers").get(0));
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
index b9b814378e9bd537d42c421c3e3fab81d381443f..543b4a5cf299d48a8a4594f95e8586752d4278cc 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
@@ -161,17 +161,12 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
-        when(viewService.count(eq(VIEW_1_PRIVILEGED_DTO), any(Instant.class)))
-                .thenReturn(VIEW_1_DATA_COUNT);
         when(viewService.data(eq(VIEW_1_PRIVILEGED_DTO), any(Instant.class), eq(0L), eq(10L)))
                 .thenReturn(VIEW_1_DATA_DTO);
 
         /* test */
         final ResponseEntity<QueryResultDto> response = viewEndpoint.getData(DATABASE_1_ID, VIEW_1_ID, null, null, null, httpServletRequest, USER_1_PRINCIPAL);
         assertEquals(HttpStatus.OK, response.getStatusCode());
-        assertNotNull(response.getHeaders().get("X-Count"));
-        assertEquals(1, response.getHeaders().get("X-Count").size());
-        assertEquals(VIEW_1_DATA_COUNT, Long.parseLong(response.getHeaders().get("X-Count").get(0)));
         assertNotNull(response.getHeaders().get("Access-Control-Expose-Headers"));
         assertEquals(1, response.getHeaders().get("Access-Control-Expose-Headers").size());
         assertEquals("X-Count", response.getHeaders().get("Access-Control-Expose-Headers").get(0));
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
index 3bf5f2a89a554206775e4138516d49616c4810b1..5898372633b0d63c5b256f6b567f8a8869583ab7 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
@@ -126,12 +126,12 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
     }
 
     @Test
-    @WithMockUser(username = USER_1_USERNAME, authorities = {"dbrepo_subset_list", "execute-query", "persist-query"})
+    @WithMockUser(username = USER_1_USERNAME, authorities = {"execute-query", "persist-query"})
     public void prometheusSubsetEndpoint_succeeds() {
 
         /* mock */
         try {
-            subsetEndpoint.list(DATABASE_1_ID, null, USER_1_PRINCIPAL);
+            subsetEndpoint.list(DATABASE_1_ID, null);
         } catch (Exception e) {
             /* ignore */
         }
@@ -151,7 +151,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
             /* ignore */
         }
         try {
-            subsetEndpoint.findById(DATABASE_1_ID, QUERY_1_ID, new MockHttpServletRequest(), null, USER_1_PRINCIPAL);
+            subsetEndpoint.findById(DATABASE_1_ID, QUERY_1_ID, new MockHttpServletRequest(), null);
         } catch (Exception e) {
             /* ignore */
         }
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
index 07394c765864671e1d286c242e3902be66a16767..b34053ec88a47a1f02ab99048fffc7e7f0cf35dd 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
@@ -21,6 +21,7 @@ import at.tuwien.api.database.table.constraints.foreign.ForeignKeyReferenceDto;
 import at.tuwien.api.database.table.constraints.foreign.ReferenceTypeDto;
 import at.tuwien.api.database.table.constraints.primary.PrimaryKeyDto;
 import at.tuwien.api.database.table.constraints.unique.UniqueDto;
+import at.tuwien.api.user.UserDto;
 import at.tuwien.config.QueryConfig;
 import at.tuwien.exception.QueryNotFoundException;
 import at.tuwien.exception.TableNotFoundException;
@@ -402,6 +403,9 @@ public interface DataMapper {
                 .created(LocalDateTime.parse(data.getString(2), mariaDbFormatter)
                         .atZone(ZoneId.of("UTC"))
                         .toInstant())
+                .creator(UserDto.builder()
+                        .id(UUID.fromString(data.getString(3)))
+                        .build())
                 .createdBy(UUID.fromString(data.getString(3)))
                 .query(data.getString(4))
                 .queryHash(data.getString(5))
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
index 265c361cd76180e36e92a292d9a36c006c9dfc97..97778e9e11679bc349ef6037fe8c7a9150cf530a 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
@@ -186,14 +186,16 @@ public class TableServiceMariaDbImpl extends HibernateConnector implements Table
         final QueryResultDto queryResult;
         try {
             /* find table data */
-            final long start = System.currentTimeMillis();
+            long start = System.currentTimeMillis();
             final ResultSet resultSet = connection.prepareStatement(mariaDbMapper.selectDatasetRawQuery(
                             table.getDatabase().getInternalName(), table.getInternalName(), table.getColumns(),
                             timestamp, size, page))
                     .executeQuery();
             log.debug("executed statement in {} ms", System.currentTimeMillis() - start);
+            start = System.currentTimeMillis();
             connection.commit();
             queryResult = dataMapper.resultListToQueryResultDto(table.getColumns(), resultSet);
+            log.debug("mapped result in {} ms", System.currentTimeMillis() - start);
         } catch (SQLException e) {
             connection.rollback();
             log.error("Failed to find data from table {}.{}: {}", table.getDatabase().getInternalName(), table.getInternalName(), e.getMessage());
diff --git a/dbrepo-gateway-service/dbrepo.conf b/dbrepo-gateway-service/dbrepo.conf
index f9c0001cebfbba5bbb842984377fb01197617d96..de8eaa417bbe422999436e83dc24f8fb66f9b1d5 100644
--- a/dbrepo-gateway-service/dbrepo.conf
+++ b/dbrepo-gateway-service/dbrepo.conf
@@ -134,7 +134,7 @@ server {
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header        X-Forwarded-Proto $scheme;
         proxy_pass              http://data;
-        proxy_read_timeout      90;
+        proxy_read_timeout      600;
     }
 
     location ~ /api/(database|concept|container|identifier|image|message|license|oai|ontology|unit|user) {
diff --git a/dbrepo-ui/components/database/DatabaseCard.vue b/dbrepo-ui/components/database/DatabaseCard.vue
index 9485fdee101584250d10bc1b8b959565a6699541..48aefa7493ce5beb52d8ec62cf794d64368b8489 100644
--- a/dbrepo-ui/components/database/DatabaseCard.vue
+++ b/dbrepo-ui/components/database/DatabaseCard.vue
@@ -4,11 +4,20 @@
     :to="`/database/${database.id}/info`"
     variant="flat"
     rounded="0"
-    :href="`/database/${database.id}`">
+    :href="`/database/${database.id}`"
+    @click="loading = true">
     <v-divider class="mx-4" />
-    <v-card-title
-      class="text-primary text-decoration-underline"
-      v-text="formatTitle(database)" />
+    <v-card-title>
+      <span
+        class="text-primary text-decoration-underline"
+        v-text="formatTitle(database)" />
+      <v-progress-circular
+        v-if="loading"
+        color="primary"
+        size="24"
+        class="ml-1"
+        indeterminate />
+    </v-card-title>
     <v-card-subtitle
       v-text="formatCreators(database)" />
     <v-card-text>
@@ -68,6 +77,11 @@
 import { formatLanguage } from '@/utils'
 
 export default {
+  data() {
+    return {
+      loading: false
+    }
+  },
   props: {
     database: {
       default: () => {
diff --git a/dbrepo-ui/components/database/DatabaseToolbar.vue b/dbrepo-ui/components/database/DatabaseToolbar.vue
index 5a86bbaa01410fb068533930af6636fc9f20d1d7..0c87e5599c688b3c4feebfbadb09a8868071d54d 100644
--- a/dbrepo-ui/components/database/DatabaseToolbar.vue
+++ b/dbrepo-ui/components/database/DatabaseToolbar.vue
@@ -10,21 +10,21 @@
         <span
           v-if="database && $vuetify.display.lgAndUp"
           v-text="database.name" />
-        <v-tooltip
-          v-if="database"
-          bottom>
-          <template v-slot:activator="{ props }">
-            <v-icon
-              class="mr-2"
-              size="small"
-              right
-              :color="database.is_public ? 'success' : 'chip'"
-              v-bind="props">
-              {{ database.is_public ? 'mdi-lock-open-outline' : 'mdi-lock-outline' }}
-            </v-icon>
-          </template>
-          <span>{{ $t('toolbars.database.' + (database.is_public ? 'public' : 'private')) }}</span>
-        </v-tooltip>
+        <v-chip
+          v-if="database && database.is_public"
+          size="small"
+          class="ml-2"
+          color="success"
+          :text="$t('toolbars.database.public')"
+          variant="outlined" />
+        <v-chip
+          v-if="database && !database.is_public"
+          size="small"
+          class="ml-2"
+          :color="colorVariant"
+          variant="outlined"
+          :text="$t('toolbars.database.private')"
+          flat />
       </v-toolbar-title>
       <v-spacer />
       <v-btn
@@ -33,6 +33,14 @@
         color="tertiary"
         :variant="buttonVariant"
         :text="$t('toolbars.database.dashboard.permanent') + ($vuetify.display.lgAndUp ? ' ' + $t('toolbars.database.dashboard.xl') : '')" />
+      <v-btn
+        v-if="canCreateTable"
+        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-table-large-plus' : null"
+        color="secondary"
+        variant="flat"
+        :text="($vuetify.display.lgAndUp ? $t('toolbars.database.create-table.xl') + ' ' : '') + $t('toolbars.database.create-table.permanent')"
+        class="mr-2"
+        :to="`/database/${$route.params.database_id}/table/create/dataset`" />
       <v-btn
         v-if="canCreateSubset"
         :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-wrench' : null"
@@ -49,14 +57,6 @@
         :text="($vuetify.display.lgAndUp ? $t('toolbars.database.create-view.xl') + ' ' : '') + $t('toolbars.database.create-view.permanent')"
         class="mr-2 white--text"
         :to="`/database/${$route.params.database_id}/view/create`" />
-      <v-btn
-        v-if="canCreateTable"
-        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-table-large-plus' : null"
-        color="secondary"
-        variant="flat"
-        :text="($vuetify.display.lgAndUp ? $t('toolbars.database.create-table.xl') + ' ' : '') + $t('toolbars.database.create-table.permanent')"
-        class="mr-2"
-        :to="`/database/${$route.params.database_id}/table/create/dataset`" />
       <v-btn
         v-if="canCreateIdentifier"
         :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-identifier' : null"
@@ -117,6 +117,9 @@ export default {
     roles () {
       return this.userStore.getRoles
     },
+    colorVariant () {
+      return this.isContrastTheme ? '' : (this.isDarkTheme ? 'tertiary' : 'secondary')
+    },
     canCreateIdentifier () {
       if (!this.roles) {
         return false
diff --git a/dbrepo-ui/components/identifier/Citation.vue b/dbrepo-ui/components/identifier/Citation.vue
index 8cd96902d48009da22cd761849be1962ba07c248..6f35ac915e255610965015ccd16adcf1dad03597 100644
--- a/dbrepo-ui/components/identifier/Citation.vue
+++ b/dbrepo-ui/components/identifier/Citation.vue
@@ -10,8 +10,8 @@
       <v-select
         v-model="style"
         :items="styles"
-        item-title="style"
-        item-value="accept"
+        item-title="title"
+        item-value="value"
         dense
         variant="outlined"
         single-line />
@@ -33,39 +33,38 @@ export default {
     return {
       loading: false,
       styles: [
-        { style: 'APA', accept: 'text/bibliography;style=apa' },
-        { style: 'IEEE', accept: 'text/bibliography;style=ieee' },
-        { style: 'BibTeX', accept: 'text/bibliography;style=bibtex' }
+        { title: 'APA', value: 'text/bibliography;style=apa' },
+        { title: 'IEEE', value: 'text/bibliography;style=ieee' },
+        { title: 'BibTeX', value: 'text/bibliography;style=bibtex' }
       ],
-      style: null,
+      style: 'text/bibliography;style=apa',
       citation: null
     }
   },
   watch: {
     style () {
-      this.loadCitation(this.style)
+      this.loadCitation()
     },
     pid () {
-      this.loadCitation(this.style)
+      this.loadCitation()
     }
   },
   mounted () {
-    this.style = this.styles[0].accept
-    this.loadCitation(null)
+    this.loadCitation()
   },
   methods: {
-    loadCitation (accept) {
-      if (!this.identifier || !accept) {
+    loadCitation () {
+      if (!this.identifier || !this.style) {
         return
       }
       this.loading = true
       const identifierService = useIdentifierService()
-      identifierService.findOne(this.identifier.id, accept)
+      identifierService.findOne(this.identifier.id, this.style)
         .then((citation) => {
           this.citation = citation
           this.loading = false
         })
-        .error(({code, message}) => {
+        .catch(({code, message}) => {
           const toast = useToastInstance()
           toast.error(this.$t(`${code}: ${message}`))
           this.loading = false
diff --git a/dbrepo-ui/components/subset/SubsetList.vue b/dbrepo-ui/components/subset/SubsetList.vue
index 21d4e7263eedd942f8abfec1470dd3a13af9d53e..b977daffa5aaf71dbe2980b98761244e8a3627b0 100644
--- a/dbrepo-ui/components/subset/SubsetList.vue
+++ b/dbrepo-ui/components/subset/SubsetList.vue
@@ -1,7 +1,7 @@
 <template>
   <div>
     <v-card
-      v-if="!loadingSubsets && queries.length === 0"
+      v-if="!loadingSubsets && subsets.length === 0"
       variant="flat"
       rounded="0"
       :text="$t('pages.database.subpages.subsets.empty')" />
@@ -14,7 +14,7 @@
         <Loading />
       </v-list-item>
       <div
-        v-for="(item, i) in queries"
+        v-for="(item, i) in subsets"
         :key="`q-${i}`">
         <v-divider v-if="i !== 0" class="mx-4" />
         <v-list>
@@ -54,9 +54,7 @@ export default {
     return {
       loadingSubsets: false,
       loadingIdentifiers: false,
-      queries: [],
-      identifiers: [],
-      isAuthorizationError: false,
+      subsets: [],
       cacheStore: useCacheStore(),
       userStore: useUserStore()
     }
@@ -77,8 +75,9 @@ export default {
       this.loadingSubsets = true
       const queryService = useQueryService()
       queryService.findAll(this.$route.params.database_id, true)
-        .then((queries) => {
-          this.queries = queries
+        .then((subsets) => {
+          this.loadingSubsets = false
+          this.subsets = subsets
         })
         .catch(({code}) => {
           this.loadingSubsets = false
@@ -88,9 +87,6 @@ export default {
           }
           toast.error(this.$t(code))
         })
-        .finally(() => {
-          this.loadingSubsets = false
-        })
     },
     title (query) {
       if (query.identifiers.length === 0) {
diff --git a/dbrepo-ui/components/subset/SubsetToolbar.vue b/dbrepo-ui/components/subset/SubsetToolbar.vue
index b51cc1d089085b657cb72d689fbf9ef2c6776b36..5c5081a2f8f5c3944928bbd59cd76dddc2c79d89 100644
--- a/dbrepo-ui/components/subset/SubsetToolbar.vue
+++ b/dbrepo-ui/components/subset/SubsetToolbar.vue
@@ -1,6 +1,7 @@
 <template>
   <div>
-    <v-toolbar flat>
+    <v-toolbar
+      flat>
       <v-btn
         class="mr-2"
         variant="plain"
@@ -27,16 +28,16 @@
         color="secondary"
         variant="flat"
         class="mb-1 ml-2"
-        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-content-save-outline' : null"
+        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-star' : null"
         :text="$t('toolbars.subset.save.permanent')"
         @click.stop="save" />
       <v-btn
         v-if="canForgetQuery"
         :loading="loadingSave"
-        color="error"
+        color="warning"
         variant="flat"
         class="mb-1 ml-2"
-        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-trash-can-outline' : null"
+        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-star-off' : null"
         :text="$t('toolbars.subset.unsave.permanent')"
         @click.stop="forget" />
       <v-btn
@@ -116,7 +117,10 @@ export default {
       if (!this.database) {
         return false
       }
-      return this.database.is_public
+      if (this.database.is_public) {
+        return true
+      }
+      return this.access
     },
     identifier () {
       /* mount pid */
@@ -154,7 +158,7 @@ export default {
       return formatTimestampUTCLabel(this.subset.created)
     },
     result_visibility () {
-      if (!this.database) {
+      if (!this.database || !this.subset) {
         return false
       }
       if (this.database.is_public) {
diff --git a/dbrepo-ui/components/view/ViewToolbar.vue b/dbrepo-ui/components/view/ViewToolbar.vue
index c107c3c0ef006c2d5456f6db187908e092664c5a..c43b730397a977559f85b55f92e62b486b15aa6f 100644
--- a/dbrepo-ui/components/view/ViewToolbar.vue
+++ b/dbrepo-ui/components/view/ViewToolbar.vue
@@ -11,16 +11,17 @@
     <v-spacer />
     <v-btn
       v-if="canDeleteView"
-      prepend-icon="mdi-delete"
       class="mr-2"
       variant="flat"
-      color="error"
-      :text="$vuetify.display.lgAndUp ? $t('navigation.delete') : ''"
+      :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-delete' : null"
       :loading="loadingDelete"
+      color="error"
+      :text="$t('navigation.delete')"
       @click="deleteView" />
     <v-btn
       v-if="canCreatePid"
-      prepend-icon="mdi-content-save-outline"
+      class="mr-2"
+      :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-content-save-outline' : null"
       variant="flat"
       color="primary"
       :text="($vuetify.display.lgAndUp ? $t('toolbars.view.pid.xl') + ' ' : '') + $t('toolbars.view.pid.permanent')"
@@ -63,6 +64,10 @@ export default {
     database () {
       return this.cacheStore.getDatabase
     },
+    buttonVariant () {
+      const runtimeConfig = useRuntimeConfig()
+      return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.button.contrast : runtimeConfig.public.variant.button.normal
+    },
     view () {
       if (!this.database) {
         return null
diff --git a/dbrepo-ui/composables/axios-instance.ts b/dbrepo-ui/composables/axios-instance.ts
index a2b6ca4f6ef5b138473b7812b460981a6f7c7f2f..d4f274b717e938c3305bc20463c93d9e9474e079 100644
--- a/dbrepo-ui/composables/axios-instance.ts
+++ b/dbrepo-ui/composables/axios-instance.ts
@@ -8,7 +8,7 @@ export const useAxiosInstance = () => {
   const userStore = useUserStore()
   if (!instance) {
     instance = axios.create({
-      timeout: 10_000,
+      timeout: 90_000,
       params: {},
       headers: {
         Accept: 'application/json',
diff --git a/dbrepo-ui/composables/identifier-service.ts b/dbrepo-ui/composables/identifier-service.ts
index a85f05a45c5d4211ca9374b874ccc367d5b56372..96e5610c8c11161b0a4c1687e630204f80e53554 100644
--- a/dbrepo-ui/composables/identifier-service.ts
+++ b/dbrepo-ui/composables/identifier-service.ts
@@ -2,7 +2,7 @@ import type {AxiosError, AxiosRequestConfig} from 'axios'
 import {axiosErrorToApiError} from '@/utils'
 
 export const useIdentifierService = (): any => {
-  async function findOne(id: number, accept: string | null): Promise<IdentifierDto> {
+  async function findOne(id: number, accept: string): Promise<IdentifierDto> {
     const axios = useAxiosInstance()
     console.debug('find identifier with id', id)
     const config: AxiosRequestConfig = {
diff --git a/dbrepo-ui/composables/query-service.ts b/dbrepo-ui/composables/query-service.ts
index fa18a55ec053bad22339a14bcb053b9a405f3716..abcd928b66d0350fd855ae380b959a33818b8f3d 100644
--- a/dbrepo-ui/composables/query-service.ts
+++ b/dbrepo-ui/composables/query-service.ts
@@ -13,6 +13,10 @@ export const useQueryService = (): any => {
           resolve(response.data)
         })
         .catch((error) => {
+          if (error.response.status === 403) {
+            /* ignore */
+            resolve([])
+          }
           console.error('Failed to find queries', error)
           reject(axiosErrorToApiError(error))
         })
@@ -77,7 +81,7 @@ export const useQueryService = (): any => {
     const axios = useAxiosInstance()
     console.debug('execute query in database with id', databaseId)
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.post<QueryResultDto>(`/api/database/${databaseId}/subset`, data, {params: mapFilter(timestamp, page, size)})
+      axios.post<QueryResultDto>(`/api/database/${databaseId}/subset`, data, {params: mapFilter(timestamp, page, size), timeout: 600_000})
         .then((response) => {
           console.info('Executed query with id', response.data.id, ' in database with id', databaseId)
           resolve(response.data)
@@ -93,7 +97,7 @@ export const useQueryService = (): any => {
     const axios = useAxiosInstance()
     console.debug('re-execute query in database with id', databaseId)
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.get<QueryResultDto>(`/api/database/${databaseId}/subset/${queryId}/data`, { params: mapFilter(null, page, size), timeout: 30_000 })
+      axios.get<QueryResultDto>(`/api/database/${databaseId}/subset/${queryId}/data`, { params: mapFilter(null, page, size) })
         .then((response) => {
           console.info('Re-executed query in database with id', databaseId)
           resolve(response.data)
@@ -109,7 +113,7 @@ export const useQueryService = (): any => {
     const axios = useAxiosInstance()
     console.debug('re-execute query in database with id', databaseId)
     return new Promise<number>((resolve, reject) => {
-      axios.head<void>(`/api/database/${databaseId}/subset/${queryId}/data`, { timeout: 30_000 })
+      axios.head<void>(`/api/database/${databaseId}/subset/${queryId}/data`)
         .then((response) => {
           const count: number = Number(response.headers['x-count'])
           console.info('Found', count, 'tuples for query', queryId, 'in database with id', databaseId)
diff --git a/dbrepo-ui/composables/table-service.ts b/dbrepo-ui/composables/table-service.ts
index 16c7f06ce6137ae9a87061ebcf253bc3e582bf0d..ffd7ebcd6074cc23d9bfa9412e19e48ef87f8f37 100644
--- a/dbrepo-ui/composables/table-service.ts
+++ b/dbrepo-ui/composables/table-service.ts
@@ -71,9 +71,8 @@ export const useTableService = (): any => {
     const axios = useAxiosInstance()
     console.debug('get data for table with id', tableId, 'in database with id', databaseId);
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/data`, { params: mapFilter(timestamp, page, size), timeout: 60_000 })
+      axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/data`, { params: mapFilter(timestamp, page, size) })
         .then((response) => {
-          response.data.count = Number(response.headers['x-count'])
           console.info('Got data for table with id', tableId, 'in database with id', databaseId)
           resolve(response.data)
         })
@@ -88,7 +87,7 @@ export const useTableService = (): any => {
     const axios = useAxiosInstance()
     console.debug('get data count for table with id', tableId, 'in database with id', databaseId);
     return new Promise<number>((resolve, reject) => {
-      axios.head<void>(`/api/database/${databaseId}/table/${tableId}/data`, { params: mapFilter(timestamp, null, null), timeout: 60_000 })
+      axios.head<void>(`/api/database/${databaseId}/table/${tableId}/data`, { params: mapFilter(timestamp, null, null) })
         .then((response: AxiosResponse<void>) => {
           const count: number = Number(response.headers['x-count'])
           console.info('Found' + count + 'in table with id', tableId, 'in database with id', databaseId)
@@ -192,7 +191,7 @@ export const useTableService = (): any => {
     const axios = useAxiosInstance()
     console.debug('suggest semantic entities for table column with id', columnId, 'of table with id', tableId, 'of database with id', databaseId)
     return new Promise<TableColumnEntityDto[]>((resolve, reject) => {
-      axios.get<TableColumnEntityDto[]>(`/api/database/${databaseId}/table/${tableId}/column/${columnId}/suggest`, {timeout: 60_000})
+      axios.get<TableColumnEntityDto[]>(`/api/database/${databaseId}/table/${tableId}/column/${columnId}/suggest`)
         .then((response) => {
           console.info('Suggested semantic entities for table column with id', columnId, 'of table with id', tableId, 'of database with id', databaseId)
           resolve(response.data)
diff --git a/dbrepo-ui/composables/view-service.ts b/dbrepo-ui/composables/view-service.ts
index adc76e32a1407f7e893cbe92692ec0b2f597591b..642a7c6e51ca7344dae72dd3ee12550c84c893a3 100644
--- a/dbrepo-ui/composables/view-service.ts
+++ b/dbrepo-ui/composables/view-service.ts
@@ -37,7 +37,7 @@ export const useViewService = (): any => {
     const axios = useAxiosInstance()
     console.debug('re-execute view with id', viewId, 'in database with id', databaseId)
     return new Promise<QueryResultDto>((resolve, reject) => {
-      axios.get<QueryResultDto>(`/api/database/${databaseId}/view/${viewId}/data`, { params: {page, size}, timeout: 30_000 })
+      axios.get<QueryResultDto>(`/api/database/${databaseId}/view/${viewId}/data`, { params: {page, size} })
         .then((response) => {
           console.info('Re-executed view with id', viewId, 'in database with id', databaseId)
           resolve(response.data)
@@ -53,7 +53,7 @@ export const useViewService = (): any => {
     const axios = useAxiosInstance()
     console.debug('re-execute view with id', viewId, 'in database with id', databaseId)
     return new Promise<number>((resolve, reject) => {
-      axios.head<number>(`/api/database/${databaseId}/view/${viewId}/data`, { timeout: 30_000 })
+      axios.head<number>(`/api/database/${databaseId}/view/${viewId}/data`)
         .then((response) => {
           const count: number = Number(response.headers['x-count'])
           console.info('Found', count, 'tuples for view with id', viewId, 'in database with id', databaseId)
diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json
index cf8dcfd03e8df91fd4ba737c4c3662dec41402f0..be8ddfcc2317d441d3a8b6edacd4b3f5a663c6af 100644
--- a/dbrepo-ui/locales/en-US.json
+++ b/dbrepo-ui/locales/en-US.json
@@ -1382,7 +1382,7 @@
     },
     "subset": {
       "save": {
-        "permanent": "Save"
+        "permanent": "Star"
       },
       "export": {
         "data": {
@@ -1399,7 +1399,7 @@
         "permanent": "PID"
       },
       "unsave": {
-        "permanent": "Unsave"
+        "permanent": "Unstar"
       }
     },
     "view": {
diff --git a/dbrepo-ui/pages/database/[database_id]/settings.vue b/dbrepo-ui/pages/database/[database_id]/settings.vue
index 61e9dc62449b48cba17d77b4bb717e8164c9f257..a79ad48c4193c9b4f0fbc83f84b3a2c0db3a6193 100644
--- a/dbrepo-ui/pages/database/[database_id]/settings.vue
+++ b/dbrepo-ui/pages/database/[database_id]/settings.vue
@@ -422,7 +422,7 @@ export default {
       databaseService.updateVisibility(this.$route.params.database_id, this.modifyVisibility)
         .then((database) => {
           const toast = useToastInstance()
-          toast.success('success.database.visibility')
+          toast.success(this.$t('success.database.visibility'))
           this.cacheStore.setDatabase(database)
         })
         .catch(() => {
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
index f740416faaf70387ed73935754c777435f58fa67..4902e2c54f243c7a2e4f3df90f3aa16cf7c26753 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/data.vue
@@ -14,6 +14,15 @@
           v-else
           v-text="executionUTC" />
       </v-toolbar-title>
+      <v-spacer />
+      <v-btn
+        :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-refresh' : null"
+        variant="flat"
+        :text="$t('toolbars.table.data.refresh')"
+        class="mr-2"
+        :disabled="loadingSubset"
+        :loading="loadingSubset"
+        @click="loadSubset" />
     </v-toolbar>
     <v-card tile>
       <QueryResults
diff --git a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
index d52ac91642901fe4b012345c1309235ea4f66420..1d9101fbf240d8d577026e53361f2cedb8f6486e 100644
--- a/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
+++ b/dbrepo-ui/pages/database/[database_id]/subset/[subset_id]/info.vue
@@ -103,7 +103,12 @@
 <script setup>
 const config = useRuntimeConfig()
 const { database_id, subset_id } = useRoute().params
-const { data } = await useFetch(`${config.public.api.server}/api/database/${database_id}/subset/${subset_id}`)
+const requestConfig = { timeout: 90_000, headers: { Accept: 'application/json', 'Content-Type': 'application/json' } }
+const userStore = useUserStore()
+if (userStore.getToken) {
+  requestConfig.headers.Authorization = `Bearer ${userStore.getToken}`
+}
+const { data } = await useFetch(`${config.public.api.server}/api/database/${database_id}/subset/${subset_id}`, requestConfig)
 if (data.value) {
   const identifierService = useIdentifierService()
   useServerHead(identifierService.subsetToServerHead(data.value))
diff --git a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
index 34527f7f195ec143519043aa3aca9a62c7fd77f8..bcab9b60be8812f270836644e5f521553a22040d 100644
--- a/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/table/[table_id]/data.vue
@@ -72,7 +72,7 @@
         :headers="headers"
         :items="rows"
         :items-length="total"
-        :loading="loadingData"
+        :loading="loadingData || loadingCount"
         :options.sync="options"
         :footer-props="footerProps"
         @update:options="loadData">
@@ -192,9 +192,6 @@ export default {
     }
   },
   computed: {
-    loadingColor () {
-      return this.error ? 'error' : 'primary'
-    },
     roles () {
       return this.userStore.getRoles
     },
@@ -283,6 +280,7 @@ export default {
   },
   watch: {
     version () {
+      this.loadCount()
       this.reload()
     },
     table (newTable, oldTable) {
@@ -293,6 +291,7 @@ export default {
   },
   mounted () {
     this.loadProperties()
+    this.loadCount()
   },
   methods: {
     addTuple () {
@@ -429,14 +428,25 @@ export default {
       this.lastReload = new Date()
       this.loadData({ page: this.options.page, itemsPerPage: this.options.itemsPerPage, sortBy: null})
     },
-    loadData ({ page, itemsPerPage, sortBy }) {
+    loadCount() {
+      this.loadingCount = true
+      const tableService = useTableService()
+      tableService.getCount(this.$route.params.database_id, this.$route.params.table_id, (this.versionISO || this.lastReload.toISOString()))
+        .then((count) => {
+          this.total = count
+          this.loadingCount = false
+        })
+        .catch((error) => {
+          this.loadingCount = false
+        })
+    },
+    loadData({ page, itemsPerPage, sortBy }) {
       this.options.page = page
       this.options.itemsPerPage = itemsPerPage
       const tableService = useTableService()
       this.loadingData = true
       tableService.getData(this.$route.params.database_id, this.$route.params.table_id, (page - 1), itemsPerPage, (this.versionISO || this.lastReload.toISOString()))
         .then((data) => {
-          this.total = data.count
           this.rows = data.result.map((row) => {
             for (const col in row) {
               const column = this.table.columns.filter(c => c.internal_name === col)[0]
diff --git a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
index 03464f5dbba66d89312f7b1c4a55332c79af161a..838ef2f0f1adf0a90f722ffd73d43457a5b92186 100644
--- a/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
+++ b/dbrepo-ui/pages/database/[database_id]/view/[view_id]/data.vue
@@ -10,7 +10,7 @@
         :prepend-icon="$vuetify.display.lgAndUp ? 'mdi-refresh' : null"
         variant="flat"
         :text="$t('toolbars.table.data.refresh')"
-        class="mb-1 ml-2"
+        class="mb-1 mr-2"
         :loading="loadingData"
         @click="reload" />
     </v-toolbar>
diff --git a/install.sh b/install.sh
index a9fcf6d10d374f048d14289d20fc89d01ef82813..5e367f4d53fefc633fb3131dad7360569ea971ac 100644
--- a/install.sh
+++ b/install.sh
@@ -69,15 +69,15 @@ fi
 echo "[📦] Pulling images for version ${VERSION} ..."
 docker compose pull
 
-echo "[✨] Starting DBRepo ..."
-docker compose up -d
-
-if [ $? -eq 0 ]; then
-  echo "[🎉] Successfully started!"
-  echo ""
-  echo "You can now inspect the logs with:"
-  echo ""
-  echo "  docker compose logs -f"
-  echo ""
-  echo "Read about next steps online: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/${VERSION}/installation/#next-steps"
-fi
+echo "[🎉] Success!"
+echo ""
+echo "You can now:"
+echo ""
+echo "  1) Either start the deployment running on http://localhost, or"
+echo "  2) Edit the BASE_URL variable in .env to set your hostname"
+echo ""
+echo "Then start the local deployment with:"
+echo ""
+echo "  docker compose up -d"
+echo ""
+echo "Read about next steps online: https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/${VERSION}/installation/#next-steps"