Skip to content
Infrastructure

Glance calendar widget timeouts: too much data, not a timeout config

By Victor Da Luz
glance dashboard homelab calendar ical debugging troubleshooting

I run Glance as my homelab dashboard. One of its widgets shows upcoming calendar events from my Nextcloud instance, using glance-ical-events - a small Python service that fetches CalDAV data and formats it for Glance’s custom-api widget type.

It worked fine for a while, then stopped. The upcoming events section showed nothing - just an empty widget with no visible error.

The error

Checking Glance logs surfaced the problem:

context deadline exceeded (Client.Timeout exceeded while awaiting headers)

The custom-api widget was making a request to the ical-events service and not getting a response back within 30 seconds. My first instinct was a timeout mismatch - the widget’s default timeout was too short. I added a timeout setting to the widget config:

type: custom-api
url: http://localhost:8076/events?limit=10&upcoming=true&url=...
timeout: 90s

Deployed it. Still timing out.

What the service logs showed

With the timeout change making no difference, I looked at what the ical-events service was actually doing. The logs showed it wasn’t just slow - it was failing while processing the calendar data.

I looked at the service configuration:

lookback_days: 14
horizon_days: 3650

horizon_days: 3650 is 10 years. On every request, the service was fetching all calendar events from Nextcloud, filtering for everything within the next decade, and parsing all of it before responding. With a calendar spanning multiple years of regular events, that’s a lot of data to process in under 30 seconds.

The fix

Reducing the date range to something reasonable for a “what’s coming up soon” widget:

lookback_days: 7
horizon_days: 30

Response time dropped from 30+ seconds to about 0.2 seconds. Widget works.

The timeout setting that did nothing

While poking around, I found something that would have saved me time: the custom-api widget type in Glance doesn’t support a timeout property. It’s not in the documentation. The widget has a hardcoded 30-second timeout with no way to configure it.

Every iteration where I’d added timeout: 90s or timeout: 120s to the widget config was being silently ignored. The widget timed out at 30 seconds regardless of what I put there.

If the root cause had actually been a slow-but-functional service that needed more time, there would have been no way to fix it from the widget config side.

Lessons learned

  • Check the service logs before assuming a timeout issue is about the timeout. The Glance error said “timeout” but the ical-events service was failing while processing data. A timeout symptom often points to a non-timeout root cause.
  • Scope date ranges to your actual use case. horizon_days: 3650 sounds thorough, but for a widget showing the next few upcoming events, 30 days is more than enough. The performance cost of fetching years of data is real.
  • Verify config options exist before relying on them. The timeout setting I spent time tuning had zero effect because custom-api doesn’t support it. When a config change has no observable effect, it’s worth checking whether the option is actually valid.

Related reading

Infrastructure

Fixing iframe embedding in self-hosted dashboards

My Glance dashboard wouldn't embed Homepage via iframe. The browser refused to display it, and fixing it turned out to be a two-step process: using the right Traefik header field, then actually deploying the config.

Read

Ready to Transform Your Career?

Let's work together to unlock your potential and achieve your professional goals.