diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingOption.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingOption.java
index 0a75c767836998eec85741023ae6e554aa8daf3c..de2d39aac8c28e5532fdc2a4a4bc59474db12b77 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingOption.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingOption.java
@@ -2,6 +2,9 @@ package de.deadlocker8.budgetmaster.repeating;
 
 import com.google.gson.annotations.Expose;
 import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEnd;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndAfterXTimes;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndDate;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndNever;
 import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifier;
 import de.deadlocker8.budgetmaster.transactions.Transaction;
 import org.springframework.format.annotation.DateTimeFormat;
@@ -132,6 +135,35 @@ public class RepeatingOption
 		return dates;
 	}
 
+	/***
+	 * Returns whether this repeating option has ended before the given date.
+	 */
+	public boolean hasEndedBefore(LocalDate date)
+	{
+		if(endOption instanceof RepeatingEndNever)
+		{
+			return false;
+		}
+
+		if(endOption instanceof RepeatingEndDate)
+		{
+			final LocalDate endDate = (LocalDate) endOption.getValue();
+			return endDate.isBefore(date);
+		}
+
+		if(endOption instanceof RepeatingEndAfterXTimes)
+		{
+			// Use a date fetch limit far into future to really calculate all dates. The date calculation will finish
+			// as soon as the number of repetitions is reached and therefore never calculate dates until the year 3000.
+			final List<LocalDate> repeatingDates = getRepeatingDates(LocalDate.of(3000, 1, 1));
+			final LocalDate lastDate = repeatingDates.get(repeatingDates.size() - 1);
+
+			return lastDate.isBefore(date);
+		}
+
+		throw new UnsupportedOperationException("Unknown repeating end option type");
+	}
+
 	@Override
 	public String toString()
 	{
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingTransactionUpdater.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingTransactionUpdater.java
index 3f86564ea0a485e7c7da795e7319d7710b10aad2..85f3f4fcfb4e94fb4e8529dcf8fc8270de51b099 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingTransactionUpdater.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/repeating/RepeatingTransactionUpdater.java
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
+import java.util.ArrayList;
 import java.util.List;
 
 @Service
@@ -53,4 +54,24 @@ public class RepeatingTransactionUpdater
 
 		return false;
 	}
+
+	/**
+	 * Returns all repeating transactions that have not ended before the given date.
+	 */
+	public List<Transaction> getActiveRepeatingTransactionsAfter(LocalDate date)
+	{
+		final List<RepeatingOption> repeatingOptions = repeatingOptionRepository.findAllByOrderByStartDateAsc();
+		final List<RepeatingOption> activeRepeatingOptions = repeatingOptions.stream()
+				.filter(repeatingOption -> !repeatingOption.hasEndedBefore(date))
+				.toList();
+
+		final List<Transaction> activeTransactions = new ArrayList<>();
+		for(RepeatingOption repeatingOption : activeRepeatingOptions)
+		{
+			final List<Transaction> transactions = transactionService.getRepository().findAllByRepeatingOption(repeatingOption);
+			activeTransactions.add(transactions.get(0));
+		}
+
+		return activeTransactions;
+	}
 }
\ No newline at end of file
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
index 10990e1e50efd1674adab9661b331c9c55c6bc98..b26ff55c412e536a550b288584de3ac5c1bcd873 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/transactions/TransactionController.java
@@ -57,6 +57,7 @@ public class TransactionController extends BaseController
 		public static final String REDIRECT_NEW_TRANSACTION = "redirect:/transactions/newTransaction/normal";
 		public static final String NEW_TRANSACTION = "transactions/newTransactionNormal";
 		public static final String CHANGE_TYPE = "transactions/changeTypeModal";
+		public static final String RECURRING_OVERVIEW = "transactions/recurringOverview";
 	}
 
 	private static final String CONTINUE = "continue";
