diff --git a/packages/desktop-client/src/components/BankSyncStatus.tsx b/packages/desktop-client/src/components/BankSyncStatus.tsx
index f49b920074996ec221f9a588722b1555fe74ea0a..77ae6457d1fa9a36626d4798ef41086e1b78b02b 100644
--- a/packages/desktop-client/src/components/BankSyncStatus.tsx
+++ b/packages/desktop-client/src/components/BankSyncStatus.tsx
@@ -14,19 +14,17 @@ export function BankSyncStatus() {
   const accountsSyncing = useSelector(
     (state: State) => state.account.accountsSyncing,
   );
+  const accountsSyncingCount = accountsSyncing.length;
 
-  const name = accountsSyncing
-    ? accountsSyncing === '__all'
-      ? 'accounts'
-      : accountsSyncing
-    : null;
-
-  const transitions = useTransition(name, {
-    from: { opacity: 0, transform: 'translateY(-100px)' },
-    enter: { opacity: 1, transform: 'translateY(0)' },
-    leave: { opacity: 0, transform: 'translateY(-100px)' },
-    unique: true,
-  });
+  const transitions = useTransition(
+    accountsSyncingCount > 0 ? 'syncing' : null,
+    {
+      from: { opacity: 0, transform: 'translateY(-100px)' },
+      enter: { opacity: 1, transform: 'translateY(0)' },
+      leave: { opacity: 0, transform: 'translateY(-100px)' },
+      unique: true,
+    },
+  );
 
   return (
     <View
@@ -56,10 +54,13 @@ export function BankSyncStatus() {
                 }}
               >
                 <AnimatedRefresh
-                  animating={true}
+                  animating
                   iconStyle={{ color: theme.pillTextSelected }}
                 />
-                <Text>Syncing {item}</Text>
+                <Text style={{ marginLeft: 5 }}>
+                  Syncing... {accountsSyncingCount} account
+                  {accountsSyncingCount > 1 && 's'} remaining
+                </Text>
               </View>
             </animated.div>
           ),
