Slow or unable to access HA thru Cloud Nabu Casa

Dashboard loads in 3 seconds locally, 90 seconds through Nabu Casa

Hi all,

I’ve been chasing this for a while and I’m running out of ideas.

My dashboard opens in about 3 seconds on the LAN. Through Nabu Casa Remote UI, the same dashboard on the same laptop takes around 90 seconds before anything shows up. The sidebar and the tabs appear after a while, then the content area just stays empty for a long time. No errors anywhere, nothing fails, nothing retries. It all works, it’s just painfully slow.

Setup is HA 2026.8.1 on a HA Yellow. Fairly big install: around 7000 entities, one dashboard with 41 views, and about 50 Lovelace resources (button-card, Bubble Card, card-mod, apexcharts and friends). Yes I know that’s a lot, which is why I tried to actually measure things instead of just assuming it’s “too heavy”.

Here’s what I’ve tested and ruled out so far:

  • Cleaned up the dashboard, removed cards, tried a nearly empty dashboard. Same slowness. So it’s not the dashboard content itself.

  • Checked Browser Mod for the classic pile of stale browser devices. I have exactly one.

  • Checked known_devices.yaml after finding an old thread about it. Five lines.

  • Disabled a bunch of integrations to cut the entity count. Barely changed anything. Turns out disabled entities stay in the state machine as “restored” until you restart HA, so that test was useless without a reboot.

  • Watched the WebSocket traffic. It’s not chatty at all, and it’s not saturated. Everything arrives in a handful of big messages rather than thousands of small ones.

  • Timed a plain file download and an empty API call through both paths. The tunnel is much slower and has way more latency than my LAN, which isn’t surprising, but the gap is bigger than I expected on a fibre line where everything else is fast.

I did find two genuine bugs while digging. Browser Mod loads its javascript file twice because it registers itself both as an extra module and as a Lovelace resource, with slightly different URLs, so the browser downloads it twice. And I had lovelace-wallpanel loading on every page while being disabled in its own config. Fixed both, it helped a bit, nowhere near enough.

What I’m left with is that the initial load pulls several megabytes before anything renders, and over the tunnel that just takes forever. Installing Tailscale gives me LAN-like speed to the same. Using OPEN VPN to access HA ovr 5G give me LAN-like speed too instance, so the box itself is fine.

So my questions:

Does anyone else with a large install see this over Remote UI, and what kind of speed do you actually get through it? I’d like to know if what I’m seeing is normal or if something is off on my side.

And the thing that puzzles me most: on every page load HA sends the full entity registry to the browser, including entities that are disabled. I have around 2500 disabled ones. They have no state and can never show up on a dashboard, but they’re still sent every time. Is there a reason for that? It looks like a decent chunk of what I’m waiting for.

Thanks in advance, happy to run more tests if anyone has an idea worth checking.

About the entity.registry file, that’s probably the least file you have be “concerned” about, how big is that ? , compared to your Fully Loaded Dashboard ?, which is the one which needs to be rendered, entities updated, API-connection etc … just imagine

Then you talking about Tailscale and access HA ovr 5G

But you have never mention anything about your “Connection” while accessing HA Via your Laptop ? or Phone-APP ? through your Cloud-Connetion
i.e is it from a sunken WIFI(Somewhere) ? , Or Over the Phone-line ? etc.

You won’t get faster speed than the Slowest link, in Your Route

You do know there is something called Route, there’s a big Different , Don’t expect anything near your Internal LAN, Obviously
Yet you keep compare to your LAN, Seriously ?

Yes there’s alot You can do at Your end to reduce the Load,

Maybe you forgot to “Flush” all your caches in your test to minimize the Load, or Not, i can’t tell

Thou Your Topic “category” is Cloud and not Social, so specify in a structured way , your tests , hardware, connection etc. etc.
And i.e stick to one Device,Your Phone or Laptop, and one type of Connection( You can variate all to compare,) but don’t make a mess out of it when describing a scenario

Fair enough, those are reasonable points. I left the numbers out to avoid drowning everyone, but you’re right that without them it’s just another “my HA is slow” thread. So here’s everything, method included.

