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

# Sessions

> The durable context a workflow runs in: its state, its runs and its lifecycle.

export const Scope = ({type, href}) => {
  const scopes = {
    workflow: ['the ', 'Workflow', ' blob type', '/blob-types/introduction#workflow'],
    scheduler: ['the ', 'Scheduler', ' blob type', '/blob-types/scheduler/overview'],
    onnx: ['the ', 'ONNX Model', ' blob type', '/blob-types/introduction#onnx'],
    worker: ['', 'blobhub-worker', ', which runs on your machines', '/worker/introduction']
  };
  const scope = scopes[type];
  if (!scope) {
    return <p>Unknown scope: {type}</p>;
  }
  return <p className="text-sm text-gray-600 dark:text-gray-400">
      Provided by {scope[0]}<strong>{scope[1]}</strong>{scope[2]}. · <a href={href || scope[3]}>Reference</a>
    </p>;
};

export const Shot = ({src, alt, caption}) => <Frame caption={caption}>
    <img className="block dark:hidden" src={src} alt={alt} />
    <img className="hidden dark:block" src={src.replace(/\.(png|svg)$/, '.dark.$1')} alt={alt} />
  </Frame>;

<Scope type="workflow" href="/blob-types/workflow/workflows/session-lifecycle" />

A session holds what outlives a single run. A run on its own forgets what it computed the moment it ends. What it
writes to its session stays there for the next run, for a person in a playground, and for an agent working through
the [worker](/general/agents-and-workers).

You create a session once, against a revision of a workflow: with the debugger's or a playground's **New Session**,
or a [Create Session](/blob-types/workflow/operations/create-session) call. The SDK creates one for a run that names
no session, or an alias no session has yet; a session id that does not exist is refused, never created.

## What a session holds

* **Session objects**, typed values each addressed by an alias, including the threads, graphs and files that
  people, workflows and agents share. [Threads & objects](/general/threads-and-objects) covers them.
* **The executions it has hosted**, each with the snapshot of the definition it ran and its own event log.
* **The events its activity raises**: the session closing or being deleted, an object written or deleted, an item
  posted to a thread, a batch applied to a graph. Any client can page through them;
  [Session Events](/blob-types/workflow/workflows/session-events) lists them.

A session can also carry an alias of your choosing, which works in place of its id wherever a run names its
session, in a [Create Execution](/blob-types/workflow/operations/create-execution) call or a schedule. Nothing
requires one.

## Runs inside a session

An execution starts only while its session is open. It runs under the rules of the session's blob, whatever
definition it names: a definition from another workflow, run [by reference](/general/workflows#workflow-references),
still resolves credentials for whoever started the run and imports only the modules the session's blob allows, and
it writes into this session. Two runs, or a run and a client reading over the API, hand values to each other
through the session's objects.

Two limits bound this, both resolved for the session's blob: `workflow.sessions_per_revision` caps how many
sessions a revision holds, and `workflow.executions_per_session` how many executions one session holds.
[Limits](/general/limits#workflow) has their values and the rest of the catalog.

## Lifecycle

A new session is `open` and fully writable. Closing it moves it to `closing`, stops every execution still running
in it, and settles into `closed` once each one has finished. A closed session is read-only, not hidden: its
objects, thread items, graph elements and runs all stay readable, and reopening it returns it to `open`.

Deleting is the other way out, from `open`, `closing` or `closed`. The session moves to `deleting`, every running
execution is stopped and waited on, and only then is anything removed: its objects and everything its threads,
graphs and files held, its executions with their snapshots, its events, and the session itself. A deleted session
cannot be brought back.

Both paths share one rule. The moment a session leaves `open`, every write is refused: uploading or deleting an
object, posting to a thread, changing a graph, starting a run. Nothing new lands while a session closes, and nothing
is purged while a run could still write into it.

A session belongs to its revision, not to the workflow. Committing the revision closes every session still open on
it, the same way a direct close would, and a new revision starts with no sessions at all. In the web app, the
debugger lists a revision's sessions and offers **New Session**, **Close Session**, **Reopen Session** and
**Delete Session**. [Session Lifecycle](/blob-types/workflow/workflows/session-lifecycle) has each transition and its
errors.

<Shot src="/general/images/sessions/sessions.png" alt="The debugger's session list for a workflow" caption="Sessions outlive the runs inside them, until they are closed or deleted." />

## Retention

A finished execution, with its events and data, is kept for 90 days by default, under the
`workflow.execution_retention_days` limit. A daily sweep removes older ones, in an open session or a closed one, and
each removal frees a slot under `workflow.executions_per_session`, so a session a schedule fires into every minute
stays below its limit.

A session and its objects are never removed by retention. They stay until the session is deleted, and deleting it
removes everything in it at once. [Retention](/general/limits#retention) covers the rules.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.