@@ -468,4 +469,12 @@ public class TransactionController extends BaseController
 		}
 		return ReturnValues.NEW_TRANSACTION;
 	}
+
+	@GetMapping("/recurringOverview")
+	public String recurringOverview(Model model)
+	{
+		final List<Transaction> activeRepeatingTransactions = repeatingTransactionUpdater.getActiveRepeatingTransactionsAfter(LocalDate.now());
+		model.addAttribute(TransactionModelAttributes.ALL_ENTITIES, activeRepeatingTransactions);
+		return ReturnValues.RECURRING_OVERVIEW;
+	}
 }
\ No newline at end of file
diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties
index d7a232adb9bb90afa909afe583588d3c36863615..3cf6a2132e173a0b9013270e87262c63975efe52 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_de.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties
@@ -365,6 +365,8 @@ transaction.new.label.account=Konto
 transaction.new.label.transfer.account=Zielkonto
 transaction.new.label.repeating=Wiederholung
 transaction.new.label.repeating.all=Alle
+transactions.recurring.headline=Aktive wiederholende Buchungen
+transactions.recurring.placeholder=Keine aktiven wiederholenden Buchungen
 
 repeating.button.add=Wiederholung hinzufügen
 repeating.button.remove=Wiederholung entfernen
diff --git a/BudgetMasterServer/src/main/resources/languages/base_en.properties b/BudgetMasterServer/src/main/resources/languages/base_en.properties
index b98c327d5f007700658800af9fbfb01f30f4407d..810fa857a9caee4c05c89fea29c94d4ac6dc3cac 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_en.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties
@@ -365,6 +365,8 @@ transaction.new.label.account=Account
 transaction.new.label.transfer.account=Destination Account
 transaction.new.label.repeating=Repeating
 transaction.new.label.repeating.all=Every
+transactions.recurring.headline=Active Recurring Transactions
+transactions.recurring.placeholder=No active recurring transactions
 
 repeating.button.add=Add repetition
 repeating.button.remove=Remove repetition
diff --git a/BudgetMasterServer/src/main/resources/templates/helpers/navbar.ftl b/BudgetMasterServer/src/main/resources/templates/helpers/navbar.ftl
index 3a815470e1803ba57debddb2c2e90784afd849ba..ec860d4aefeec69d5ab7b952637c6eec10a60f51 100644
--- a/BudgetMasterServer/src/main/resources/templates/helpers/navbar.ftl
+++ b/BudgetMasterServer/src/main/resources/templates/helpers/navbar.ftl
@@ -149,7 +149,7 @@
     <#if activeID == "transactions" || activeID == "templates" || activeID == "recurring">
         <li class="sub-menu <#if activeID == "transactions">active</#if>"><a href="<@s.url '${link}'/>" class="waves-effect no-padding"><div class="stripe ${activeColor}"></div><i class="material-icons">${icon}</i>${text}</a></li>
         <li class="sub-menu sub-menu-entry <#if activeID == "templates">active</#if>"><a href="<@s.url '/templates'/>" class="waves-effect no-padding"><div class="stripe ${activeColor}"></div><i class="material-icons">${entityType.TEMPLATE.getIcon()}</i>${locale.getString("menu.transactions.templates")}</a></li>
-        <li class="sub-menu sub-menu-entry <#if activeID == "recurring">active</#if>"><a href="<@s.url '/templates'/>" class="waves-effect no-padding"><div class="stripe ${activeColor}"></div><i class="material-icons">${entityType.RECURRING_TRANSACTIONS.getIcon()}</i>${locale.getString("menu.transactions.recurring")}</a></li>
+        <li class="sub-menu sub-menu-entry <#if activeID == "recurring">active</#if>"><a href="<@s.url '/transactions/recurringOverview'/>" class="waves-effect no-padding"><div class="stripe ${activeColor}"></div><i class="material-icons">${entityType.RECURRING_TRANSACTIONS.getIcon()}</i>${locale.getString("menu.transactions.recurring")}</a></li>
     <#else>
         <li><a href="<@s.url '${link}'/>" class="waves-effect"><i class="material-icons">${icon}</i>${text}</a></li>
     </#if>