Up front: I changed my mind twice while measuring. I first thought it was the size of my dashboard, then the per-request latency. Both were wrong. What follows is what’s left after ruling everything else out.

Test conditions

Mac mini on wired gigabit ethernet, no WiFi, no cellular. Free fibre line. HA Yellow (CM4), Core 2026.8.1, also on wired gigabit. Each pair of tests run a couple of minutes apart. I hit two addresses from the same machine: the local IP, and the Nabu Casa hostname. Worth noting, even from inside my own network that hostname resolves to the relay, so the traffic really does go out and come back through the tunnel. It’s not a local shortcut. Relay in question: eu-central-1-15.ui.nabu.casa, region eu-central-1.

The numbers below come from the Mac mini, on both Safari and Chrome — same results either way.

But the symptom itself shows up everywhere I’ve tried it: Safari and Chrome on the Mac mini, Safari and Chrome on iOS, Chrome on Android, and the Home Assistant companion app on both iOS and Android. So it isn’t a browser, a rendering engine, an OS, or a particular client-side cache.

Since you asked about my connection

Phone on 5G, outdoors, SFR: 659 Mb/s down, 43 Mb/s up, 11 to 21 ms latency.

Same phone on my home WiFi, Free fibre: 639 Mb/s down, 604 Mb/s up, 13 to 15 ms latency.

The upload from home is the one that matters, since that’s HA pushing data outwards. I’ll be honest about the method: a speedtest measures against a nearby test server, not against the relay, so it isn’t the same route. Keep that 604 Mb/s in mind anyway.

And the Yellow’s own link, before anyone asks

Gigabit ethernet, no WiFi. I had it serve the 3.5 MB of /api/states locally: 2 seconds, so about 15 Mb/s. On a 1000 Mb/s link the cable clearly isn’t working hard — what limits it is the CM4’s serialisation speed. If its link were the problem, local access would be slow too. It isn’t.

The raw stream, no dashboard involved

Same /api/states request, about 3.6 MB, same token, LAN versus the cloud URL:

  • LAN: 3.6 MB in roughly 0.3 s, so ~90 Mb/s
  • Cloud: 3.6 MB in 86 to 99 seconds, so ~0.3 Mb/s

No dashboard in there. No custom cards, no rendering, no WebSocket. Just a GET returning JSON. The ratio is already 300 to 1.

The test that identifies what kind of throttling this is

This is the one that made me drop the latency theory. I ran the same request over 1, then 2, then 4 parallel connections, capped at 2 MB each:

  • 1 connection: 0.35 Mb/s
  • 2 connections: 0.46 Mb/s total, so 0.23 each
  • 4 connections: 0.38 Mb/s total, so 0.09 each

The aggregate stays flat. If this were a per-connection latency problem, four connections would have given roughly four times the throughput. Instead they share a fixed-size cake. So it’s an aggregate cap on the tunnel, somewhere around 0.4 Mb/s.

And it isn’t transient: I forced a disconnect and reconnect of the tunnel through cloud/remote/disconnect and connect. It lands on the same node and the throughput is unchanged. The cap is persistent and there’s nothing I can do about it from my side.

The test that definitively rules out my dashboard

I went all the way on this one, because it’s the objection I get every time. I backed up my config, then replaced it with this, and nothing else:

title: Aperçu
views:
- title: Hello
path: accueil
icon: mdi:home-heart
cards:
- type: markdown
content: "# Hello"

196 bytes, against 1.692 MB for my real config. A factor of 9000. Same URL, same dashboard, same everything — only the content changes.

Locally: load at 744 ms in both cases, and more to the point exactly the same 163 requests and the same 14 MB of decoded JavaScript. Config size changes nothing about resource loading; the frontend loads everything that’s registered regardless of what it has to display.

Through the cloud, cold — I emptied all 4 caches and unregistered the service worker before measuring:

  • DOMContentLoaded: 1877 ms
  • Load, meaning the HA shell alone: 11 945 ms
  • last resource finished: 109 311 ms
  • transferred: 1228 KB across 161 requests, so about 0.09 Mb/s

