Skip to content

Dashboard Data and Refresh

Dashboard widgets display data aggregated from multiple workspace collections. This page explains how that data flows from the database to your screen, how caching works, and how to optimize performance for large workspaces.

Data flow overview

The data pipeline for dashboard widgets follows this path:

  1. User opens a dashboard -- the frontend requests widget data from the API.
  2. API checks the cache -- Redis is checked for a recently computed result.
  3. Cache hit -- the cached result is returned immediately.
  4. Cache miss -- the API runs an aggregation query against MongoDB.
  5. Result is cached -- the fresh result is stored in Redis with a TTL.
  6. Data is returned -- the frontend renders the widget.
StepComponentLatency (typical)
Cache checkRedis< 1ms
Cache hit responseAPI to frontend5-20ms
Aggregation queryMongoDB50-500ms depending on data volume
Cache writeRedis< 1ms
Full round trip (cache miss)End to end100-600ms

Data sources

Each widget type draws data from specific MongoDB collections:

Widget categoryPrimary collectionsSecondary collections
Issue distribution (state, priority, label, assignee)issuesstates, labels, workspace_memberships
Activity widgets (heatmap, timeline)activity_logissues, workspace_memberships
Cycle widgets (risk cards, active cycles)cycles, cycle_issuesissues
Module widgetsmodules, module_issuesissues
Time tracking widgetstime_logsissues, workspace_memberships
Health and risk widgetsissuesactivity_log, cycles
Workspace summaryprojects, cycles, workspace_memberships, pages, modules, issuesNone
User-specific (welcome, recent)activity_log, Redis recent-items cacheissues

Workspace-wide aggregation

By default, dashboard widgets aggregate data across the entire workspace. This means:

  • All projects the user has access to are included.
  • Guest users see only data from projects they are invited to.
  • Archived projects are excluded unless explicitly included in widget configuration.

When a widget is scoped to a specific project or cycle, the aggregation pipeline adds a filter stage that limits results to that scope.

Refresh behavior

Automatic refresh on page load

Every time a user opens a dashboard, all visible widgets fetch fresh data. If cached data is available and within the TTL window, the cache is used.

Manual refresh

Click the Refresh icon in the dashboard toolbar to force all widgets to fetch new data, bypassing the cache.

ActionCache behavior
Page loadUses cache if available
Manual refreshBypasses cache, fetches fresh data
Auto-refresh intervalBypasses cache on each tick
Widget configuration changeFetches fresh data for that widget

Auto-refresh intervals

Configure an automatic refresh interval for dashboards that stay open on a monitor:

IntervalUse case
OffDefault. Data refreshes only on page load or manual refresh
1 minuteHigh-frequency monitoring (standup screens)
5 minutesActive monitoring during sprints
15 minutesBackground awareness
30 minutesLow-priority overview screens

Set the interval from the dashboard toolbar ... menu > Auto-refresh.

TIP

Auto-refresh increases API load proportionally. A dashboard with 10 widgets refreshing every minute generates 10 API calls per minute. Use longer intervals for dashboards with many widgets.

Caching strategy

Redis cache structure

Dashboard data is cached in Redis with the following key pattern:

setget:dashboard:{workspace_id}:{widget_type}:{config_hash}
ComponentDescription
workspace_idThe workspace this data belongs to
widget_typeThe widget type identifier
config_hashSHA-256 hash of the widget's filter and scope configuration

This ensures that two widgets of the same type with different configurations maintain separate caches.

Cache TTL

Data typeDefault TTLRationale
Issue counts and distributions5 minutesBalances freshness with query cost
Activity data (heatmap, timeline)10 minutesActivity patterns change slowly
Cycle and module progress5 minutesSprint data should be reasonably current
Health scores15 minutesComposite scores need less frequent updates
Workspace summary counts10 minutesDocument counts are expensive on large workspaces
User-specific data (welcome, recent)2 minutesPersonal data should feel fresh

Cache invalidation