diff --git a/BudgetMasterServer/src/main/resources/templates/transactions/recurringOverview.ftl b/BudgetMasterServer/src/main/resources/templates/transactions/recurringOverview.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..709632930a3ed5c916905abd28fc1149a20704e9
--- /dev/null
+++ b/BudgetMasterServer/src/main/resources/templates/transactions/recurringOverview.ftl
@@ -0,0 +1,44 @@
+<html>
+    <head>
+        <#import "../helpers/header.ftl" as header>
+        <@header.globals/>
+        <@header.header "BudgetMaster - ${locale.getString('transactions.recurring.headline')}"/>
+        <@header.style "transactions"/>
+        <@header.style "search"/>
+        <#import "/spring.ftl" as s>
+    </head>
+    <@header.body>
+        <#import "../helpers/navbar.ftl" as navbar>
+        <@navbar.navbar "recurring" settings/>
+
+        <#import "../search/searchMacros.ftl" as searchMacros>
+
+        <main>
+            <div class="card main-card background-color">
+                <div class="container">
+                    <div class="section center-align">
+                        <div class="headline">${locale.getString("transactions.recurring.headline")}</div>
+                    </div>
+                </div>
+
+                <@header.content>
+                    <#if transactions?has_content>
+                        <@searchMacros.renderTransactions transactions=transactions openLinksInNewTab=false/>
+                    <#else>
+                        <#-- show placeholde text if there are no active recurring transactions -->
+                        <br>
+                        <div class="row">
+                            <div class="col s12">
+                                <div class="headline-small center-align">${locale.getString("transactions.recurring.placeholder")}</div>
+                            </div>
+                        </div>
+                    </#if>
+                </@header.content>
+            </div>
+        </main>
+
+        <!--  Scripts-->
+        <#import "../helpers/scripts.ftl" as scripts>
+        <@scripts.scripts/>
+    </@header.body>
+</html>
\ No newline at end of file
diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
index 44e88c344a7ef1ee0a31840107feb23ff4053397..6ad5268505ae8fe7980fbd62bab78b4b9391fd2c 100644
--- a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
+++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingOptionTest.java
@@ -200,4 +200,73 @@ class RepeatingOptionTest
 		assertThat(repeatingOption.getRepeatingDates(dateFetchLimit))
 				.isEqualTo(expected);
 	}
+
+	// test hasEndedBefore()
+
+	@Test
+	void test_HasEndedBefore_EndNever()
+	{
+		LocalDate startDate = LocalDate.of(2018, 4, 22);
+		RepeatingOption repeatingOption = new RepeatingOption(startDate,
+				new RepeatingModifierDays(3),
+				new RepeatingEndNever());
+
+		LocalDate date = LocalDate.of(2018, 5, 2);
+
+		assertThat(repeatingOption.hasEndedBefore(date)).isFalse();
+	}
+
+	@Test
+	void test_HasEndedBefore_EndDate_NotEnded()
+	{
+		LocalDate startDate = LocalDate.of(2018, 4, 30);
+		LocalDate endDate = LocalDate.of(2019, 9, 28);
+		RepeatingOption repeatingOption = new RepeatingOption(startDate,
+				new RepeatingModifierYears(1),
+				new RepeatingEndDate(endDate));
+
+		LocalDate date = LocalDate.of(2018, 5, 2);
+
+		assertThat(repeatingOption.hasEndedBefore(date)).isFalse();
+	}
+
+	@Test
+	void test_HasEndedBefore_EndDate_HasEnded()
+	{
+		LocalDate startDate = LocalDate.of(2018, 4, 30);
+		LocalDate endDate = LocalDate.of(2019, 9, 28);
+		RepeatingOption repeatingOption = new RepeatingOption(startDate,
+				new RepeatingModifierYears(1),
+				new RepeatingEndDate(endDate));
+
+		LocalDate date = LocalDate.of(2019, 9, 29);
+
+		assertThat(repeatingOption.hasEndedBefore(date)).isTrue();
+	}
+
+	@Test
+	void test_HasEndedBefore_EndAfterXTimes_NotEnded()
+	{
+		LocalDate startDate = LocalDate.of(2018, 4, 30);
+		RepeatingOption repeatingOption = new RepeatingOption(startDate,
+				new RepeatingModifierYears(1),
+				new RepeatingEndAfterXTimes(2));
+
+		LocalDate date = LocalDate.of(2020, 4, 29);
+
+		assertThat(repeatingOption.hasEndedBefore(date)).isFalse();
+	}
+
+	@Test
+	void test_HasEndedBefore_EndAfterXTimes_HasEnded()
+	{
+		LocalDate startDate = LocalDate.of(2018, 4, 30);
+		RepeatingOption repeatingOption = new RepeatingOption(startDate,
+				new RepeatingModifierYears(1),
+				new RepeatingEndAfterXTimes(2));
+
+		LocalDate date = LocalDate.of(2022, 9, 29);
+
+		assertThat(repeatingOption.hasEndedBefore(date)).isTrue();
+	}
 }
