> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timeback.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Activity models

> Single-session vs stateful activities and when to use each

Timeback supports two activity models. The right choice depends on the nature of your app, its architecture, and the learning material: specifically, whether students complete an activity in one sitting or across multiple sessions.

## Single-session

The simplest model: a student starts and completes an activity in one browser session.

```mermaid theme={null}
graph LR
    A[Student starts] --> B[Engages] --> C[Ends activity]
    style A fill:#e0f2fe,stroke:#0284c7
    style C fill:#dcfce7,stroke:#16a34a
```

The client SDK tracks time and reports completion together. The frontend is the source of truth — it observed the entire activity lifecycle.

**Use single-session when:**

* Students complete the activity in one sitting (quizzes, short lessons, drills)
* The frontend has all the data it needs to report completion metrics
* You do not need to persist activity state across page reloads

## Stateful/Resumable

Many apps support activities that span multiple sessions:

```mermaid theme={null}
graph TD
    subgraph Monday
        A[Student starts] --> B[Answers 10 questions] --> C[Leaves]
    end
    C -.-> |Tuesday — no activity| D
    subgraph Wednesday
        D[Student resumes] --> E[Answers 10 more] --> F[Completes]
    end
    style A fill:#e0f2fe,stroke:#0284c7
    style C fill:#fef9c3,stroke:#ca8a04
    style D fill:#e0f2fe,stroke:#0284c7
    style F fill:#dcfce7,stroke:#16a34a
```

Here, state lives in the **app's database**: progress, accumulated time, and status. The frontend cannot be the sole source of truth because it was not present for all sessions.

**Use stateful when:**

* Activities span multiple days or sessions
* The backend owns progress (server-validated answers, adaptive learning)
* Students need to resume where they left off

## The Key Insight

Timeback emits two types of learning events:

<Card title="TimeSpentEvent" icon="clock">
  *"Student engaged for N seconds"*

  **Per session**: Multiple events per activity run.
</Card>

<Card title="ActivityCompletedEvent" icon="circle-check">
  *"Student finished with these results"*

  **Per activity**: One event per activity run.
</Card>

For single-session activities, these two events naturally coincide; the student starts and finishes in one sitting, so time and completion are reported together.

Stateful activities do not. Time-spent should be reported per learning session (e.g., "12 minutes on Monday", "8 minutes on Wednesday"), while activity completion happens once, when the activity is truly done.

The SDK handles this by decoupling time tracking from completion. Time is reported continuously via periodic heartbeats. Completion is reported separately, either from the client or the server.

## How the models differ

| Aspect              | Single-session                                                                                  | Stateful                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Sessions**        | One                                                                                             | Multiple                                                                                                              |
| **Time tracking**   | Automatic heartbeats                                                                            | Automatic heartbeats                                                                                                  |
| **Completion**      | [`activity.end(...)`](/beta/build-on-timeback/sdk/activity-tracking/single-session#basic-usage) | [`timeback.activity.record(...)`](/beta/build-on-timeback/sdk/activity-tracking/stateful#server-recording-completion) |
| **State ownership** | Frontend                                                                                        | App database                                                                                                          |
| **Resume support**  | Not needed                                                                                      | `runId` persisted and reused                                                                                          |

Both models use the same client SDK for time tracking. The difference is in who reports completion and whether state persists across sessions.

<CardGroup cols={2}>
  <Card title="Single-session guide" icon="bolt" href="/beta/build-on-timeback/sdk/activity-tracking/single-session">
    Implementation guide for one-sitting activities.
  </Card>

  <Card title="Stateful guide" icon="arrows-rotate" href="/beta/build-on-timeback/sdk/activity-tracking/stateful">
    Implementation guide for multi-session activities.
  </Card>
</CardGroup>