A 196-byte dashboard takes 110 seconds to show up.

One difference I hadn’t anticipated, while I’m at it: on the LAN I’m on plain HTTP, so a non-secure context, and HA’s service worker doesn’t even register there. Over the cloud, on HTTPS, it does.

So the two paths don’t have the same caching mechanism, which makes a cold comparison even less favourable to the cloud.

What happens with the real dashboard, cold

Worse: it doesn’t finish. Per the HAR, the load transfers 1.78 MB and then gives up and drops back to the login page after about a minute and a half. The WebSocket never establishes. Files of 5 to 12 KB take 15 to 23 seconds, authorize.js at 118 KB takes 16.5 seconds. The plain HA shell takes 7.4 s versus 1.2 s on the LAN.

So cold, through the cloud, my install isn’t slow, it’s unusable.

The test that isolates the culprit

I also reach my instance over OpenVPN. Same phone, same 5G, same Yellow, same dashboard: it works normally.

The difference is structural. Over OpenVPN my phone builds a direct tunnel to my router: one hop, my own latency. With Nabu Casa there is no direct path — the Yellow holds an outbound connection to the relay, my client connects to that same relay, and every byte goes up and then back down.

Same hardware, same line, same dashboard, only the route changes. That’s a controlled test, and it points at the relay.

What I ruled out along the way, in case it saves someone time

Browser Mod piling up stale browser sessions, the explanation that comes up most often: I have exactly one device and thirteen entities.

A bloated known_devices.yaml, which fixed it for someone in an older thread: mine is 543 bytes.

WebSocket saturation from too many subscriptions: 34 frames for the entire load, 170 state changes in 15 seconds. The socket is bored.

Cutting the entity count by disabling integrations. That one is a trap and I lost an evening to it.

I disabled 62 config entries covering 1756 entities, 24% of my total, and measured the payload before and after: 3.518 MB versus 3.452 MB. Under 2%. Disabled entities stay in the state machine as restored: true until HA restarts, so you measure nothing without a reboot.

And dashboard size, definitively ruled out by the 196-byte test.

Two genuine bugs I found while digging

Browser Mod downloads its 174 KB file twice on every load. It registers itself both through add_extra_js_url as /browser_mod.js?<version> and as a Lovelace resource /browser_mod.js?automatically-added&<version>. Different query string, different cache entry, two downloads. Locally that costs 16 ms plus 319 ms and nobody would ever notice. Through the tunnel it cost me 13.2 seconds plus 10.6 seconds. Deleting the Lovelace resource doesn’t stick, the integration recreates it at startup — but if you edit the resource URL so it ends with the version number, the integration leaves it alone and you get a single download.

And I had lovelace-wallpanel loading 213 KB on every page while being disabled in its own config.

Removed.

Between them, about 387 KB and 12 requests less per load. It helps, it’s nowhere near enough — of course, since the problem isn’t volume.

My questions

An aggregate cap of roughly 0.4 Mb/s on a Remote UI relay: is that expected? Fair use, QoS, or a saturated node? And if it’s the node, is there any way to move to another one? Reconnecting always lands on the same one.

Because at that rate it isn’t only my install that’s affected: the plain HA shell already takes 7.4 seconds, and an empty dashboard 110. That makes remote access unusable cold for anyone, whatever their config.

If anyone wants to compare, here’s the measurement that matters — aggregate throughput, not latency.

Run it from a terminal with a long-lived access token:

time curl -s -o /dev/null -H "Authorization: Bearer YOUR_TOKEN" \
"https://YOUR-INSTANCE.ui.nabu.casa/api/states"

Compare it with the same request against your local IP. It’s the ratio between the two that tells the story, and it doesn’t depend on any dashboard.

TLDR :slight_smile: .. but again you start comparing your GIGA b ( LOCAL ) LAN, with a Cloud connection
It’s not like your " Potential " GIGA bit Internet Subscription ( Or LAN ) is any garanti for traffic outside Your LAN or nearest Trace-Point in your Operators network