\ No newline at end of file
diff --git a/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingTransactionUpdaterTest.java b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingTransactionUpdaterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6e5116205a0d4fd60b809a21a77237f21daddab
--- /dev/null
+++ b/BudgetMasterServer/src/test/java/de/deadlocker8/budgetmaster/unit/repeating/RepeatingTransactionUpdaterTest.java
@@ -0,0 +1,124 @@
+package de.deadlocker8.budgetmaster.unit.repeating;
+
+import de.deadlocker8.budgetmaster.accounts.Account;
+import de.deadlocker8.budgetmaster.accounts.AccountType;
+import de.deadlocker8.budgetmaster.repeating.RepeatingOption;
+import de.deadlocker8.budgetmaster.repeating.RepeatingOptionRepository;
+import de.deadlocker8.budgetmaster.repeating.RepeatingTransactionUpdater;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndAfterXTimes;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndDate;
+import de.deadlocker8.budgetmaster.repeating.endoption.RepeatingEndNever;
+import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierDays;
+import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierMonths;
+import de.deadlocker8.budgetmaster.repeating.modifier.RepeatingModifierYears;
+import de.deadlocker8.budgetmaster.transactions.Transaction;
+import de.deadlocker8.budgetmaster.transactions.TransactionRepository;
+import de.deadlocker8.budgetmaster.transactions.TransactionService;
+import de.deadlocker8.budgetmaster.unit.helpers.LocalizedTest;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@ExtendWith(SpringExtension.class)
+@LocalizedTest
+class RepeatingTransactionUpdaterTest
+{
+	@Mock
+	private TransactionService transactionService;
+
+	@Mock
+	private TransactionRepository transactionRepository;
+
+	@Mock
+	private RepeatingOptionRepository repeatingOptionRepository;
+
+	private Transaction TRANSACTION_1;
+	private Transaction TRANSACTION_2;
+	private Transaction TRANSACTION_3;
+	private Transaction TRANSACTION_4;
+
+	private RepeatingTransactionUpdater repeatingTransactionUpdater;
+
+	@BeforeEach
+	void beforeEach()
+	{
+		final RepeatingOption REPEATING_OPTION_END_NEVER = new RepeatingOption(LocalDate.of(2022, 12, 1),
+				new RepeatingModifierDays(3),
+				new RepeatingEndNever());
+
+		final RepeatingOption REPEATING_OPTION_END_DATE = new RepeatingOption(LocalDate.of(2022, 10, 24),
+				new RepeatingModifierMonths(1),
+				new RepeatingEndDate(LocalDate.of(2023, 2, 15)));
+
+		final RepeatingOption REPEATING_OPTION_END_AFTER_X_TIMES = new RepeatingOption(LocalDate.of(2018, 4, 30),
+				new RepeatingModifierYears(1),
+				new RepeatingEndAfterXTimes(2));
+
+		final Account account = new Account("Account", AccountType.CUSTOM);
+
+		TRANSACTION_1 = new Transaction();
+		TRANSACTION_1.setName("abc");
+		TRANSACTION_1.setAmount(700);
+		TRANSACTION_1.setAccount(account);
+		TRANSACTION_1.setIsExpenditure(true);
+		TRANSACTION_1.setRepeatingOption(REPEATING_OPTION_END_NEVER);
+		Mockito.when(transactionRepository.findAllByRepeatingOption(REPEATING_OPTION_END_NEVER)).thenReturn(List.of(TRANSACTION_1));
+
+		TRANSACTION_2 = new Transaction();
+		TRANSACTION_2.setName("Lorem");
+		TRANSACTION_2.setAmount(200);
+		TRANSACTION_2.setAccount(account);
+		TRANSACTION_2.setIsExpenditure(true);
+		TRANSACTION_2.setRepeatingOption(REPEATING_OPTION_END_DATE);
+
+		TRANSACTION_3 = new Transaction();
+		TRANSACTION_3.setName("Ipsum");
+		TRANSACTION_3.setAmount(75);
+		TRANSACTION_3.setAccount(account);
+		TRANSACTION_3.setIsExpenditure(true);
+		TRANSACTION_3.setRepeatingOption(REPEATING_OPTION_END_AFTER_X_TIMES);
+		Mockito.when(transactionRepository.findAllByRepeatingOption(REPEATING_OPTION_END_DATE)).thenReturn(List.of(TRANSACTION_2, TRANSACTION_3));
+
+		TRANSACTION_4 = new Transaction();
+		TRANSACTION_4.setName("dolor");
+		TRANSACTION_4.setAmount(50);
+		TRANSACTION_4.setAccount(account);
+		TRANSACTION_4.setIsExpenditure(true);
+		TRANSACTION_4.setRepeatingOption(REPEATING_OPTION_END_AFTER_X_TIMES);
+		Mockito.when(transactionRepository.findAllByRepeatingOption(REPEATING_OPTION_END_AFTER_X_TIMES)).thenReturn(List.of(TRANSACTION_4));
+
+		Mockito.when(transactionService.getRepository()).thenReturn(transactionRepository);
+		Mockito.when(repeatingOptionRepository.findAllByOrderByStartDateAsc()).thenReturn(List.of(REPEATING_OPTION_END_NEVER, REPEATING_OPTION_END_DATE, REPEATING_OPTION_END_AFTER_X_TIMES));
+		repeatingTransactionUpdater = new RepeatingTransactionUpdater(transactionService, repeatingOptionRepository);
+	}
+
+	@Test
+	void test_getActiveRepeatingTransactionsAfter()
+	{
+		assertThat(repeatingTransactionUpdater.getActiveRepeatingTransactionsAfter(LocalDate.of(2023, 1, 20)))
+				.containsExactly(TRANSACTION_1, TRANSACTION_2);
+	}
+
+	@Test
+	void test_getActiveRepeatingTransactionsAfter_2()
+	{
+		assertThat(repeatingTransactionUpdater.getActiveRepeatingTransactionsAfter(LocalDate.of(2017, 1, 20)))
+				.containsExactly(TRANSACTION_1, TRANSACTION_2, TRANSACTION_4);
+	}
+
+	@Test
+	void test_getActiveRepeatingTransactionsAfter_3()
+	{
+		assertThat(repeatingTransactionUpdater.getActiveRepeatingTransactionsAfter(LocalDate.of(2023, 10, 1)))
+				.containsExactly(TRANSACTION_1);
+	}
+}