diff --git a/i18n/en.json b/i18n/en.json
index c34de74ae5..91bbb6cda2 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -1,4 +1,6 @@
 {
+  "user_usage_stats": "Account usage statistics",
+  "user_usage_stats_description": "View account usage statistics",
   "about": "Refresh",
   "account": "Account",
   "account_settings": "Account Settings",
@@ -1315,5 +1317,7 @@
   "years_ago": "{years, plural, one {# year} other {# years}} ago",
   "yes": "Yes",
   "you_dont_have_any_shared_links": "You don't have any shared links",
-  "zoom_image": "Zoom Image"
+  "zoom_image": "Zoom Image",
+  "timeline": "Timeline",
+  "total": "Total"
 }
diff --git a/web/src/lib/components/shared-components/side-bar/more-information-albums.svelte b/web/src/lib/components/shared-components/side-bar/more-information-albums.svelte
deleted file mode 100644
index 58ce0c8574..0000000000
--- a/web/src/lib/components/shared-components/side-bar/more-information-albums.svelte
+++ /dev/null
@@ -1,27 +0,0 @@
-<script lang="ts">
-  import { type AlbumStatisticsResponseDto, getAlbumStatistics } from '@immich/sdk';
-  import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
-  import { t } from 'svelte-i18n';
-
-  interface Props {
-    albumType: keyof AlbumStatisticsResponseDto;
-  }
-
-  let { albumType }: Props = $props();
-
-  const handleAlbumCount = async () => {
-    try {
-      return await getAlbumStatistics();
-    } catch {
-      return { owned: 0, shared: 0, notShared: 0 };
-    }
-  };
-</script>
-
-{#await handleAlbumCount()}
-  <LoadingSpinner />
-{:then data}
-  <div>
-    <p>{$t('albums_count', { values: { count: data[albumType] } })}</p>
-  </div>
-{/await}
diff --git a/web/src/lib/components/shared-components/side-bar/more-information-assets.svelte b/web/src/lib/components/shared-components/side-bar/more-information-assets.svelte
deleted file mode 100644
index 5e4589be18..0000000000
--- a/web/src/lib/components/shared-components/side-bar/more-information-assets.svelte
+++ /dev/null
@@ -1,20 +0,0 @@
-<script lang="ts">
-  import { getAssetStatistics } from '@immich/sdk';
-  import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
-  import { t } from 'svelte-i18n';
-
-  interface Props {
-    assetStats: NonNullable<Parameters<typeof getAssetStatistics>[0]>;
-  }
-
-  let { assetStats }: Props = $props();
-</script>
-
-{#await getAssetStatistics(assetStats)}
-  <LoadingSpinner />
-{:then data}
-  <div>
-    <p>{$t('videos_count', { values: { count: data.videos } })}</p>
-    <p>{$t('photos_count', { values: { count: data.images } })}</p>
-  </div>
-{/await}
diff --git a/web/src/lib/components/shared-components/side-bar/side-bar-link.svelte b/web/src/lib/components/shared-components/side-bar/side-bar-link.svelte
index d3fd94ae08..13f08533c5 100644
--- a/web/src/lib/components/shared-components/side-bar/side-bar-link.svelte
+++ b/web/src/lib/components/shared-components/side-bar/side-bar-link.svelte
@@ -1,10 +1,7 @@
 <script lang="ts">
-  import { fade } from 'svelte/transition';
   import Icon from '$lib/components/elements/icon.svelte';
-  import { mdiInformationOutline } from '@mdi/js';
   import { resolveRoute } from '$app/paths';
   import { page } from '$app/stores';
-  import type { Snippet } from 'svelte';
 
   interface Props {
     title: string;
@@ -13,7 +10,6 @@
     flippedLogo?: boolean;
     isSelected?: boolean;
     preloadData?: boolean;
-    moreInformation?: Snippet;
   }
 
   let {
@@ -23,10 +19,8 @@
     flippedLogo = false,
     isSelected = $bindable(false),
     preloadData = true,
-    moreInformation,
   }: Props = $props();
 
-  let showMoreInformation = $state(false);
   let routePath = $derived(resolveRoute(routeId, {}));
 
   $effect(() => {
@@ -39,7 +33,7 @@
   data-sveltekit-preload-data={preloadData ? 'hover' : 'off'}
   draggable="false"
   aria-current={isSelected ? 'page' : undefined}
-  class="flex w-full place-items-center justify-between gap-4 rounded-r-full py-3 transition-[padding] delay-100 duration-100 hover:cursor-pointer hover:bg-immich-gray hover:text-immich-primary dark:text-immich-dark-fg dark:hover:bg-immich-dark-gray dark:hover:text-immich-dark-primary
+  class="flex w-full place-items-center gap-4 rounded-r-full py-3 transition-[padding] delay-100 duration-100 hover:cursor-pointer hover:bg-immich-gray hover:text-immich-primary dark:text-immich-dark-fg dark:hover:bg-immich-dark-gray dark:hover:text-immich-dark-primary
     {isSelected
     ? 'bg-immich-primary/10 text-immich-primary hover:bg-immich-primary/10 dark:bg-immich-dark-primary/10 dark:text-immich-dark-primary'
     : ''}
@@ -50,33 +44,5 @@
     <Icon path={icon} size="1.5em" class="shrink-0" flipped={flippedLogo} ariaHidden />
     <span class="text-sm font-medium">{title}</span>
   </div>
-
-  <div
-    class="h-0 overflow-hidden transition-[height] delay-1000 duration-100 sm:group-hover:h-auto group-hover:sm:overflow-visible md:h-auto md:overflow-visible"
-  >
-    {#if moreInformation}
-      <!-- svelte-ignore a11y_no_static_element_interactions -->
-      <div
-        class="relative flex cursor-default select-none justify-center"
-        onmouseenter={() => (showMoreInformation = true)}
-        onmouseleave={() => (showMoreInformation = false)}
-      >
-        <div class="p-1 text-gray-600 hover:cursor-help dark:text-gray-400">
-          <Icon path={mdiInformationOutline} />
-        </div>
-
-        {#if showMoreInformation}
-          <div class="absolute right-6 top-0">
-            <div
-              class="flex place-content-center place-items-center whitespace-nowrap rounded-3xl border bg-immich-bg px-6 py-3 text-xs text-immich-fg shadow-lg dark:border-immich-dark-gray dark:bg-gray-600 dark:text-immich-dark-fg"
-              class:hidden={!showMoreInformation}
-              transition:fade={{ duration: 200 }}
-            >
-              {@render moreInformation?.()}
-            </div>
-          </div>
-        {/if}
-      </div>
-    {/if}
-  </div>
+  <div></div>
 </a>
diff --git a/web/src/lib/components/shared-components/side-bar/side-bar.svelte b/web/src/lib/components/shared-components/side-bar/side-bar.svelte
index 54607e1779..000afa5d1a 100644
--- a/web/src/lib/components/shared-components/side-bar/side-bar.svelte
+++ b/web/src/lib/components/shared-components/side-bar/side-bar.svelte
@@ -24,8 +24,6 @@
   } from '@mdi/js';
   import SideBarSection from './side-bar-section.svelte';
   import SideBarLink from './side-bar-link.svelte';
-  import MoreInformationAssets from '$lib/components/shared-components/side-bar/more-information-assets.svelte';
-  import MoreInformationAlbums from '$lib/components/shared-components/side-bar/more-information-albums.svelte';
   import { t } from 'svelte-i18n';
   import BottomInfo from '$lib/components/shared-components/side-bar/bottom-info.svelte';
   import { preferences } from '$lib/stores/user.store';
@@ -47,11 +45,7 @@
       routeId="/(user)/photos"
       bind:isSelected={isPhotosSelected}
       icon={isPhotosSelected ? mdiImageMultiple : mdiImageMultipleOutline}
-    >
-      {#snippet moreInformation()}
-        <MoreInformationAssets assetStats={{ isArchived: false }} />
-      {/snippet}
-    </SideBarLink>
+    ></SideBarLink>
 
     {#if $featureFlags.search}
       <SideBarLink title={$t('explore')} routeId="/(user)/explore" icon={mdiMagnify} />
@@ -80,11 +74,7 @@
       routeId="/(user)/sharing"
       icon={isSharingSelected ? mdiAccountMultiple : mdiAccountMultipleOutline}
       bind:isSelected={isSharingSelected}
-    >
-      {#snippet moreInformation()}
-        <MoreInformationAlbums albumType="shared" />
-      {/snippet}
-    </SideBarLink>
+    ></SideBarLink>
 
     <div class="text-xs transition-all duration-200 dark:text-immich-dark-fg">
       <p class="hidden p-6 group-hover:sm:block md:block">{$t('library').toUpperCase()}</p>
@@ -96,17 +86,9 @@
       routeId="/(user)/favorites"
       icon={isFavoritesSelected ? mdiHeart : mdiHeartOutline}
       bind:isSelected={isFavoritesSelected}
-    >
-      {#snippet moreInformation()}
-        <MoreInformationAssets assetStats={{ isFavorite: true }} />
-      {/snippet}
-    </SideBarLink>
+    ></SideBarLink>
 
-    <SideBarLink title={$t('albums')} routeId="/(user)/albums" icon={mdiImageAlbum} flippedLogo>
-      {#snippet moreInformation()}
-        <MoreInformationAlbums albumType="owned" />
-      {/snippet}
-    </SideBarLink>
+    <SideBarLink title={$t('albums')} routeId="/(user)/albums" icon={mdiImageAlbum} flippedLogo></SideBarLink>
 
     {#if $preferences.tags.enabled && $preferences.tags.sidebarWeb}
       <SideBarLink title={$t('tags')} routeId="/(user)/tags" icon={mdiTagMultipleOutline} flippedLogo />
@@ -128,11 +110,7 @@
       routeId="/(user)/archive"
       bind:isSelected={isArchiveSelected}
       icon={isArchiveSelected ? mdiArchiveArrowDown : mdiArchiveArrowDownOutline}
-    >
-      {#snippet moreInformation()}
-        <MoreInformationAssets assetStats={{ isArchived: true }} />
-      {/snippet}
-    </SideBarLink>
+    ></SideBarLink>
 
     {#if $featureFlags.trash}
       <SideBarLink
@@ -140,11 +118,7 @@
         routeId="/(user)/trash"
         bind:isSelected={isTrashSelected}
         icon={isTrashSelected ? mdiTrashCan : mdiTrashCanOutline}
-      >
-        {#snippet moreInformation()}
-          <MoreInformationAssets assetStats={{ isTrashed: true }} />
-        {/snippet}
-      </SideBarLink>
+      ></SideBarLink>
     {/if}
   </nav>
 
diff --git a/web/src/lib/components/user-settings-page/user-settings-list.svelte b/web/src/lib/components/user-settings-page/user-settings-list.svelte
index 6f8a0ce4dc..5fdcc4a6a0 100644
--- a/web/src/lib/components/user-settings-page/user-settings-list.svelte
+++ b/web/src/lib/components/user-settings-page/user-settings-list.svelte
@@ -30,8 +30,10 @@
     mdiFeatureSearchOutline,
     mdiKeyOutline,
     mdiOnepassword,
+    mdiServerOutline,
     mdiTwoFactorAuthentication,
   } from '@mdi/js';
+  import UserUsageStatistic from '$lib/components/user-settings-page/user-usage-statistic.svelte';
 
   interface Props {
     keys?: ApiKeyResponseDto[];
@@ -59,6 +61,15 @@
     <UserProfileSettings />
   </SettingAccordion>
 
+  <SettingAccordion
+    icon={mdiServerOutline}
+    key="user-usage-info"
+    title={$t('user_usage_stats')}
+    subtitle={$t('user_usage_stats_description')}
+  >
+    <UserUsageStatistic />
+  </SettingAccordion>
+
   <SettingAccordion icon={mdiApi} key="api-keys" title={$t('api_keys')} subtitle={$t('manage_your_api_keys')}>
     <UserAPIKeyList bind:keys />
   </SettingAccordion>
diff --git a/web/src/lib/components/user-settings-page/user-usage-statistic.svelte b/web/src/lib/components/user-settings-page/user-usage-statistic.svelte
new file mode 100644
index 0000000000..8833d266ea
--- /dev/null
+++ b/web/src/lib/components/user-settings-page/user-usage-statistic.svelte
@@ -0,0 +1,124 @@
+<script lang="ts">
+  import {
+    getAlbumStatistics,
+    getAssetStatistics,
+    type AlbumStatisticsResponseDto,
+    type AssetStatsResponseDto,
+  } from '@immich/sdk';
+  import { onMount } from 'svelte';
+  import { t } from 'svelte-i18n';
+
+  let timelineStats: AssetStatsResponseDto = $state({
+    videos: 0,
+    images: 0,
+    total: 0,
+  });
+
+  let favoriteStats: AssetStatsResponseDto = $state({
+    videos: 0,
+    images: 0,
+    total: 0,
+  });
+
+  let archiveStats: AssetStatsResponseDto = $state({
+    videos: 0,
+    images: 0,
+    total: 0,
+  });
+
+  let trashStats: AssetStatsResponseDto = $state({
+    videos: 0,
+    images: 0,
+    total: 0,
+  });
+
+  let albumStats: AlbumStatisticsResponseDto = $state({
+    owned: 0,
+    shared: 0,
+    notShared: 0,
+  });
+
+  const getUsage = async () => {
+    [timelineStats, favoriteStats, archiveStats, trashStats, albumStats] = await Promise.all([
+      getAssetStatistics({ isArchived: false }),
+      getAssetStatistics({ isFavorite: true }),
+      getAssetStatistics({ isArchived: true }),
+      getAssetStatistics({ isTrashed: true }),
+      getAlbumStatistics(),
+    ]);
+  };
+
+  onMount(async () => {
+    await getUsage();
+  });
+</script>
+
+{#snippet row(viewName: string, imageCount: number, videoCount: number, totalCount: number)}
+  <td class="w-1/4 text-ellipsis px-4 text-sm">{viewName}</td>
+  <td class="w-1/4 text-ellipsis px-4 text-sm">{imageCount}</td>
+  <td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/4"> {videoCount}</td>
+  <td class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-1/4"> {totalCount}</td>
+{/snippet}
+
+<section class="my-6">
+  <p class="text-xs dark:text-white uppercase">{$t('photos_and_videos')}</p>
+  <table class="w-full text-left mt-4">
+    <thead
+      class="mb-4 flex h-12 w-full rounded-md border bg-gray-50 text-immich-primary dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-primary"
+    >
+      <tr class="flex w-full place-items-center">
+        <th class="w-1/4 text-center text-sm font-medium">{$t('view').toLocaleString()}</th>
+        <th class="w-1/4 text-center text-sm font-medium">{$t('photos').toLocaleString()}</th>
+        <th class="w-1/4 text-center text-sm font-medium">{$t('videos').toLocaleString()}</th>
+        <th class="w-1/4 text-center text-sm font-medium">{$t('total').toLocaleString()}</th>
+      </tr>
+    </thead>
+    <tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
+      <tr
+        class="flex h-[60px] w-full place-items-center text-center dark:text-immich-dark-fg bg-immich-bg dark:bg-immich-dark-gray/50"
+      >
+        {@render row($t('timeline'), timelineStats.images, timelineStats.videos, timelineStats.total)}
+      </tr>
+
+      <tr
+        class="flex h-[60px] w-full place-items-center text-center dark:text-immich-dark-fg bg-immich-gray dark:bg-immich-dark-gray/75"
+      >
+        {@render row($t('favorites'), favoriteStats.images, favoriteStats.videos, favoriteStats.total)}
+      </tr>
+
+      <tr
+        class="flex h-[60px] w-full place-items-center text-center dark:text-immich-dark-fg bg-immich-bg dark:bg-immich-dark-gray/50"
+      >
+        {@render row($t('archive'), archiveStats.images, archiveStats.videos, archiveStats.total)}
+      </tr>
+
+      <tr
+        class="flex h-[60px] w-full place-items-center text-center dark:text-immich-dark-fg bg-immich-gray dark:bg-immich-dark-gray/75"
+      >
+        {@render row($t('trash'), trashStats.images, trashStats.videos, trashStats.total)}
+      </tr>
+    </tbody>
+  </table>
+
+  <div class="mt-6">
+    <p class="text-xs dark:text-white uppercase">{$t('albums')}</p>
+  </div>
+  <table class="w-full text-left mt-4">
+    <thead
+      class="mb-4 flex h-12 w-full rounded-md border bg-gray-50 text-immich-primary dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-primary"
+    >
+      <tr class="flex w-full place-items-center">
+        <th class="w-1/2 text-center text-sm font-medium">{$t('owned')}</th>
+        <th class="w-1/2 text-center text-sm font-medium">{$t('shared')}</th>
+      </tr>
+    </thead>
+    <tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
+      <tr
+        class="flex h-[60px] w-full place-items-center text-center dark:text-immich-dark-fg bg-immich-bg dark:bg-immich-dark-gray/50"
+      >
+        <td class="w-1/2 text-ellipsis px-4 text-sm"> {albumStats.owned.toLocaleString()}</td>
+        <td class="w-1/2 text-ellipsis px-4 text-sm">{albumStats.shared.toLocaleString()}</td>
+      </tr>
+    </tbody>
+  </table>
+</section>