diff --git a/homeassistant/components/netatmo/data_handler.py b/homeassistant/components/netatmo/data_handler.py
index e1d100f773e7183449ef85401e3ac6465a95baf3..d132fc16c7d1a692c45ed443a4c445fc8cf7ac17 100644
--- a/homeassistant/components/netatmo/data_handler.py
+++ b/homeassistant/components/netatmo/data_handler.py
@@ -17,6 +17,7 @@ from pyatmo.modules.device_types import (
     DeviceType as NetatmoDeviceType,
 )
 
+from homeassistant.components import cloud
 from homeassistant.config_entries import ConfigEntry
 from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
 from homeassistant.helpers.dispatcher import (
@@ -69,6 +70,10 @@ PUBLISHERS = {
 }
 
 BATCH_SIZE = 3
+DEV_FACTOR = 7
+DEV_LIMIT = 400
+CLOUD_FACTOR = 2
+CLOUD_LIMIT = 150
 DEFAULT_INTERVALS = {
     ACCOUNT: 10800,
     HOME: 300,
@@ -126,6 +131,7 @@ class NetatmoDataHandler:
     """Manages the Netatmo data handling."""
 
     account: pyatmo.AsyncAccount
+    _interval_factor: int
 
     def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
         """Initialize self."""
@@ -135,6 +141,14 @@ class NetatmoDataHandler:
         self.publisher: dict[str, NetatmoPublisher] = {}
         self._queue: deque = deque()
         self._webhook: bool = False
+        if config_entry.data["auth_implementation"] == cloud.DOMAIN:
+            self._interval_factor = CLOUD_FACTOR
+            self._rate_limit = CLOUD_LIMIT
+        else:
+            self._interval_factor = DEV_FACTOR
+            self._rate_limit = DEV_LIMIT
+        self.poll_start = time()
+        self.poll_count = 0
 
     async def async_setup(self) -> None:
         """Set up the Netatmo data handler."""
@@ -167,16 +181,29 @@ class NetatmoDataHandler:
         We do up to BATCH_SIZE calls in one update in order
         to minimize the calls on the api service.
         """
-        for data_class in islice(self._queue, 0, BATCH_SIZE):
+        for data_class in islice(self._queue, 0, BATCH_SIZE * self._interval_factor):
             if data_class.next_scan > time():
                 continue
 
             if publisher := data_class.name:
-                self.publisher[publisher].next_scan = time() + data_class.interval
+                error = await self.async_fetch_data(publisher)
 
-                await self.async_fetch_data(publisher)
+                if error:
+                    self.publisher[publisher].next_scan = (
+                        time() + data_class.interval * 10
+                    )
+                else:
+                    self.publisher[publisher].next_scan = time() + data_class.interval
 
         self._queue.rotate(BATCH_SIZE)
+        cph = self.poll_count / (time() - self.poll_start) * 3600
+        _LOGGER.debug("Calls per hour: %i", cph)
+        if cph > self._rate_limit:
+            for publisher in self.publisher.values():
+                publisher.next_scan += 60
+        if (time() - self.poll_start) > 3600:
+            self.poll_start = time()
+            self.poll_count = 0
 
     @callback
     def async_force_update(self, signal_name: str) -> None:
@@ -198,31 +225,29 @@ class NetatmoDataHandler:
             _LOGGER.debug("%s camera reconnected", MANUFACTURER)
             self.async_force_update(ACCOUNT)
 
-    async def async_fetch_data(self, signal_name: str) -> None:
+    async def async_fetch_data(self, signal_name: str) -> bool:
         """Fetch data and notify."""
+        self.poll_count += 1
+        has_error = False
         try:
             await getattr(self.account, self.publisher[signal_name].method)(
                 **self.publisher[signal_name].kwargs
             )
 
-        except pyatmo.NoDevice as err:
-            _LOGGER.debug(err)
-
-        except pyatmo.ApiError as err:
-            _LOGGER.debug(err)
-
-        except asyncio.TimeoutError as err:
+        except (pyatmo.NoDevice, pyatmo.ApiError) as err:
             _LOGGER.debug(err)
-            return
+            has_error = True
 
-        except aiohttp.ClientConnectorError as err:
+        except (asyncio.TimeoutError, aiohttp.ClientConnectorError) as err:
             _LOGGER.debug(err)
-            return
+            return True
 
         for update_callback in self.publisher[signal_name].subscriptions:
             if update_callback:
                 update_callback()
 
+        return has_error
+
     async def subscribe(
         self,
         publisher: str,
@@ -239,10 +264,11 @@ class NetatmoDataHandler:
         if publisher == "public":
             kwargs = {"area_id": self.account.register_public_weather_area(**kwargs)}
 
+        interval = int(DEFAULT_INTERVALS[publisher] / self._interval_factor)
         self.publisher[signal_name] = NetatmoPublisher(
             name=signal_name,
-            interval=DEFAULT_INTERVALS[publisher],
-            next_scan=time() + DEFAULT_INTERVALS[publisher],
+            interval=interval,
+            next_scan=time() + interval,
             subscriptions={update_callback},
             method=PUBLISHERS[publisher],
             kwargs=kwargs,