diff --git a/src/components/background-service.jsx b/src/components/background-service.jsx
index 96a6bb28..0a9665c2 100644
--- a/src/components/background-service.jsx
+++ b/src/components/background-service.jsx
@@ -13,55 +13,80 @@ export default memo(function BackgroundService({ isLoggedIn }) {
   // - WebSocket to receive notifications when page is visible
   const [visible, setVisible] = useState(true);
   usePageVisibility(setVisible);
+  const checkLatestNotification = async (masto, instance, skipCheckMarkers) => {
+    if (states.notificationsLast) {
+      const notificationsIterator = masto.v1.notifications.list({
+        limit: 1,
+        sinceId: states.notificationsLast.id,
+      });
+      const { value: notifications } = await notificationsIterator.next();
+      if (notifications?.length) {
+        if (skipCheckMarkers) {
+          states.notificationsShowNew = true;
+        } else {
+          let lastReadId;
+          try {
+            const markers = await masto.v1.markers.fetch({
+              timeline: 'notifications',
+            });
+            lastReadId = markers?.notifications?.lastReadId;
+          } catch (e) {}
+          if (lastReadId) {
+            states.notificationsShowNew = notifications[0].id !== lastReadId;
+          } else {
+            states.notificationsShowNew = true;
+          }
+        }
+      }
+    }
+  };
+
   useEffect(() => {
     let sub;
+    let pollNotifications;
     if (isLoggedIn && visible) {
       const { masto, streaming, instance } = api();
       (async () => {
         // 1. Get the latest notification
-        if (states.notificationsLast) {
-          const notificationsIterator = masto.v1.notifications.list({
-            limit: 1,
-            since_id: states.notificationsLast.id,
-          });
-          const { value: notifications } = await notificationsIterator.next();
-          if (notifications?.length) {
-            let lastReadId;
-            try {
-              const markers = await masto.v1.markers.fetch({
-                timeline: 'notifications',
-              });
-              lastReadId = markers?.notifications?.lastReadId;
-            } catch (e) {}
-            if (lastReadId) {
-              states.notificationsShowNew = notifications[0].id !== lastReadId;
-            } else {
+        await checkLatestNotification(masto, instance);
+
+        let hasStreaming = false;
+        // 2. Start streaming
+        if (streaming) {
+          try {
+            hasStreaming = true;
+            sub = streaming.user.notification.subscribe();
+            console.log('🎏 Streaming notification', sub);
+            for await (const entry of sub) {
+              if (!sub) break;
+              console.log('🔔🔔 Notification entry', entry);
+              if (entry.event === 'notification') {
+                console.log('🔔🔔 Notification', entry);
+                saveStatus(entry.payload, instance, {
+                  skipThreading: true,
+                });
+              }
               states.notificationsShowNew = true;
             }
+          } catch (e) {
+            hasStreaming = false;
+            console.error(e);
           }
         }
 
-        // 2. Start streaming
-        if (streaming) {
-          sub = streaming.user.notification.subscribe();
-          console.log('🎏 Streaming notification', sub);
-          for await (const entry of sub) {
-            if (!sub) break;
-            console.log('🔔🔔 Notification entry', entry);
-            if (entry.event === 'notification') {
-              console.log('🔔🔔 Notification', entry);
-              saveStatus(entry.payload, instance, {
-                skipThreading: true,
-              });
-            }
-            states.notificationsShowNew = true;
-          }
+        if (!hasStreaming) {
+          console.log('🎏 Streaming failed, fallback to polling');
+          // Fallback to polling every minute
+          pollNotifications = setInterval(() => {
+            checkLatestNotification(masto, instance, true);
+          }, 1000 * 60);
         }
       })();
     }
     return () => {
       sub?.unsubscribe?.();
       sub = null;
+      clearInterval(pollNotifications);
     };
   }, [visible, isLoggedIn]);