---
title: Stack Activity
description: Per-stack event log showing deploys, restarts, config changes, and alerts, each attributed to the user or system process that triggered them.
---
The **Activity** tab in the right-hand **Anatomy** panel gives you a timestamped record of everything that happened to the selected stack: deploys, restarts, stops, starts, image updates, drift events, and health gate outcomes. Every entry is attributed to the user or background process that triggered it, so you always have full operational context at a glance. The **files** and **edit** buttons on the same header strip belong to the panel as a whole and stay available regardless of which tab is active.
## What you'll see
Each entry in the activity list contains four pieces of information:
| Field | Description |
|-------|-------------|
| **Icon** | Category of the event (deploy, restart, stop, start, image update, drift, and others) |
| **Message** | What happened, for example `plex deployed`. Sensitive values such as tokens, secrets, basic-auth credentials, and bearer tokens are redacted before storage |
| **Attribution** | `by ` for user-initiated actions; `via ` for events triggered by background processes such as Auto-Heal or the Scheduler |
| **Time** | Relative time since the event: `just now`, `5m ago`, `2h ago`, `3d ago` |
## Event categories
Ten categories have a dedicated icon. Any other notification scoped to a stack (deploy failures, scan findings, monitor alerts) also flows into the timeline and renders with a generic activity icon.
| Category | Example message |
|----------|-----------------|
| Deploy succeeded | `plex deployed` |
| Stack restarted | `dozzle restarted` |
| Stack stopped | `radarr stopped` |
| Stack started | `radarr started` |
| Image update applied | `Auto-update: stack "dozzle" updated with new images` |
| Drift detected | `Drift detected on sonarr: 2 findings` |
| Drift resolved | `Drift resolved on tautulli: 1 finding cleared` |
| Update started | `tautulli update started` |
| Health gate passed | `plex: health gate passed` |
| Health gate failed | `plex: health gate failed` |
## Day grouping
Events are grouped by day under three headers: **Today**, **Yesterday**, and **Earlier**. Within each group, events appear most-recent first. The grouping recomputes every minute so a panel left open past midnight automatically rolls the **Today** bucket into **Yesterday**.
## Live updates
New events stream in over the same WebSocket that powers the notification bell. The list updates without a page refresh while the tab is open. Duplicate events are deduplicated by ID, and the timeline is sorted by `(timestamp, id)` so events emitted within the same millisecond stay in a stable order.
If the WebSocket connection drops, a banner appears at the top of the timeline:
> Live updates offline; reconnecting…
New events are paused until the connection re-establishes. Existing entries remain visible. Once the banner clears, new events resume automatically without any action on your part.
## Pagination
The tab loads the 50 most recent events on open. If a stack has more recorded events, a **Load more** button appears at the bottom of the list. Each click fetches the next 50 older events. The button disappears once the timeline reaches the end of the stored history.
The underlying API endpoint, `GET /api/stacks/{stackName}/activity`, accepts an optional `before` (timestamp) and `beforeId` (row id) pair for cursor-based pagination. Both parameters must be sent together; sending `beforeId` without `before` is rejected.
## Empty state vs unavailable
Two states can make the tab look empty, and they mean different things:
- **No activity recorded yet** appears when the stack genuinely has no recorded events. This is normal for stacks that have not had any lifecycle actions since Sencho began tracking activity.
- **Activity unavailable** appears when the request to fetch events fails (for example, the node became unreachable mid-load). A **Retry** button is shown next to this message.
## Who triggered an event
Sencho attributes every recorded event to the actor that performed it:
- **User-initiated actions** (deploy, restart, stop, start, image update triggered from a button or the API): the actor is the authenticated username, shown as `by `.
- **Background subsystems**: the actor is the subsystem name, shown as `via `.
| Background subsystem | Displayed as |
|----------------------|--------------|
| Generic system event | `via System` |
| Auto-Heal | `via Auto-Heal` |
| Scheduler | `via Scheduler` |
| Image Update | `via Image Update` |
| Docker event monitor | `via Docker` |
| Blueprint reconciler | `via Blueprint` |
| Host Monitor | `via Monitor` |
| Policy enforcement | `via Policy` |
An Auto-Heal restart and a manual restart produce separate entries in the timeline because their actors differ, even when the event message is otherwise identical.
## Retention
Activity is stored in a per-instance SQLite table. Two limits apply, whichever is reached first:
- **Time-based:** events older than the configured retention window (30 days by default) are removed during the next periodic cleanup.
- **Per-stack cap:** the most recent 500 events per (node, stack) are kept. Older events for that stack are pruned on the next cleanup run.
Events without an associated stack (system-level notifications) are kept up to 1,000 per node before the oldest are removed.
Cleanup runs on the same schedule as container-metrics cleanup, so retention applies even on long-running instances.
## Accessing the Activity tab
1. Click any stack in the left sidebar to open it.
2. Select the **Activity** tab in the Anatomy panel header.
## Troubleshooting
This is normal for stacks that have not had any lifecycle actions (deploy, restart, stop, update) since Sencho started tracking activity. The tab populates the first time a lifecycle event is recorded. Events that occurred before Sencho was installed are not backfilled.
The request to fetch activity failed, usually because the node is unreachable or the backend returned a server error. Click **Retry** to re-fire the request without reloading the page. If the node has been removed or its credentials have changed, go to **Settings → Nodes** to verify the connection.
Live events arrive over WebSocket. If the "Live updates offline; reconnecting…" banner is visible, new events are paused until the connection recovers. Scroll down to check whether the event is already present below the visible viewport, or wait for the banner to clear and the event will appear automatically. If the event still does not show up, check the notification bell for error-level alerts that may indicate the action itself did not complete.
These are two distinct events. The first is a manual restart; the second is Auto-Heal restarting the container after a separate unhealthy-duration breach. Each event is its own entry with its own actor. Two rows here are correct behavior, not a duplicate.
The notification bell surfaces system alerts and error-level events. User-initiated operational events (start, stop, restart, deploy, update) appear exclusively in the per-stack Activity tab, keeping the global tray focused on conditions that need your attention.