diff --git a/packages/desktop-client/src/components/accounts/Account.jsx b/packages/desktop-client/src/components/accounts/Account.jsx
index 4db7abb7c276504b4960f69c00b6f03a7fa9b42e..62f2a7f6f11f08db927e6d1e79fd08fe160484a9 100644
--- a/packages/desktop-client/src/components/accounts/Account.jsx
+++ b/packages/desktop-client/src/components/accounts/Account.jsx
@@ -462,7 +462,7 @@ class AccountInternal extends PureComponent {
     const accountId = this.props.accountId;
     const account = this.props.accounts.find(acct => acct.id === accountId);
 
-    await this.props.syncAndDownload(account ? account.id : null);
+    await this.props.syncAndDownload(account ? account.id : undefined);
   };
 
   onImport = async () => {
diff --git a/packages/desktop-client/src/components/accounts/Header.jsx b/packages/desktop-client/src/components/accounts/Header.jsx
index eaade96bfb2b47eca427bad29cfff0c611f42a5d..93cd451150303e1301424f294e9e94f6a0d10ee2 100644
--- a/packages/desktop-client/src/components/accounts/Header.jsx
+++ b/packages/desktop-client/src/components/accounts/Header.jsx
@@ -232,8 +232,9 @@ export function AccountHeader({
                     width={13}
                     height={13}
                     animating={
-                      (account && accountsSyncing === account.name) ||
-                      accountsSyncing === '__all'
+                      account
+                        ? accountsSyncing.includes(account.id)
+                        : accountsSyncing.length > 0
                     }
                     style={{ marginRight: 4 }}
                   />{' '}
diff --git a/packages/desktop-client/src/components/sidebar/Account.tsx b/packages/desktop-client/src/components/sidebar/Account.tsx
index 3cd28ba2e61bc07fc804bd5d14f48c0875e52fa9..2c232a73a14ee216be3f6534943f16fec4b4a558 100644
--- a/packages/desktop-client/src/components/sidebar/Account.tsx
+++ b/packages/desktop-client/src/components/sidebar/Account.tsx
@@ -38,6 +38,7 @@ type AccountProps = {
   query: Binding;
   account?: AccountEntity;
   connected?: boolean;
+  pending?: boolean;
   failed?: boolean;
   updated?: boolean;
   style?: CSSProperties;
@@ -50,6 +51,7 @@ export function Account({
   name,
   account,
   connected,
+  pending = false,
   failed,
   updated,
   to,
@@ -125,9 +127,11 @@ export function Account({
                   width: 5,
                   height: 5,
                   borderRadius: 5,
-                  backgroundColor: failed
-                    ? theme.sidebarItemBackgroundFailed
-                    : theme.sidebarItemBackgroundPositive,
+                  backgroundColor: pending
+                    ? theme.sidebarItemBackgroundPending
+                    : failed
+                      ? theme.sidebarItemBackgroundFailed
+                      : theme.sidebarItemBackgroundPositive,
                   marginLeft: 2,
                   transition: 'transform .3s',
                   opacity: connected ? 1 : 0,
diff --git a/packages/desktop-client/src/components/sidebar/Accounts.tsx b/packages/desktop-client/src/components/sidebar/Accounts.tsx
index e85e32e4a193508811955b8527b38d6e45988bc6..d85cb537bd7f9487dd6e72036f6ed2b66bd8afa6 100644
--- a/packages/desktop-client/src/components/sidebar/Accounts.tsx
+++ b/packages/desktop-client/src/components/sidebar/Accounts.tsx
@@ -1,7 +1,9 @@
 // @ts-strict-ignore
 import React, { useState } from 'react';
+import { useSelector } from 'react-redux';
 
 import * as queries from 'loot-core/src/client/queries';
+import { type State } from 'loot-core/src/client/state-types';
 
 import { useBudgetedAccounts } from '../../hooks/useBudgetedAccounts';
 import { useClosedAccounts } from '../../hooks/useClosedAccounts';
@@ -35,6 +37,9 @@ export function Accounts({
   const offbudgetAccounts = useOffBudgetAccounts();
   const budgetedAccounts = useBudgetedAccounts();
   const closedAccounts = useClosedAccounts();
+  const syncingAccountIds = useSelector(
+    (state: State) => state.account.accountsSyncing,
+  );
 
   const getAccountPath = account => `/accounts/${account.id}`;
 
@@ -78,6 +83,7 @@ export function Accounts({
           name={account.name}
           account={account}
           connected={!!account.bank}
+          pending={syncingAccountIds.includes(account.id)}
           failed={failedAccounts && failedAccounts.has(account.id)}
           updated={updatedAccounts && updatedAccounts.includes(account.id)}
           to={getAccountPath(account)}
@@ -103,6 +109,7 @@ export function Accounts({
           name={account.name}
           account={account}
           connected={!!account.bank}
+          pending={syncingAccountIds.includes(account.id)}
           failed={failedAccounts && failedAccounts.has(account.id)}
           updated={updatedAccounts && updatedAccounts.includes(account.id)}
           to={getAccountPath(account)}
diff --git a/packages/desktop-client/src/style/themes/dark.ts b/packages/desktop-client/src/style/themes/dark.ts
index a2a2f3526c66d10fa6617b25c26060e87e3bd463..4d2800587ecebdf43b6cf50ea17683ccee22bc22 100644
--- a/packages/desktop-client/src/style/themes/dark.ts
+++ b/packages/desktop-client/src/style/themes/dark.ts
@@ -39,6 +39,7 @@ export const tableRowHeaderBackground = colorPalette.navy700;
 export const tableRowHeaderText = colorPalette.navy150;
 
 export const sidebarBackground = colorPalette.navy900;
+export const sidebarItemBackgroundPending = colorPalette.orange200;
 export const sidebarItemBackgroundPositive = colorPalette.green500;
 export const sidebarItemBackgroundFailed = colorPalette.red300;
 export const sidebarItemAccentSelected = colorPalette.purple200;
diff --git a/packages/desktop-client/src/style/themes/development.ts b/packages/desktop-client/src/style/themes/development.ts
index 68e190b6b69e7f9f87c009cb89fb8dd78caf7972..9ce9db8795d6a48a0aeb34963290b2439a5525d8 100644
--- a/packages/desktop-client/src/style/themes/development.ts
+++ b/packages/desktop-client/src/style/themes/development.ts
@@ -39,6 +39,7 @@ export const tableRowHeaderBackground = colorPalette.navy50;
 export const tableRowHeaderText = colorPalette.navy800;
 
 export const sidebarBackground = colorPalette.navy900;
+export const sidebarItemBackgroundPending = colorPalette.orange200;
 export const sidebarItemBackgroundPositive = colorPalette.green500;
 export const sidebarItemBackgroundFailed = colorPalette.red300;
 export const sidebarItemBackgroundHover = colorPalette.navy800;
diff --git a/packages/desktop-client/src/style/themes/light.ts b/packages/desktop-client/src/style/themes/light.ts
index a442f746a0f54a20ff3da7c1672ef5361ae78c29..124bb671e28308ec262e1d3f6e4565c182de40d9 100644
--- a/packages/desktop-client/src/style/themes/light.ts
+++ b/packages/desktop-client/src/style/themes/light.ts
@@ -39,6 +39,7 @@ export const tableRowHeaderBackground = colorPalette.navy50;
 export const tableRowHeaderText = colorPalette.navy800;
 
 export const sidebarBackground = colorPalette.navy900;
+export const sidebarItemBackgroundPending = colorPalette.orange200;
 export const sidebarItemBackgroundPositive = colorPalette.green500;
 export const sidebarItemBackgroundFailed = colorPalette.red300;
 export const sidebarItemBackgroundHover = colorPalette.navy800;
diff --git a/packages/desktop-client/src/style/themes/midnight.ts b/packages/desktop-client/src/style/themes/midnight.ts
index 6e6dea4bda1ebc83bcfbc8afc6c0794e9a3baf22..1fc41c202cdf240c171a5ca3238ff857a877f06a 100644
--- a/packages/desktop-client/src/style/themes/midnight.ts
+++ b/packages/desktop-client/src/style/themes/midnight.ts
@@ -39,6 +39,7 @@ export const tableRowHeaderBackground = colorPalette.gray700;
 export const tableRowHeaderText = colorPalette.gray150;
 
 export const sidebarBackground = colorPalette.gray900;
+export const sidebarItemBackgroundPending = colorPalette.orange200;
 export const sidebarItemBackgroundPositive = colorPalette.green400;
 export const sidebarItemBackgroundFailed = colorPalette.red300;
 export const sidebarItemAccentSelected = colorPalette.purple200;
diff --git a/packages/loot-core/src/client/actions/account.ts b/packages/loot-core/src/client/actions/account.ts
index e7f7f269b4b2d67fab7208cf71808e63d2b3a215..f6448ce9e56a799e16016b231a72ea1fc834f79f 100644
--- a/packages/loot-core/src/client/actions/account.ts
+++ b/packages/loot-core/src/client/actions/account.ts
@@ -2,7 +2,6 @@
 import { send } from '../../platform/client/fetch';
 import * as constants from '../constants';
 import type {
-  AccountSyncFailuresAction,
   AccountSyncStatusAction,
   SetAccountsSyncingAction,
 } from '../state-types/account';
@@ -17,11 +16,11 @@ import { getPayees, getAccounts } from './queries';
 import type { Dispatch, GetState } from './types';
 
 export function setAccountsSyncing(
-  name: SetAccountsSyncingAction['name'],
+  ids: SetAccountsSyncingAction['ids'],
 ): SetAccountsSyncingAction {
   return {
     type: constants.SET_ACCOUNTS_SYNCING,
-    name,
+    ids,
   };
 }
 
@@ -47,14 +46,6 @@ export function markAccountSuccess(
     failed: false,
   };
 }
-export function setFailedAccounts(
-  syncErrors: AccountSyncFailuresAction['syncErrors'],
-): AccountSyncFailuresAction {
-  return {
-    type: constants.ACCOUNT_SYNC_FAILURES,
-    syncErrors,
-  };
-}
 
 export function unlinkAccount(id: string) {
   return async (dispatch: Dispatch) => {
@@ -107,96 +98,89 @@ export function connectAccounts(
   };
 }
 
-// TODO: type correctly or remove (unused)
-export function connectGoCardlessAccounts(
-  institution,
-  publicToken,
-  accountIds,
-  offbudgetIds,
-) {
-  return async (dispatch: Dispatch) => {
-    const ids = await send('gocardless-accounts-connect', {
-      institution,
-      publicToken,
-      accountIds,
-      offbudgetIds,
-    });
-    await dispatch(getPayees());
-    await dispatch(getAccounts());
-    return ids;
-  };
-}
-
-export function syncAccounts(id: string) {
+export function syncAccounts(id?: string) {
   return async (dispatch: Dispatch, getState: GetState) => {
-    if (getState().account.accountsSyncing) {
+    // Disallow two parallel sync operations
+    if (getState().account.accountsSyncing.length > 0) {
       return false;
     }
 
-    if (id) {
-      const account = getState().queries.accounts.find(a => a.id === id);
-      dispatch(setAccountsSyncing(account.name));
-    } else {
-      dispatch(setAccountsSyncing('__all'));
-    }
+    // Build an array of IDs for accounts to sync.. if no `id` provided
+    // then we assume that all accounts should be synced
+    const accountIdsToSync = id
+      ? [id]
+      : getState()
+          .queries.accounts.filter(
+            ({ bank, closed, tombstone }) => !!bank && !closed && !tombstone,
+          )
+          .map(({ id }) => id);
+
+    dispatch(setAccountsSyncing(accountIdsToSync));
 
-    const { errors, newTransactions, matchedTransactions, updatedAccounts } =
-      await send('gocardless-accounts-sync', { id });
-    dispatch(setAccountsSyncing(null));
+    let isSyncSuccess = false;
 
-    if (id) {
-      const error = errors.find(error => error.accountId === id);
+    // Loop through the accounts and perform sync operation.. one by one
+    for (let idx = 0; idx < accountIdsToSync.length; idx++) {
+      const accountId = accountIdsToSync[idx];
 
+      // Perform sync operation
+      const { errors, newTransactions, matchedTransactions, updatedAccounts } =
+        await send('gocardless-accounts-sync', {
+          id: accountId,
+        });
+
+      // Mark the account as failed or succeeded (depending on sync output)
+      const [error] = errors;
       if (error) {
         // We only want to mark the account as having problem if it
         // was a real syncing error.
         if (error.type === 'SyncError') {
-          dispatch(markAccountFailed(id, error.category, error.code));
+          dispatch(markAccountFailed(accountId, error.category, error.code));
         }
       } else {
-        dispatch(markAccountSuccess(id));
+        dispatch(markAccountSuccess(accountId));
       }
-    } else {
-      dispatch(
-        setFailedAccounts(
-          errors
-            .filter(error => error.type === 'SyncError')
-            .map(error => ({
-              id: error.accountId,
-              type: error.category,
-              code: error.code,
-            })),
-        ),
-      );
-    }
 
-    errors.forEach(error => {
-      if (error.type === 'SyncError') {
-        dispatch(
-          addNotification({
-            type: 'error',
-            message: error.message,
-          }),
-        );
-      } else {
-        dispatch(
-          addNotification({
-            type: 'error',
-            message: error.message,
-            internal: error.internal,
-          }),
-        );
-      }
-    });
+      // Dispatch errors (if any)
+      errors.forEach(error => {
+        if (error.type === 'SyncError') {
+          dispatch(
+            addNotification({
+              type: 'error',
+              message: error.message,
+            }),
+          );
+        } else {
+          dispatch(
+            addNotification({
+              type: 'error',
+              message: error.message,
+              internal: error.internal,
+            }),
+          );
+        }
+      });
 
-    dispatch({
-      type: constants.SET_NEW_TRANSACTIONS,
-      newTransactions,
-      matchedTransactions,
-      updatedAccounts,
-    });
+      // Set new transactions
+      dispatch({
+        type: constants.SET_NEW_TRANSACTIONS,
+        newTransactions,
+        matchedTransactions,
+        updatedAccounts,
+      });
+
+      // Dispatch the ids for the accounts that are yet to be synced
+      dispatch(setAccountsSyncing(accountIdsToSync.slice(idx + 1)));
+
+      if (newTransactions.length > 0 || matchedTransactions.length > 0) {
+        isSyncSuccess = true;
+      }
+    }
 
-    return newTransactions.length > 0 || matchedTransactions.length > 0;
+    // Rest the sync state back to empty (fallback in case something breaks
+    // in the logic above)
+    dispatch(setAccountsSyncing([]));
+    return isSyncSuccess;
   };
 }
 
diff --git a/packages/loot-core/src/client/actions/sync.ts b/packages/loot-core/src/client/actions/sync.ts
index 94aa3f7db065b4d8a5593a32a75bcacd8833815b..77838897fca7c6b88336b1d82c8a96d907d84274 100644
--- a/packages/loot-core/src/client/actions/sync.ts
+++ b/packages/loot-core/src/client/actions/sync.ts
@@ -50,7 +50,7 @@ export function sync() {
   };
 }
 
-export function syncAndDownload(accountId) {
+export function syncAndDownload(accountId?: string) {
   return async (dispatch: Dispatch) => {
     // It is *critical* that we sync first because of transaction
     // reconciliation. We want to get all transactions that other
diff --git a/packages/loot-core/src/client/constants.ts b/packages/loot-core/src/client/constants.ts
index c107dea1c823b106d38e4b92193624e126c7e389..03f0e5786307e1f4b9274d71658f5de67026d13b 100644
--- a/packages/loot-core/src/client/constants.ts
+++ b/packages/loot-core/src/client/constants.ts
@@ -26,5 +26,4 @@ export const SET_LAST_UNDO_STATE = 'SET_LAST_UNDO_STATE';
 export const SET_LAST_SPLIT_STATE = 'SET_LAST_SPLIT_STATE';
 export const SET_ACCOUNTS_SYNCING = 'SET_ACCOUNTS_SYNCING';
 export const ACCOUNT_SYNC_STATUS = 'ACCOUNT_SYNC_STATUS';
-export const ACCOUNT_SYNC_FAILURES = 'ACCOUNT_SYNC_FAILURES';
 export const SIGN_OUT = 'SIGN_OUT';
diff --git a/packages/loot-core/src/client/reducers/account.ts b/packages/loot-core/src/client/reducers/account.ts
index 7c36ee5f73c4a245083574251616da0e616a292c..37387c5e52b1816f14a426da828fb2a1393753ef 100644
--- a/packages/loot-core/src/client/reducers/account.ts
+++ b/packages/loot-core/src/client/reducers/account.ts
@@ -4,7 +4,7 @@ import type { AccountState } from '../state-types/account';
 
 const initialState: AccountState = {
   failedAccounts: new Map(),
-  accountsSyncing: null,
+  accountsSyncing: [],
 };
 
 export function update(state = initialState, action: Action): AccountState {
@@ -12,7 +12,7 @@ export function update(state = initialState, action: Action): AccountState {
     case constants.SET_ACCOUNTS_SYNCING:
       return {
         ...state,
-        accountsSyncing: action.name,
+        accountsSyncing: action.ids,
       };
     case constants.ACCOUNT_SYNC_STATUS: {
       const failedAccounts = new Map(state.failedAccounts);
@@ -27,17 +27,6 @@ export function update(state = initialState, action: Action): AccountState {
 
       return { ...state, failedAccounts };
     }
-    case constants.ACCOUNT_SYNC_FAILURES: {
-      const failures = new Map();
-      action.syncErrors.forEach(error => {
-        failures.set(error.id, {
-          type: error.type,
-          code: error.code,
-        });
-      });
-
-      return { ...state, failedAccounts: failures };
-    }
     default:
   }
   return state;
diff --git a/packages/loot-core/src/client/state-types/account.d.ts b/packages/loot-core/src/client/state-types/account.d.ts
index 2b119bc271427c8d60e81e020d4f501f30cf1e33..5abad2a6df2d3f87a849f32472114b7faaade6d3 100644
--- a/packages/loot-core/src/client/state-types/account.d.ts
+++ b/packages/loot-core/src/client/state-types/account.d.ts
@@ -2,12 +2,12 @@ import type * as constants from '../constants';
 
 export type AccountState = {
   failedAccounts: Map<string, { type: string; code: string }>;
-  accountsSyncing: string | null;
+  accountsSyncing: string[];
 };
 
 export type SetAccountsSyncingAction = {
   type: typeof constants.SET_ACCOUNTS_SYNCING;
-  name: string | null;
+  ids: string[];
 };
 
 export type AccountSyncStatusAction = {
@@ -24,16 +24,4 @@ export type AccountSyncStatusAction = {
     }
 );
 
-export type AccountSyncFailuresAction = {
-  type: typeof constants.ACCOUNT_SYNC_FAILURES;
-  syncErrors: Array<{
-    id: string;
-    type: string;
-    code: string;
-  }>;
-};
-
-export type AccountActions =
-  | SetAccountsSyncingAction
-  | AccountSyncStatusAction
-  | AccountSyncFailuresAction;
+export type AccountActions = SetAccountsSyncingAction | AccountSyncStatusAction;
diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts
index 21c3b7420e8b4c13929bbe4f376d343cb0bea7ee..64cd29938bb685dfb44ffe9b9e33d6400a2dbb06 100644
--- a/packages/loot-core/src/server/main.ts
+++ b/packages/loot-core/src/server/main.ts
@@ -1266,18 +1266,14 @@ handlers['gocardless-accounts-sync'] = async function ({ id }) {
     'user-id',
     'user-key',
   ]);
-  let accounts = await db.runQuery(
+  const accounts = await db.runQuery(
     `SELECT a.*, b.bank_id as bankId FROM accounts a
          LEFT JOIN banks b ON a.bank = b.id
-         WHERE a.tombstone = 0 AND a.closed = 0`,
-    [],
+         WHERE a.tombstone = 0 AND a.closed = 0 AND a.id = ?`,
+    [id],
     true,
   );
 
-  if (id) {
-    accounts = accounts.filter(acct => acct.id === id);
-  }
-
   const errors = [];
   let newTransactions = [];
   let matchedTransactions = [];
diff --git a/packages/loot-core/src/types/server-handlers.d.ts b/packages/loot-core/src/types/server-handlers.d.ts
index 1883a36ccac11d502f297d4a129cc3c2d6afda57..eff46e2f601878126b45d7d7a4c1b3b5e5a7d2c0 100644
--- a/packages/loot-core/src/types/server-handlers.d.ts
+++ b/packages/loot-core/src/types/server-handlers.d.ts
@@ -246,7 +246,7 @@ export interface ServerHandlers {
     | { error: 'failed' }
   >;
 
-  'gocardless-accounts-sync': (arg: { id }) => Promise<{
+  'gocardless-accounts-sync': (arg: { id: string }) => Promise<{
     errors;
     newTransactions;
     matchedTransactions;
diff --git a/upcoming-release-notes/2416.md b/upcoming-release-notes/2416.md
new file mode 100644
index 0000000000000000000000000000000000000000..eb28989aa2427afee5a47734c4f909d8c3646e79
--- /dev/null
+++ b/upcoming-release-notes/2416.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [MatissJanis]
+---
+
+Bank sync quality of life improvements: show "pending" status on accounts, progressively import new transactions instead of waiting for all account sync to finish before adding them to the ledger.