Have you “tested” simple Ping and Tracert, to get an idea of “latency s and hops” ?
It Still sounds like you don’t understand what you basically is doing, the only thing you seems to have verified, is that your Device using to access HA, is capable of doing it’s job
And forget about 5G, you are lucky if you connect to a 5G sender/receiver, and again it’s far from a garanty for your “normal” activity speed

NOTE: in regards to your browser_mod’s 2 instances, maybe that’s the same thing as reported in here, in several Topics, and where the solution to avoid double-loading of this is in a configuration “setting” ( Which i deleted , when i went over to UIX )
So already there it seems like you can “reduce” a few seconds, beside all the other “traffic” your heavily loaded Main Dashboards generate.

@multinet33 sorry to say so and I don’t mean this in a harsh way, just some advice.

I stopped reading your first post in this topic because of the readability of it and it keeps going and going.
Same thing with the second one.
At least my brain has a problem of how you describe your issue…

You may well be right, and honestly I hope you are: if the problem is on my end, I can fix it.
That’s exactly why I’m measuring instead of complaining. Let me take your points one at a time, with the commands so you can judge the method, and I’ll put a question back to you at the end.

The one measurement that sums it all up, taken on the Yellow itself, same network card, same minute: 98 Mb/s to a third-party server, 0.195 Mb/s through its own Nabu Casa tunnel. The same 3.67 MB moved in both cases. Only the route changes.

The detail of that one is further down, with the command. Let me go through your points in order first.

Ping and traceroute, which I genuinely hadn’t run

ping -c 20 eu-central-1-15.ui.nabu.casa
→ 20 packets transmitted, 0 packets received, 100.0% packet loss

ICMP is blocked, as it is with most cloud hosts. So ping tells us nothing, either way.

traceroute -w 2 -q 1 -m 18 209.38.178.58
 1  192.168.1.1              6.1 ms
 3  station17.multimania.isdnet.net   12.5 ms
 4  212.27.35.0              11.8 ms
 7  port-channel8670.ccr91.lhr01.atlas.cogentco.com   19.5 ms
 8  te0-5-0-6-4.agr21.lhr01.atlas.cogentco.com        18.6 ms
 9+ * (filtered)

Short path: my router, the Free network, then Cogent in London. Every hop that answers is under
20 ms. The relay resolves to 209.38.178.58.

Since ICMP is filtered, I measured latency where it actually matters, at the TCP level on port 443:

curl -s -o /dev/null -w "connect=%{time_connect}s tls=%{time_appconnect}s code=%{http_code}\n" \
     "https://<my-instance>.ui.nabu.casa/api/"

connect=0.028004s  tls=1.049466s  code=401
connect=0.026261s  tls=1.119223s  code=401
connect=0.036894s  tls=3.761991s  code=401
connect=0.028922s  tls=1.179933s  code=401
connect=0.029932s  tls=1.485679s  code=401
connect=0.029331s  tls=1.246404s  code=401
connect=0.029713s  tls=0.145414s  code=401
connect=0.031229s  tls=1.357957s  code=401

26 to 37 ms of TCP connect, very stable. So the network path is fine: few hops, normal latency, no loss. But look at the TLS column.

The control I was missing

Same machine, same second, same link, against a third-party HTTPS server:

curl -s -o /dev/null -w "connect=%{time_connect}s tls=%{time_appconnect}s\n" https://1.1.1.1/

connect=0.013120s tls=0.031197s
connect=0.012954s tls=0.029044s
connect=0.013950s tls=0.030213s

Cloudflare completes its handshake in 30 ms. The Nabu Casa path takes between one and nearly four seconds. TCP is comparable on both sides; it’s the layer above that falls apart.

Then I re-ran the whole set from the Yellow itself

What your point really made me realise is that I was testing from the wrong end. The Yellow is the one that opens the outbound connection to the relay, so it’s its internet link that carries the remote traffic, not my Mac’s. Everything below comes from a terminal on the Yellow.

First its own throughput to the internet, outside the tunnel, 10 MB each way:

