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

# State management

> Learn how to maintain persistent data across interactions in Gradio

State management allows your Gradio applications to remember information between user interactions. This is essential for building applications that need to track conversation history, maintain user sessions, or accumulate data over multiple steps.

## What is state?

In Gradio, "state" refers to data that persists across multiple function calls within a user session. Without state, each interaction is independent - the application has no memory of previous inputs or outputs.

State in Gradio is:

* **Session-specific**: Each user has their own isolated state
* **Temporary**: State resets when the user refreshes the page or their session expires
* **Invisible**: State components don't appear in the UI
* **Flexible**: Can store any Python object (lists, dicts, custom objects)

## The State component

The simplest way to manage state is with the `State` component:

```python theme={null}
import gradio as gr

def increment(count):
    count = count + 1
    return count, f"Count: {count}"

with gr.Blocks() as demo:
    state = gr.State(value=0)  # Initialize state to 0
    output = gr.Textbox(label="Current Count")
    button = gr.Button("Increment")
    
    button.click(
        fn=increment,
        inputs=state,  # State is an input
        outputs=[state, output]  # State is also an output
    )

demo.launch()
```

Key points:

* Initialize state with a default value: `gr.State(value=0)`
* Include state in both `inputs` and `outputs` to update it
* Return the updated state from your function

## Common state patterns

### Accumulating chat history

Maintain conversation context in a chatbot:

```python theme={null}
import gradio as gr
import random
import time

def respond(message, chat_history):
    bot_message = random.choice(["How are you?", "Nice day!", "Interesting!"])
    chat_history.append({"role": "user", "content": message})
    chat_history.append({"role": "assistant", "content": bot_message})
    time.sleep(1)
    return "", chat_history

with gr.Blocks() as demo:
    chatbot = gr.Chatbot()
    msg = gr.Textbox(placeholder="Type a message...")
    clear = gr.ClearButton([msg, chatbot])
    
    msg.submit(respond, [msg, chatbot], [msg, chatbot])

demo.launch()
```

The chatbot component itself acts as state, storing the message history.

### Multi-step workflows

Collect information across multiple interactions:

```python theme={null}
import gradio as gr

def collect_name(name, data):
    data = data or {}
    data["name"] = name
    return data, f"Hello {name}! Now enter your age."

def collect_age(age, data):
    data["age"] = age
    return data, f"Thanks! You are {age} years old."

with gr.Blocks() as demo:
    state = gr.State(value={})
    output = gr.Textbox(label="Status")
    
    name_input = gr.Textbox(label="Name")
    name_btn = gr.Button("Submit Name")
    
    age_input = gr.Number(label="Age")
    age_btn = gr.Button("Submit Age")
    
    name_btn.click(collect_name, [name_input, state], [state, output])
    age_btn.click(collect_age, [age_input, state], [state, output])

demo.launch()
```

### Maintaining counters

Track user actions or iterations:

```python theme={null}
import gradio as gr

def track_clicks(click_count, click_history):
    click_count += 1
    click_history.append(f"Click #{click_count}")
    return click_count, click_history, "\n".join(click_history)

with gr.Blocks() as demo:
    click_count = gr.State(value=0)
    click_history = gr.State(value=[])
    
    output = gr.Textbox(label="Click History", lines=5)
    button = gr.Button("Click Me!")
    
    button.click(
        fn=track_clicks,
        inputs=[click_count, click_history],
        outputs=[click_count, click_history, output]
    )

demo.launch()
```

## State in Interface

When using `gr.Interface`, you can use the special `"state"` string shortcut:

```python theme={null}
import gradio as gr

def process_with_state(text, state):
    state = state or []
    state.append(text)
    history = "\n".join(state)
    return history, state

demo = gr.Interface(
    fn=process_with_state,
    inputs=["textbox", "state"],
    outputs=["textbox", "state"]
)

demo.launch()
```

<Warning>
  When using Interface with state, there must be exactly one state input and one state output.
</Warning>

## Complex state objects

State can hold any Python object, including custom classes:

```python theme={null}
import gradio as gr
from dataclasses import dataclass
from typing import List

@dataclass
class UserSession:
    name: str = ""
    messages: List[str] = None
    preferences: dict = None
    
    def __post_init__(self):
        if self.messages is None:
            self.messages = []
        if self.preferences is None:
            self.preferences = {}

def initialize():
    return UserSession(), "Session initialized"

def add_message(message, session):
    session.messages.append(message)
    count = len(session.messages)
    return session, f"Total messages: {count}"

with gr.Blocks() as demo:
    session = gr.State(value=UserSession())
    status = gr.Textbox(label="Status")
    
    init_btn = gr.Button("Initialize Session")
    init_btn.click(initialize, None, [session, status])
    
    msg_input = gr.Textbox(label="Message")
    msg_btn = gr.Button("Add Message")
    msg_btn.click(add_message, [msg_input, session], [session, status])

demo.launch()
```

## State vs component values

### When to use State

Use `gr.State` when you need to:

* Store data that shouldn't be visible to users
* Maintain large data structures (models, datasets)
* Track internal application state
* Keep intermediate computation results

