+
+
Spend is bucketed by UTC day
+
+
+
+ {!readsWholeKey && (
+
+ Showing your own requests on this key. A key shared across a team will have spend from other members that is
+ not counted here.
+
+ )}
+
+
+
+
+
+ Savings
+ {savingsSubtitle}
+
+
+ setAccumulation(value as SavingsAccumulation)}>
+
+ Cumulative
+ {intervalLabel}
+
+
+
+
+
+ {/* Distinguishes "still fetching" from "this key genuinely had no traffic": an empty
+ chart alone reads as a broken panel, and a $0.00 tile reads as a real zero. */}
+ {!hasRows && (
+
+ {isLoading ? "Loading savings..." : "No usage recorded for this key in this range."}
+
+ )}
+ {hasRows && accumulation === "cumulative" && (
+
+ )}
+ {/* Not stacked: auto-router can go negative on a cold-cache write, and stacking would
+ draw that below the axis while the rest of the bar still read as the total. */}
+ {hasRows && accumulation !== "cumulative" && }
+
+
+
+ );
+};
+
+export default KeySavingsTab;
diff --git a/ui/litellm-dashboard/src/components/templates/key_info_view.tsx b/ui/litellm-dashboard/src/components/templates/key_info_view.tsx
index b14820d8afa..5cfa737397b 100644
--- a/ui/litellm-dashboard/src/components/templates/key_info_view.tsx
+++ b/ui/litellm-dashboard/src/components/templates/key_info_view.tsx
@@ -14,6 +14,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { EntityLink } from "@/components/shared/EntityLink";
import { teamDetailHref } from "@/utils/entityLinks";
import { KeyInfoHeader } from "./KeyInfoHeader";
+import KeySavingsTab from "./KeySavingsTab";
import { useEffect, useState } from "react";
import { isProxyAdminRole, isUserTeamAdminForSingleTeam, rolesWithWriteAccess } from "../../utils/roles";
import { mapDisplayToInternalNames, mapInternalToDisplayNames } from "../callback_info_helpers";
@@ -603,6 +604,9 @@ export default function KeyInfoView({