diff --git a/src/components/Search/FilterDropdowns/UserSelectPopup.tsx b/src/components/Search/FilterDropdowns/UserSelectPopup.tsx
index 56ecb8d4fcb4..36111245a3f0 100644
--- a/src/components/Search/FilterDropdowns/UserSelectPopup.tsx
+++ b/src/components/Search/FilterDropdowns/UserSelectPopup.tsx
@@ -12,6 +12,7 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
 import useWindowDimensions from '@hooks/useWindowDimensions';
 import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
+import memoize from '@libs/memoize';
 import type {Option, Section} from '@libs/OptionsListUtils';
 import {filterAndOrderOptions, getValidOptions} from '@libs/OptionsListUtils';
 import type {OptionData} from '@libs/ReportUtils';
@@ -22,6 +23,8 @@ function getSelectedOptionData(option: Option) {
     return {...option, reportID: `${option.reportID}`, selected: true};
 }
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'UserSelectPopup.getValidOptions'});
+
 type UserSelectPopupProps = {
     /** The currently selected users */
     value: string[];
@@ -63,28 +66,29 @@ function UserSelectPopup({value, closeOverlay, onChange}: UserSelectPopupProps)
 
     const cleanSearchTerm = searchTerm.trim().toLowerCase();
 
-    // Get a list of all options/personal details and filter them by the current search term
-    const listData = useMemo(() => {
-        const optionsList = getValidOptions(
+    const optionsList = useMemo(() => {
+        return memoizedGetValidOptions(
             {
                 reports: options.reports,
                 personalDetails: options.personalDetails,
             },
             {
-                selectedOptions,
                 excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT,
-                includeSelectedOptions: true,
                 includeCurrentUser: true,
             },
         );
+    }, [options.reports, options.personalDetails]);
 
-        const {personalDetails: filteredOptionsList, recentReports} = filterAndOrderOptions(optionsList, cleanSearchTerm, {
+    const filteredOptions = useMemo(() => {
+        return filterAndOrderOptions(optionsList, cleanSearchTerm, {
             excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT,
             maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW,
             canInviteUser: false,
         });
+    }, [optionsList, cleanSearchTerm]);
 
-        const personalDetailList = filteredOptionsList
+    const listData = useMemo(() => {
+        const personalDetailList = filteredOptions.personalDetails
             .map((participant) => ({
                 ...participant,
                 isSelected: selectedOptions.some((selectedOption) => selectedOption.accountID === participant.accountID),
@@ -100,8 +104,16 @@ function UserSelectPopup({value, closeOverlay, onChange}: UserSelectPopupProps)
                 return 0;
             });
 
-        return [...(personalDetailList ?? []), ...(recentReports ?? [])];
-    }, [cleanSearchTerm, options.personalDetails, options.reports, selectedOptions, accountID]);
+        const recentReportsList = filteredOptions.recentReports.map((report) => {
+            const isSelected = selectedOptions.some((selectedOption) => selectedOption.reportID === report.reportID);
+            return {
+                ...report,
+                isSelected,
+            };
+        });
+
+        return [...personalDetailList, ...recentReportsList];
+    }, [filteredOptions, selectedOptions, accountID]);
 
     const {sections, headerMessage} = useMemo(() => {
         const newSections: Section[] = [
diff --git a/src/components/Search/SearchFiltersParticipantsSelector.tsx b/src/components/Search/SearchFiltersParticipantsSelector.tsx
index ea26d2134a9a..ca447b7e26ab 100644
--- a/src/components/Search/SearchFiltersParticipantsSelector.tsx
+++ b/src/components/Search/SearchFiltersParticipantsSelector.tsx
@@ -7,7 +7,8 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useScreenWrapperTransitionStatus from '@hooks/useScreenWrapperTransitionStatus';
 import {canUseTouchScreen} from '@libs/DeviceCapabilities';
-import {filterAndOrderOptions, formatSectionsFromSearchTerm, getValidOptions} from '@libs/OptionsListUtils';
+import memoize from '@libs/memoize';
+import {filterAndOrderOptions, filterSelectedOptions, formatSectionsFromSearchTerm, getValidOptions} from '@libs/OptionsListUtils';
 import type {Option, Section} from '@libs/OptionsListUtils';
 import type {OptionData} from '@libs/ReportUtils';
 import {getDisplayNameForParticipant} from '@libs/ReportUtils';
@@ -25,6 +26,8 @@ const defaultListOptions = {
     headerMessage: '',
 };
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'SearchFiltersParticipantsSelector.getValidOptions'});
+
 function getSelectedOptionData(option: Option): OptionData {
     // eslint-disable-next-line rulesdir/no-default-id-values
     return {...option, selected: true, reportID: option.reportID ?? '-1'};
@@ -53,26 +56,29 @@ function SearchFiltersParticipantsSelector({initialAccountIDs, onFiltersUpdate}:
             return defaultListOptions;
         }
 
-        return getValidOptions(
+        return memoizedGetValidOptions(
             {
                 reports: options.reports,
                 personalDetails: options.personalDetails,
             },
             {
-                selectedOptions,
                 excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT,
             },
         );
-    }, [areOptionsInitialized, options.personalDetails, options.reports, selectedOptions]);
+    }, [areOptionsInitialized, options.personalDetails, options.reports]);
+
+    const unselectedOptions = useMemo(() => {
+        return filterSelectedOptions(defaultOptions, new Set(selectedOptions.map((option) => option.accountID)));
+    }, [defaultOptions, selectedOptions]);
 
     const chatOptions = useMemo(() => {
-        return filterAndOrderOptions(defaultOptions, cleanSearchTerm, {
+        return filterAndOrderOptions(unselectedOptions, cleanSearchTerm, {
             selectedOptions,
             excludeLogins: CONST.EXPENSIFY_EMAILS_OBJECT,
             maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW,
             canInviteUser: false,
         });
-    }, [defaultOptions, cleanSearchTerm, selectedOptions]);
+    }, [unselectedOptions, cleanSearchTerm, selectedOptions]);
 
     const {sections, headerMessage} = useMemo(() => {
         const newSections: Section[] = [];
diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts
index 7001c9fbcd6c..2b9ac2de089b 100644
--- a/src/libs/OptionsListUtils.ts
+++ b/src/libs/OptionsListUtils.ts
@@ -2572,6 +2572,21 @@ function filterAndOrderOptions(options: Options, searchInputValue: string, confi
     };
 }
 
+/**
+ * Filter out selected options from personal details and recent reports
+ * @param options - The options to filter
+ * @param selectedOptions - The selected options to filter out.
+ * @returns The filtered options
+ */
+function filterSelectedOptions(options: Options, selectedOptions: Set<number | undefined>): Options {
+    const filteredOptions = {
+        ...options,
+        personalDetails: options.personalDetails.filter(({accountID}) => !selectedOptions.has(accountID)),
+        recentReports: options.recentReports.filter(({accountID}) => !selectedOptions.has(accountID)),
+    };
+    return filteredOptions;
+}
+
 function sortAlphabetically<T extends Partial<Record<TKey, string | undefined>>, TKey extends keyof T>(items: T[], key: TKey): T[] {
     return items.sort((a, b) => localeCompare(a[key]?.toLowerCase() ?? '', b[key]?.toLowerCase() ?? ''));
 }
@@ -2681,6 +2696,7 @@ export {
     shallowOptionsListCompare,
     optionsOrderBy,
     recentReportComparator,
+    filterSelectedOptions,
 };
 
 export type {Section, SectionBase, MemberForList, Options, OptionList, SearchOption, Option, OptionTree, ReportAndPersonalDetailOptions};
diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx
index 06b83b0d9e5b..99e105ef99fb 100755
--- a/src/pages/NewChatPage.tsx
+++ b/src/pages/NewChatPage.tsx
@@ -23,10 +23,12 @@ import useThemeStyles from '@hooks/useThemeStyles';
 import {navigateToAndOpenReport, searchInServer, setGroupDraft} from '@libs/actions/Report';
 import {canUseTouchScreen} from '@libs/DeviceCapabilities';
 import Log from '@libs/Log';
+import memoize from '@libs/memoize';
 import Navigation from '@libs/Navigation/Navigation';
 import type {Option, Section} from '@libs/OptionsListUtils';
 import {
     filterAndOrderOptions,
+    filterSelectedOptions,
     formatSectionsFromSearchTerm,
     getFirstKeyForList,
     getHeaderMessage,
@@ -49,6 +51,8 @@ type SelectedOption = ListItem &
         reportID?: string;
     };
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'NewChatPage.getValidOptions'});
+
 function useOptions() {
     const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');
     const [selectedOptions, setSelectedOptions] = useState<SelectedOption[]>([]);
@@ -61,28 +65,29 @@ function useOptions() {
     });
 
     const defaultOptions = useMemo(() => {
-        const filteredOptions = getValidOptions(
+        const filteredOptions = memoizedGetValidOptions(
             {
                 reports: listOptions.reports ?? [],
                 personalDetails: listOptions.personalDetails ?? [],
             },
             {
                 betas: betas ?? [],
-                selectedOptions,
                 includeSelfDM: true,
             },
         );
         return filteredOptions;
-    }, [betas, listOptions.personalDetails, listOptions.reports, selectedOptions]);
+    }, [betas, listOptions.personalDetails, listOptions.reports]);
+
+    const unselectedOptions = useMemo(() => filterSelectedOptions(defaultOptions, new Set(selectedOptions.map(({accountID}) => accountID))), [defaultOptions, selectedOptions]);
 
     const options = useMemo(() => {
-        const filteredOptions = filterAndOrderOptions(defaultOptions, debouncedSearchTerm, {
+        const filteredOptions = filterAndOrderOptions(unselectedOptions, debouncedSearchTerm, {
             selectedOptions,
             maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW,
         });
 
         return filteredOptions;
-    }, [debouncedSearchTerm, defaultOptions, selectedOptions]);
+    }, [debouncedSearchTerm, unselectedOptions, selectedOptions]);
     const cleanSearchTerm = useMemo(() => debouncedSearchTerm.trim().toLowerCase(), [debouncedSearchTerm]);
     const headerMessage = useMemo(() => {
         return getHeaderMessage(
diff --git a/src/pages/iou/request/MoneyRequestAccountantSelector.tsx b/src/pages/iou/request/MoneyRequestAccountantSelector.tsx
index 107a2de8a306..9e36005750ea 100644
--- a/src/pages/iou/request/MoneyRequestAccountantSelector.tsx
+++ b/src/pages/iou/request/MoneyRequestAccountantSelector.tsx
@@ -12,6 +12,7 @@ import useNetwork from '@hooks/useNetwork';
 import useOnyx from '@hooks/useOnyx';
 import useScreenWrapperTransitionStatus from '@hooks/useScreenWrapperTransitionStatus';
 import {canUseTouchScreen} from '@libs/DeviceCapabilities';
+import memoize from '@libs/memoize';
 import type {Section} from '@libs/OptionsListUtils';
 import {
     filterAndOrderOptions,
@@ -30,6 +31,8 @@ import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type {Accountant} from '@src/types/onyx/IOU';
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'MoneyRequestAccountantSelector.getValidOptions'});
+
 type MoneyRequestAccountantSelectorProps = {
     /** Callback to request parent modal to go to next step */
     onFinish: (value?: string) => void;
@@ -66,7 +69,7 @@ function MoneyRequestAccountantSelector({onFinish, onAccountantSelected, iouType
             getEmptyOptions();
         }
 
-        const optionList = getValidOptions(
+        const optionList = memoizedGetValidOptions(
             {
                 reports: options.reports,
                 personalDetails: options.personalDetails,
diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx
index 9783c6423e4a..bcd8cacbb92e 100644
--- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx
+++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx
@@ -35,6 +35,7 @@ import {canUseTouchScreen} from '@libs/DeviceCapabilities';
 import getPlatform from '@libs/getPlatform';
 import goToSettings from '@libs/goToSettings';
 import {isMovingTransactionFromTrackExpense} from '@libs/IOUUtils';
+import memoize from '@libs/memoize';
 import Navigation from '@libs/Navigation/Navigation';
 import type {Option, SearchOption, Section} from '@libs/OptionsListUtils';
 import {
@@ -63,6 +64,8 @@ import type {Participant} from '@src/types/onyx/IOU';
 import {isEmptyObject} from '@src/types/utils/EmptyObject';
 import ImportContactButton from './ImportContactButton';
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'MoneyRequestParticipantsSelector.getValidOptions'});
+
 type MoneyRequestParticipantsSelectorProps = {
     /** Callback to request parent modal to go to next step, which should be split */
     onFinish?: (value?: string) => void;
@@ -168,7 +171,7 @@ function MoneyRequestParticipantsSelector(
             };
         }
 
-        const optionList = getValidOptions(
+        const optionList = memoizedGetValidOptions(
             {
                 reports: options.reports,
                 personalDetails: options.personalDetails.concat(contacts),
diff --git a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
index 84e606a931aa..54828fe79d23 100644
--- a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
@@ -12,6 +12,7 @@ import useLocalize from '@hooks/useLocalize';
 import useOnyx from '@hooks/useOnyx';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {searchInServer} from '@libs/actions/Report';
+import memoize from '@libs/memoize';
 import Navigation from '@libs/Navigation/Navigation';
 import {filterAndOrderOptions, getHeaderMessage, getValidOptions} from '@libs/OptionsListUtils';
 import CONST from '@src/CONST';
@@ -19,6 +20,8 @@ import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
 import type {Participant} from '@src/types/onyx/IOU';
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'AddDelegatePage.getValidOptions'});
+
 function useOptions() {
     const betas = useBetas();
     const [isLoading, setIsLoading] = useState(true);
@@ -39,7 +42,7 @@ function useOptions() {
     );
 
     const defaultOptions = useMemo(() => {
-        const {recentReports, personalDetails, userToInvite, currentUserOption} = getValidOptions(
+        const {recentReports, personalDetails, userToInvite, currentUserOption} = memoizedGetValidOptions(
             {
                 reports: optionsList.reports,
                 personalDetails: optionsList.personalDetails,
diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.tsx b/src/pages/tasks/TaskAssigneeSelectorModal.tsx
index d3d633875197..d347ba1d28a6 100644
--- a/src/pages/tasks/TaskAssigneeSelectorModal.tsx
+++ b/src/pages/tasks/TaskAssigneeSelectorModal.tsx
@@ -23,6 +23,7 @@ import {searchInServer} from '@libs/actions/Report';
 import {canModifyTask, editTaskAssignee, setAssigneeValue} from '@libs/actions/Task';
 import {READ_COMMANDS} from '@libs/API/types';
 import HttpUtils from '@libs/HttpUtils';
+import memoize from '@libs/memoize';
 import Navigation from '@libs/Navigation/Navigation';
 import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
 import {filterAndOrderOptions, getHeaderMessage, getValidOptions, isCurrentUser} from '@libs/OptionsListUtils';
@@ -34,6 +35,8 @@ import ROUTES from '@src/ROUTES';
 import type SCREENS from '@src/SCREENS';
 import type {Report} from '@src/types/onyx';
 
+const memoizedGetValidOptions = memoize(getValidOptions, {maxSize: 5, monitoringName: 'TaskAssigneeSelectorModal.getValidOptions'});
+
 function useOptions() {
     const betas = useBetas();
     const [isLoading, setIsLoading] = useState(true);
@@ -41,7 +44,7 @@ function useOptions() {
     const {options: optionsList, areOptionsInitialized} = useOptionsList();
 
     const defaultOptions = useMemo(() => {
-        const {recentReports, personalDetails, userToInvite, currentUserOption} = getValidOptions(
+        const {recentReports, personalDetails, userToInvite, currentUserOption} = memoizedGetValidOptions(
             {
                 reports: optionsList.reports,
                 personalDetails: optionsList.personalDetails,