```python theme={null}
import gradio as gr

# Good use of State: internal counter
with gr.Blocks() as demo:
    counter = gr.State(value=0)  # Not visible
    display = gr.Number(label="Count")  # Visible
    btn = gr.Button("Increment")
    
    btn.click(
        lambda c: (c + 1, c + 1),
        counter,
        [counter, display]
    )
```

### When to use regular components

Use regular components as "state" when:

* Users need to see the persisted value
* The state is simple and fits a component type
* You want users to potentially edit the state

```python theme={null}
import gradio as gr

# Good use of visible component as state: editable history
with gr.Blocks() as demo:
    history = gr.Textbox(label="History", lines=10)
    new_entry = gr.Textbox(label="Add Entry")
    btn = gr.Button("Add")
    
    btn.click(
        lambda entry, hist: hist + "\n" + entry,
        [new_entry, history],
        history
    )
```

## Initializing state

### Default values

Set initial state when creating the component:

```python theme={null}
import gradio as gr

with gr.Blocks() as demo:
    # Simple types
    counter = gr.State(value=0)
    text_state = gr.State(value="")
    list_state = gr.State(value=[])
    dict_state = gr.State(value={})
    
    # Complex objects
    custom_state = gr.State(value={"user": "Alice", "score": 100})
```

### Dynamic initialization

Initialize state based on computations:

```python theme={null}
import gradio as gr
import time

def init_with_timestamp():
    return {"started_at": time.time(), "actions": []}

with gr.Blocks() as demo:
    session = gr.State(value=None)
    status = gr.Textbox()
    
    demo.load(
        lambda: (init_with_timestamp(), "Session started"),
        None,
        [session, status]
    )
```

## Clearing state

Reset state to initial values:

```python theme={null}
import gradio as gr

def reset():
    return 0, "", "State cleared"

with gr.Blocks() as demo:
    counter = gr.State(value=0)
    messages = gr.Textbox(label="Messages")
    status = gr.Textbox(label="Status")
    
    increment_btn = gr.Button("Increment")
    reset_btn = gr.Button("Reset")
    
    increment_btn.click(
        lambda c: (c + 1, f"Count: {c + 1}", ""),
        counter,
        [counter, messages, status]
    )
    
    reset_btn.click(
        reset,
        None,
        [counter, messages, status]
    )
```

Or use the `ClearButton`:

```python theme={null}
import gradio as gr

with gr.Blocks() as demo:
    state = gr.State(value=[])
    textbox = gr.Textbox()
    
    # Clears both state and textbox to their default values
    clear_btn = gr.ClearButton([state, textbox])
```

## State limitations

### Session isolation

Each user session has independent state:

```python theme={null}
import gradio as gr

# This counter is per-user, not global
with gr.Blocks() as demo:
    counter = gr.State(value=0)
    output = gr.Number()
    btn = gr.Button("Increment")
    
    btn.click(
        lambda c: (c + 1, c + 1),
        counter,
        [counter, output]
    )
```

User A clicking "Increment" doesn't affect User B's counter.

<Note>
  If you need to share data across all users, use global Python variables or a database. However, be careful with thread safety!
</Note>

### Not persistent across refreshes

State resets when the page refreshes:

```python theme={null}
import gradio as gr

# This counter resets to 0 when user refreshes the page
with gr.Blocks() as demo:
    counter = gr.State(value=0)
    # User increments to 10, refreshes page → back to 0
```

For true persistence, use external storage (databases, files, etc.).

### Memory considerations

State is stored in server memory:

```python theme={null}
import gradio as gr

# Careful! Large state uses server memory
with gr.Blocks() as demo:
    # This could use a lot of memory with many users
    large_data = gr.State(value=[0] * 1000000)
```

<Warning>
  Avoiding storing very large objects in State, especially with many concurrent users. Consider using file storage or databases for large data.
</Warning>

## Advanced patterns

### Conditional state updates

Update state only under certain conditions:

```python theme={null}
import gradio as gr

def conditional_update(value, threshold, state):
    if value > threshold:
        state.append(value)
        return state, f"Added {value} to state"
    return state, f"Value {value} too low"

with gr.Blocks() as demo:
    state = gr.State(value=[])
    value_input = gr.Number(label="Value")
    threshold = gr.Number(label="Threshold", value=10)
    status = gr.Textbox(label="Status")
    btn = gr.Button("Check and Add")
    
    btn.click(
        conditional_update,
        [value_input, threshold, state],
        [state, status]
    )
```

### State with multiple functions

Pass state through a chain of operations:

```python theme={null}
import gradio as gr

def step1(input, state):
    state["step1_result"] = input.upper()
    return state, state["step1_result"]

def step2(state):
    result = state["step1_result"] + "!!!"
    state["step2_result"] = result
    return state, result

with gr.Blocks() as demo:
    state = gr.State(value={})
    inp = gr.Textbox(label="Input")
    mid = gr.Textbox(label="After Step 1")
    out = gr.Textbox(label="After Step 2")
    btn = gr.Button("Process")
    
    btn.click(
        step1, [inp, state], [state, mid]
    ).then(
        step2, state, [state, out]
    )
```

## See also

* [Components](/concepts/components) - State is a special component
* [Events](/concepts/events) - How to update state via events
* [Blocks](/concepts/blocks) - Using state in custom layouts
* [ChatInterface](/concepts/chat-interface) - Built-in chat history state management


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