curl -s -o /dev/null -w "%{speed_download} B/s in %{time_total}s\n" \
     "https://speed.cloudflare.com/__down?bytes=10000000"
→ 13,919,221 B/s in 0.718 s     that's 111 Mb/s

dd if=/dev/zero of=/tmp/10M bs=1M count=10
curl -s -o /dev/null -w "%{speed_upload} B/s in %{time_total}s\n" \
     -T /tmp/10M "https://speed.cloudflare.com/__up"
→ 12,219,328 B/s in 0.858 s     that's 98 Mb/s

Then, from the same machine seconds later, the same /api/states request through its own Nabu Casa URL. The traffic goes out to the relay and comes back down, so it’s exactly the remote path.

curl -s -o /dev/null -H "Authorization: Bearer <token>" \
     -w "%{size_download} B in %{time_total}s -> %{speed_download} B/s\n" \
     "https://<my-instance>.ui.nabu.casa/api/states"
→ 3,671,526 B in 150.59 s -> 24,381 B/s      that's 0.195 Mb/s

… and the same request locally, for reference:
→ 3,671,465 B in 0.154 s -> 23,853,073 B/s   that's 191 Mb/s

98 Mb/s to Cloudflare, 0.195 Mb/s through its own tunnel. Same machine, same NIC, same minute, same 3.67 MB. Only the route changes. A factor of 500.

One methodological caveat I’d rather raise myself: in that test the Yellow queries its own public URL, so the bytes cross its link twice, once going up through the tunnel and once coming back down the curl connection. Even counting it double, that’s 0.39 Mb/s on a link that just demonstrated 98.

TLS handshakes from the Yellow, eight samples to the relay and three to Cloudflare:

to the relay : 0.138 · 0.310 · 0.822 · 0.916 · 0.946 · 1.766 · 1.805 · 5.861 s
to 1.1.1.1   : 0.083 · 0.096 · 0.100 s
(TCP: 0.028 to 0.032 s to the relay, 0.013 s to Cloudflare)

Its TLS baseline is slower than my Mac’s, 90 ms against 30, because the CM4 does crypto more slowly — that’s expected, and I’m saying it so nobody thinks I’m dressing up the number. But 5.8 seconds is sixty times its own baseline, measured on the same machine in the same minute.

The traceroute from the Yellow, while I was at it:

 2  192.168.1.1                                        2.4 ms
 5  212.27.35.0  (Free)                               12.0 ms
 8  port-channel8670.ccr91.lhr01.atlas.cogentco.com   17.6 ms
 9  te0-5-0-6-4.agr21.lhr01.atlas.cogentco.com        17.2 ms
10  ae6.sdr1.gb-slo1.as14061.net                      16.4 ms
11+ * (filtered)

Ten hops, everything that answers is under 18 ms, no loss. Ping is still 100% loss from there too, so the ICMP blocking really does come from the host end rather than being something odd about my setup.

On your broader point

I’m not comparing my local gigabit to a cloud connection and expecting the same thing. I don’t expect 90 Mb/s through a tunnel. What I’m trying to understand is why I get 0.2 to 0.4 Mb/s, and above all why that number doesn’t move with parallelism. From the Mac:

for i in 1 2 3 4; do
  curl -s -o /dev/null -H "Authorization: Bearer <token>" -r 0-2000000 \
       -w "%{speed_download}\n" "https://<my-instance>.ui.nabu.casa/api/states" &
done; wait

1 connection  : 0.35 Mb/s
2 connections : 0.46 Mb/s aggregate  (0.23 each)
4 connections : 0.38 Mb/s aggregate  (0.09 each)

And the same thing from the Yellow, which comes out even cleaner:

1 connection  : 50,817 B/s                   = 0.41 Mb/s aggregate
2 connections : 14,568 + 14,511 B/s          = 0.23 Mb/s aggregate
4 connections : 11,276 + 11,274 × 3          = 0.36 Mb/s aggregate

