diff --git a/packages/desktop-client/src/components/reports/Overview.jsx b/packages/desktop-client/src/components/reports/Overview.jsx
index 975735eec85bbb1039ee2348a846d06414177379..8100b3009725ae1cdab0afe4bc56a62cc0c3378e 100644
--- a/packages/desktop-client/src/components/reports/Overview.jsx
+++ b/packages/desktop-client/src/components/reports/Overview.jsx
@@ -13,11 +13,9 @@ import { View } from '../common/View';
 import { CashFlowCard } from './reports/CashFlowCard';
 import { CustomReportListCards } from './reports/CustomReportListCards';
 import { NetWorthCard } from './reports/NetWorthCard';
-import { SankeyCard } from './reports/SankeyCard';
 
 export function Overview() {
   const customReports = useReports();
-  const sankeyFeatureFlag = useFeatureFlag('sankeyReport');
 
   const customReportsFeatureFlag = useFeatureFlag('customReports');
 
@@ -54,14 +52,6 @@ export function Overview() {
         <NetWorthCard accounts={accounts} />
         <CashFlowCard />
       </View>
-      <View
-        style={{
-          flex: '0 0 auto',
-          flexDirection: 'row',
-        }}
-      >
-        {sankeyFeatureFlag && <SankeyCard />}
-      </View>
       {customReportsFeatureFlag && (
         <CustomReportListCards reports={customReports} />
       )}
diff --git a/packages/desktop-client/src/components/reports/ReportRouter.jsx b/packages/desktop-client/src/components/reports/ReportRouter.jsx
index 4318b31410288c94688d874663dc6455a36c2066..463e9484d4ac3139b5c43f9a0dfd6402014f3cdf 100644
--- a/packages/desktop-client/src/components/reports/ReportRouter.jsx
+++ b/packages/desktop-client/src/components/reports/ReportRouter.jsx
@@ -5,7 +5,6 @@ import { Overview } from './Overview';
 import { CashFlow } from './reports/CashFlow';
 import { CustomReport } from './reports/CustomReport';
 import { NetWorth } from './reports/NetWorth';
-import { Sankey } from './reports/Sankey';
 
 export function ReportRouter() {
   return (
@@ -14,7 +13,6 @@ export function ReportRouter() {
       <Route path="/net-worth" element={<NetWorth />} />
       <Route path="/cash-flow" element={<CashFlow />} />
       <Route path="/custom" element={<CustomReport />} />
-      <Route path="/sankey" element={<Sankey />} />
     </Routes>
   );
 }
diff --git a/packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx b/packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
deleted file mode 100644
index 5f97bfcba804cad8ec8e4cf3e345c3009bca556e..0000000000000000000000000000000000000000
--- a/packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-// @ts-strict-ignore
-import React from 'react';
-
-import {
-  Sankey,
-  Tooltip,
-  Rectangle,
-  Layer,
-  ResponsiveContainer,
-} from 'recharts';
-
-import { Container } from '../Container';
-import { numberFormatterTooltip } from '../numberFormatter';
-
-type SankeyProps = {
-  style;
-  data;
-  compact: boolean;
-};
-
-function SankeyNode({ x, y, width, height, index, payload, containerWidth }) {
-  const isOut = x + width + 6 > containerWidth;
-  let payloadValue = Math.round(payload.value / 1000).toString();
-  if (payload.value < 1000) {
-    payloadValue = '<1k';
-  } else {
-    payloadValue = payloadValue + 'k';
-  }
-  return (
-    <Layer key={`CustomNode${index}`}>
-      <Rectangle
-        x={x}
-        y={y}
-        width={width}
-        height={height}
-        fill="#5192ca"
-        fillOpacity="1"
-      />
-      <text
-        textAnchor={isOut ? 'end' : 'start'}
-        x={isOut ? x - 6 : x + width + 6}
-        y={y + height / 2}
-        fontSize="13"
-      >
-        {payload.name}
-      </text>
-      <text
-        textAnchor={isOut ? 'end' : 'start'}
-        x={isOut ? x - 6 : x + width + 6}
-        y={y + height / 2 + 13}
-        fontSize="9"
-        strokeOpacity="0.5"
-      >
-        {payloadValue}
-      </text>
-    </Layer>
-  );
-}
-
-function convertToCondensed(data) {
-  const budgetNodeIndex = data.nodes.findIndex(node => node.name === 'Budget');
-
-  // Calculate total income (links going into the "Budget" node)
-  const totalIncome = data.links.reduce((acc, link) => {
-    return link.target === budgetNodeIndex ? acc + link.value : acc;
-  }, 0);
-
-  // Calculate total expenses (links going out of the "Budget" node)
-  const totalExpenses = data.links.reduce((acc, link) => {
-    return link.source === budgetNodeIndex ? acc + link.value : acc;
-  }, 0);
-
-  return {
-    nodes: [{ name: 'Income' }, { name: 'Budget' }, { name: 'Expenses' }],
-    links: [
-      { source: 0, target: 1, value: totalIncome },
-      { source: 1, target: 2, value: totalExpenses },
-    ],
-  };
-}
-
-export function SankeyGraph({ style, data, compact }: SankeyProps) {
-  const sankeyData = compact ? convertToCondensed(data) : data;
-
-  if (!data.links || data.links.length === 0) return null;
-  const margin = {
-    left: 0,
-    right: 0,
-    top: compact ? 0 : 10,
-    bottom: compact ? 0 : 25,
-  };
-
-  return compact ? (
-    <ResponsiveContainer>
-      <Sankey
-        data={sankeyData}
-        node={props => <SankeyNode {...props} />}
-        sort={true}
-        iterations={1000}
-        nodePadding={23}
-        margin={margin}
-      >
-        <Tooltip
-          formatter={numberFormatterTooltip}
-          isAnimationActive={false}
-          separator=": "
-        />
-      </Sankey>
-    </ResponsiveContainer>
-  ) : (
-    <Container
-      style={{
-        ...style,
-        ...(compact && { height: 'auto' }),
-      }}
-    >
-      {width => (
-        <ResponsiveContainer>
-          <Sankey
-            data={sankeyData}
-            node={props => <SankeyNode {...props} containerWidth={width} />}
-            sort={true}
-            iterations={1000}
-            nodePadding={23}
-            margin={margin}
-          >
-            <Tooltip
-              formatter={numberFormatterTooltip}
-              isAnimationActive={false}
-              separator=": "
-            />
-          </Sankey>
-        </ResponsiveContainer>
-      )}
-    </Container>
-  );
-}
diff --git a/packages/desktop-client/src/components/reports/reports/Sankey.jsx b/packages/desktop-client/src/components/reports/reports/Sankey.jsx
deleted file mode 100644
index fad99a01c68655a15ebc2896346160346884e0b6..0000000000000000000000000000000000000000
--- a/packages/desktop-client/src/components/reports/reports/Sankey.jsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import React, { useState, useEffect, useMemo } from 'react';
-
-import * as d from 'date-fns';
-
-import { send } from 'loot-core/src/platform/client/fetch';
-import * as monthUtils from 'loot-core/src/shared/months';
-
-import { useCategories } from '../../../hooks/useCategories';
-import { useFilters } from '../../../hooks/useFilters';
-import { theme, styles } from '../../../style';
-import { Paragraph } from '../../common/Paragraph';
-import { View } from '../../common/View';
-import { SankeyGraph } from '../graphs/SankeyGraph';
-import { Header } from '../Header';
-import { createSpreadsheet as sankeySpreadsheet } from '../spreadsheets/sankey-spreadsheet';
-import { useReport } from '../useReport';
-import { fromDateRepr } from '../util';
-
-export function Sankey() {
-  const { grouped: categoryGroups } = useCategories();
-  const {
-    filters,
-    saved,
-    conditionsOp,
-    onApply: onApplyFilter,
-    onDelete: onDeleteFilter,
-    onUpdate: onUpdateFilter,
-    onCondOpChange,
-  } = useFilters();
-
-  const [allMonths, setAllMonths] = useState(null);
-  const [start, setStart] = useState(
-    monthUtils.subMonths(monthUtils.currentMonth(), 5),
-  );
-  const [end, setEnd] = useState(monthUtils.currentMonth());
-
-  const params = useMemo(
-    () => sankeySpreadsheet(start, end, categoryGroups, filters, conditionsOp),
-    [start, end, categoryGroups, filters, conditionsOp],
-  );
-  const data = useReport('sankey', params);
-  useEffect(() => {
-    async function run() {
-      const trans = await send('get-earliest-transaction');
-      const currentMonth = monthUtils.currentMonth();
-      let earliestMonth = trans
-        ? monthUtils.monthFromDate(d.parseISO(fromDateRepr(trans.date)))
-        : currentMonth;
-
-      // Make sure the month selects are at least populates with a
-      // year's worth of months. We can undo this when we have fancier
-      // date selects.
-      const yearAgo = monthUtils.subMonths(monthUtils.currentMonth(), 12);
-      if (earliestMonth > yearAgo) {
-        earliestMonth = yearAgo;
-      }
-
-      const allMonths = monthUtils
-        .rangeInclusive(earliestMonth, monthUtils.currentMonth())
-        .map(month => ({
-          name: month,
-          pretty: monthUtils.format(month, 'MMMM, yyyy'),
-        }))
-        .reverse();
-
-      setAllMonths(allMonths);
-    }
-    run();
-  }, []);
-
-  function onChangeDates(start, end) {
-    setStart(start);
-    setEnd(end);
-  }
-
-  if (!allMonths || !data) {
-    return null;
-  }
-
-  return (
-    <View style={{ ...styles.page, minWidth: 650, overflow: 'hidden' }}>
-      <Header
-        title="Sankey"
-        allMonths={allMonths}
-        start={start}
-        end={end}
-        onChangeDates={onChangeDates}
-        filters={filters}
-        saved={saved}
-        onApply={onApplyFilter}
-        onUpdateFilter={onUpdateFilter}
-        onDeleteFilter={onDeleteFilter}
-        conditionsOp={conditionsOp}
-        onCondOpChange={onCondOpChange}
-      />
-
-      <View
-        style={{
-          backgroundColor: theme.tableBackground,
-          padding: 30,
-          paddingTop: 0,
-          overflow: 'auto',
-          flexGrow: 1,
-        }}
-      >
-        <View
-          style={{
-            textAlign: 'right',
-            paddingTop: 20,
-            paddingRight: 20,
-            flexShrink: 0,
-          }}
-        >
-          <View
-            style={{ ...styles.largeText, fontWeight: 400, marginBottom: 5 }}
-          />
-        </View>
-
-        <SankeyGraph style={{ flexGrow: 1 }} data={data} />
-
-        <View style={{ marginTop: 30 }}>
-          <Paragraph>
-            <strong>What is a Sankey plot?</strong>
-          </Paragraph>
-          <Paragraph>
-            A Sankey plot visualizes the flow of quantities between multiple
-            categories, emphasizing the distribution and proportional
-            relationships of data streams. If you hover over the graph, you can
-            see detailed flow values between categories.
-          </Paragraph>
-        </View>
-      </View>
-    </View>
-  );
-}
diff --git a/packages/desktop-client/src/components/reports/reports/SankeyCard.jsx b/packages/desktop-client/src/components/reports/reports/SankeyCard.jsx
deleted file mode 100644
index 492962c23c25b4ac7d3ae6314123f6f8a9c9d9d4..0000000000000000000000000000000000000000
--- a/packages/desktop-client/src/components/reports/reports/SankeyCard.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import React, { useMemo } from 'react';
-
-import * as monthUtils from 'loot-core/src/shared/months';
-
-import { useCategories } from '../../../hooks/useCategories';
-import { styles } from '../../../style';
-import { Block } from '../../common/Block';
-import { View } from '../../common/View';
-import { DateRange } from '../DateRange';
-import { SankeyGraph } from '../graphs/SankeyGraph';
-import { LoadingIndicator } from '../LoadingIndicator';
-import { ReportCard } from '../ReportCard';
-import { createSpreadsheet as sankeySpreadsheet } from '../spreadsheets/sankey-spreadsheet';
-import { useReport } from '../useReport';
-
-export function SankeyCard() {
-  const { grouped: categoryGroups } = useCategories();
-  const end = monthUtils.currentMonth();
-  const start = monthUtils.subMonths(end, 5);
-
-  const params = useMemo(
-    () => sankeySpreadsheet(start, end, categoryGroups),
-    [start, end, categoryGroups],
-  );
-  const data = useReport('sankey', params);
-
-  return (
-    <ReportCard flex={1} to="/reports/sankey">
-      <View style={{ flexDirection: 'row', padding: 20 }}>
-        <View style={{ flex: 1 }}>
-          <Block
-            style={{ ...styles.mediumText, fontWeight: 500, marginBottom: 5 }}
-            role="heading"
-          >
-            Sankey
-          </Block>
-          <DateRange start={start} end={end} />
-        </View>
-      </View>
-      <View style={{ flex: 1 }}>
-        {data ? (
-          <SankeyGraph data={data} compact={true} />
-        ) : (
-          <LoadingIndicator />
-        )}
-      </View>
-    </ReportCard>
-  );
-}
diff --git a/packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
deleted file mode 100644
index c51f835ab84a1f58e6197b0b6804851f67610910..0000000000000000000000000000000000000000
--- a/packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-// @ts-strict-ignore
-import { runQuery } from 'loot-core/src/client/query-helpers';
-import { send } from 'loot-core/src/platform/client/fetch';
-import { q } from 'loot-core/src/shared/query';
-import { integerToAmount } from 'loot-core/src/shared/util';
-
-export function createSpreadsheet(
-  start,
-  end,
-  categories,
-  conditions = [],
-  conditionsOp,
-) {
-  return async (spreadsheet, setData) => {
-    // gather filters user has set
-    const { filters } = await send('make-filters-from-conditions', {
-      conditions: conditions.filter(cond => !cond.customName),
-    });
-    const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and';
-
-    // create list of Income subcategories
-    const allIncomeSubcategories = [].concat(
-      ...categories
-        .filter(category => category.is_income === 1)
-        .map(category => category.categories),
-    );
-
-    // retrieve sum of subcategory expenses
-    async function fetchCategoryData(categories) {
-      try {
-        return await Promise.all(
-          categories.map(async mainCategory => {
-            const subcategoryBalances = await Promise.all(
-              mainCategory.categories
-                .filter(subcategory => subcategory.is_income !== 1)
-                .map(async subcategory => {
-                  const results = await runQuery(
-                    q('transactions')
-                      .filter({
-                        [conditionsOpKey]: filters,
-                      })
-                      .filter({
-                        $and: [
-                          { date: { $gte: start + '-01' } },
-                          { date: { $lte: end + '-31' } },
-                        ],
-                      })
-                      .filter({ category: subcategory.id })
-                      .calculate({ $sum: '$amount' }),
-                  );
-                  return {
-                    subcategory: subcategory.name,
-                    value: results.data * -1,
-                  };
-                }),
-            );
-
-            // Here you could combine, reduce or transform the subcategoryBalances if needed
-            return {
-              name: mainCategory.name,
-              balances: subcategoryBalances,
-            };
-          }),
-        );
-      } catch (error) {
-        console.error('Error fetching category data:', error);
-        throw error; // Re-throw if you want the error to propagate
-      }
-    }
-
-    // retrieve all income subcategory payees
-    async function fetchIncomeData() {
-      // Map over allIncomeSubcategories and return an array of promises
-      const promises = allIncomeSubcategories.map(subcategory => {
-        return runQuery(
-          q('transactions')
-            .filter({
-              [conditionsOpKey]: filters,
-            })
-            .filter({
-              $and: [
-                { date: { $gte: start + '-01' } },
-                { date: { $lte: end + '-31' } },
-              ],
-            })
-            .filter({ category: subcategory.id })
-            .groupBy(['payee'])
-            .select(['payee', { amount: { $sum: '$amount' } }]),
-        );
-      });
-
-      // Use Promise.all() to wait for all queries to complete
-      const resultsArrays = await Promise.all(promises);
-
-      // unravel the results
-      const payeesDict = {};
-      resultsArrays.forEach(item => {
-        item.data.forEach(innerItem => {
-          payeesDict[innerItem.payee] = innerItem.amount;
-        });
-      });
-
-      // First, collect all unique IDs from payeesDict
-      const payeeIds = Object.keys(payeesDict);
-
-      const results = await runQuery(
-        q('payees')
-          .filter({ id: { $oneof: payeeIds } })
-          .select(['id', 'name']),
-      );
-
-      // Convert the resulting array to a payee-name-map
-      const payeeNames = {};
-      results.data.forEach(item => {
-        if (item.name && payeesDict[item.id]) {
-          payeeNames[item.name] = payeesDict[item.id];
-        }
-      });
-      return payeeNames;
-    }
-    const categoryData = await fetchCategoryData(categories);
-    const incomeData = await fetchIncomeData();
-
-    // convert retrieved data into the proper sankey format
-    setData(transformToSankeyData(categoryData, incomeData));
-  };
-}
-
-function transformToSankeyData(categoryData, incomeData) {
-  const data = { nodes: [], links: [] };
-  const nodeNames = new Set();
-
-  // Add the Budget node first.
-  data.nodes.push({ name: 'Budget' });
-  nodeNames.add('Budget');
-
-  // Handle the income sources and link them to the Budget node.
-  Object.entries(incomeData).forEach(([sourceName, value]) => {
-    if (!nodeNames.has(sourceName) && integerToAmount(value) > 0) {
-      data.nodes.push({ name: sourceName });
-      nodeNames.add(sourceName);
-      data.links.push({
-        source: sourceName,
-        target: 'Budget',
-        value: integerToAmount(value),
-      });
-    }
-  });
-
-  // add all category expenses that have valid subcategories and a balance
-  for (const mainCategory of categoryData) {
-    if (!nodeNames.has(mainCategory.name) && mainCategory.balances.length > 0) {
-      let mainCategorySum = 0;
-      for (const subCategory of mainCategory.balances) {
-        if (!nodeNames.has(subCategory.subcategory) && subCategory.value > 0) {
-          mainCategorySum += subCategory.value;
-        }
-      }
-      if (mainCategorySum === 0) {
-        continue;
-      }
-      data.nodes.push({ name: mainCategory.name });
-      nodeNames.add(mainCategory.name);
-      data.links.push({
-        source: 'Budget',
-        target: mainCategory.name,
-        value: integerToAmount(mainCategorySum),
-      });
-
-      // add the subcategories of the main category
-      for (const subCategory of mainCategory.balances) {
-        if (!nodeNames.has(subCategory.subcategory) && subCategory.value > 0) {
-          data.nodes.push({ name: subCategory.subcategory });
-          nodeNames.add(subCategory.subcategory);
-
-          data.links.push({
-            source: mainCategory.name,
-            target: subCategory.subcategory,
-            value: integerToAmount(subCategory.value),
-          });
-        }
-      }
-    }
-  }
-
-  // Map source and target in links to the index of the node
-  data.links.forEach(link => {
-    link.source = data.nodes.findIndex(node => node.name === link.source);
-    link.target = data.nodes.findIndex(node => node.name === link.target);
-  });
-
-  return data;
-}
diff --git a/packages/desktop-client/src/components/settings/Experimental.tsx b/packages/desktop-client/src/components/settings/Experimental.tsx
index 15f20989fecf4cbf98cb8bf2707eac438bbb7912..c7bcff182c74a500fb812c8b8e468ff41b9ecdcb 100644
--- a/packages/desktop-client/src/components/settings/Experimental.tsx
+++ b/packages/desktop-client/src/components/settings/Experimental.tsx
@@ -80,7 +80,6 @@ export function ExperimentalFeatures() {
         expanded ? (
           <View style={{ gap: '1em' }}>
             <FeatureToggle flag="customReports">Custom reports</FeatureToggle>
-            <FeatureToggle flag="sankeyReport">Sankey report</FeatureToggle>
 
             <ReportBudgetFeature />
 
diff --git a/packages/desktop-client/src/hooks/useFeatureFlag.ts b/packages/desktop-client/src/hooks/useFeatureFlag.ts
index c3d3fa1376f0b31e84f1561794658a4ada228ebf..467abc9ee2ca7d6ad718857ccd931073f65a07e6 100644
--- a/packages/desktop-client/src/hooks/useFeatureFlag.ts
+++ b/packages/desktop-client/src/hooks/useFeatureFlag.ts
@@ -4,7 +4,6 @@ import { type State } from 'loot-core/src/client/state-types';
 import type { FeatureFlag } from 'loot-core/src/types/prefs';
 
 const DEFAULT_FEATURE_FLAG_STATE: Record<FeatureFlag, boolean> = {
-  sankeyReport: false,
   reportBudget: false,
   goalTemplatesEnabled: false,
   customReports: false,
diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts
index f4a13c81d9d6ebd97967c6fb0cfcd8cdee2e63b2..0db98547329891fd882de3cc9f523653d660fa50 100644
--- a/packages/loot-core/src/types/prefs.d.ts
+++ b/packages/loot-core/src/types/prefs.d.ts
@@ -1,7 +1,6 @@
 import { type numberFormats } from '../shared/util';
 
 export type FeatureFlag =
-  | 'sankeyReport'
   | 'reportBudget'
   | 'goalTemplatesEnabled'
   | 'customReports'
diff --git a/upcoming-release-notes/2417.md b/upcoming-release-notes/2417.md
new file mode 100644
index 0000000000000000000000000000000000000000..c67a8abe74f37a2b06775a60c7b40550e335dd76
--- /dev/null
+++ b/upcoming-release-notes/2417.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [MatissJanis]
+---
+
+Delete experimental sankey feature - development abandoned.