The cache is invalidated automatically in these scenarios:

TriggerScope
Issue state changeWidgets filtered to that project
Issue created or deletedAll issue-based widgets in the workspace
Cycle started or endedCycle-related widgets
Manual refresh button clickedAll widgets on the current dashboard
Widget configuration changedThat specific widget

Real-time vs. cached data

SetGet dashboards prioritize reliability over real-time precision:

AspectBehavior
Data currencyWidgets show data that is at most TTL-old (typically 5-15 minutes)
ConsistencyAll widgets on a dashboard may show data from slightly different points in time
Real-time updatesNot pushed to dashboards via WebSocket (unlike notifications)
Timer widgetThe time tracking timer is real-time via Redis, but time log aggregations are cached

WARNING

If two team members look at the same dashboard at slightly different times, they may see different numbers. This is expected and resolves on the next refresh cycle.

Performance considerations

Large workspaces

Workspaces with more than 50,000 issues may experience slower aggregation queries. Mitigation strategies:

StrategyDescription
Scope widgets to projectsReduces the dataset for each query
Use longer refresh intervalsReduces query frequency
Limit list widgetsSet lower max-items on Issues Due Soon, Hot Issues, Stalled Issues
Avoid many custom query widgetsCustom queries bypass pre-optimized aggregation pipelines

MongoDB indexes

Dashboard aggregation queries rely on these indexes for performance:

CollectionIndexUsed by
issues{ workspace_id: 1, state_id: 1 }State distribution, stats bar
issues{ workspace_id: 1, priority: 1 }Priority distribution
issues{ workspace_id: 1, assignee_id: 1 }Assignee distribution, workload
issues{ workspace_id: 1, due_date: 1 }Issues due soon, deadline calendar
activity_log{ workspace_id: 1, created_at: -1 }Activity timeline, heatmap
time_logs{ workspace_id: 1, logged_date: 1 }Time tracking widgets
cycle_issues{ cycle_id: 1 }Cycle progress, risk cards
module_issues{ module_id: 1 }Module progress

API rate limiting

Dashboard API endpoints are rate-limited to prevent abuse:

Endpoint patternRate limit
GET /api/workspaces/{slug}/dashboards/{id}/widgets60 requests per minute
GET /api/workspaces/{slug}/dashboards/{id}/widgets/{widget_id}/data120 requests per minute
POST /api/workspaces/{slug}/dashboards/{id}/refresh10 requests per minute

API endpoints

MethodEndpointDescription
GET/api/workspaces/{slug}/dashboards/List all dashboards
POST/api/workspaces/{slug}/dashboards/Create a dashboard
GET/api/workspaces/{slug}/dashboards/{id}/Get dashboard details
PATCH/api/workspaces/{slug}/dashboards/{id}/Update dashboard settings
DELETE/api/workspaces/{slug}/dashboards/{id}/Delete a dashboard
GET/api/workspaces/{slug}/dashboards/{id}/widgets/List widgets on a dashboard
POST/api/workspaces/{slug}/dashboards/{id}/widgets/Add a widget
PATCH/api/workspaces/{slug}/dashboards/{id}/widgets/{widget_id}/Update widget configuration
DELETE/api/workspaces/{slug}/dashboards/{id}/widgets/{widget_id}/Remove a widget
GET/api/workspaces/{slug}/dashboards/{id}/widgets/{widget_id}/data/Fetch widget data
POST/api/workspaces/{slug}/dashboards/{id}/refresh/Force refresh all widgets

Troubleshooting

SymptomLikely causeFix
Widget shows stale dataCache TTL has not expiredClick the manual Refresh button
Widget shows "No data"Scope filter excludes all resultsCheck widget configuration scope
Widget loads slowlyLarge dataset without project scopeScope the widget to a specific project
Dashboard takes long to loadToo many widgets fetching simultaneouslyReduce widget count or increase refresh interval
Numbers differ between widgetsWidgets cached at different timesRefresh the dashboard to align cache timestamps