At four connections the four figures land within three bytes per second of each other. That isn’t congestion, that’s sharing. The aggregate stays flat, and two connections actually give less than one. A faulty device or link would have given four times the throughput at four connections; here each one’s share is exactly the ceiling divided by their number.

And the same phone, on the same 5G, reaches the same instance normally over OpenVPN. Same device, same carrier, same internet, same dashboard. Only the route changes.

My question, and it’s the one I really care about

I replaced my entire dashboard with this, and nothing else:

title: Aperçu
views:
  - title: Hello
    path: accueil
    cards:
      - type: markdown
        content: "# Hello"

196 bytes. One view, one card. Cold — caches emptied and service worker unregistered — it takes 110 seconds to appear through Nabu Casa.

Do you consider that normal?

If you do, I’ll stop here and adjust my expectations accordingly. If you don’t, then something is genuinely wrong, on my end or elsewhere, and that’s precisely what I’m trying to pin down. Either way your answer helps.

And if there’s a measurement I’m still missing, tell me which one and I’ll happily run it.

Thanks either way for the time you’re putting into replying. It’s what made me run the ping and traceroute I hadn’t thought to do, and more importantly re-run the whole set from the Yellow rather than from my Mac. That’s where the most telling measurement of the lot came from.

Ok NIck

I have a simple 196 bytes dashboard that takes 110 seconds to show up when acceded thru cloud nabu casa. Nothing else.

EDIT: I put my cloud on a new HA instance on portainer : cloud access is NORMAL (the nabu casa url is the same)

so I have a problem on the yellow

Yeah it does seems like your underlying connection is fine ,

This question you have to post in Nabu Support side, but try to “structure” you latest post, with the most relevant parts

Thou, You are now comparing a worldclass DNS Provider( Multi-Billions-dollar-Company ), with A Small Cloud-Service-Server :joy:

It is really hard to read when you cut and paste from a text editor.

Oh you’re right, I reformated previous messages, thank you

Solved: it wasn’t Nabu Casa, it was my own templates

Dashboard in 3 s on the LAN, 90 s through the cloud. I was blaming the Nabu Casa relay. Wrongly.

The test that proved me wrong. I connected a test HA instance (21 entities) to the same Nabu Casa account — same URL, same relay, one variable changed. It loaded instantly. The relay was fine.

The real cause. A plain WebSocket ping on the LAN took 158 ms on my box against 4 ms on the test instance. My event loop was saturated by three templates like this one:

{{ states.sensor | selectattr('entity_id','search','...') | list | count }}

states.sensor walks my 3,865 sensors, and since HA can’t predict which ones matter, it subscribes the sensor to every state change in the domain. Each change re-ran the whole scan. 51% of the loop.

The LAN hid this (it pays the latency once per request), the tunnel amplified it 1000× (it pays on every round trip).

The fix. Make the block trigger-based. The Jinja doesn’t change by a single character:

  - trigger:
      - trigger: time_pattern
        minutes: "/5"
    sensor:

Result: loop latency 158 ms → 1.4 ms, cloud throughput 0.10 → 5.07 Mb/s.

The rule: never use states.<domain> followed by a filter in a template that isn’t trigger-based. To test yourself: 40 WebSocket pings on the LAN, median under 5 ms means you’re fine.

Sorry, I have No Words ! , However, good that you “penetrated” it

Well, we finally got there :grinning_face_with_smiling_eyes:. In the end, you were right about one thing: the problem wasn’t Nabu Casa itself.

But I think the investigation also showed why it wasn’t so unreasonable to suspect it in the first place — the exact same HA instance behaved badly through Nabu Casa while another instance worked perfectly through the same service.

Anyway, the templates were the culprit. Case closed… and apparently I finally ‘penetrated’ the problem :wink:.

Same issue here since 2026.8.2 (HA OS). Local access is instant, but Nabu Casa remote access has 1-2s lag on dashboard navigation specifically — service calls (lights etc.) are instant even remotely. Also seeing repeated “Unclosed client session” errors in the logs (18 occurrences over ~4h30). Anyone found a fix?

Hi, if you have the same issue, the fix is marked and linked in the first post of this thread.