Agent skill

Optimizing Streamlit Performance

by iusztinpaul in iusztinpaul/designing-real-world-ai-agents-workshop

Optimizing Streamlit app performance. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

Apache-2.0Auto-check passedBackend & APIs

Install Optimizing Streamlit Performance

skills CLI
$ npx skills add iusztinpaul/designing-real-world-ai-agents-workshop --skill optimizing-streamlit-performance -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install iusztinpaul/designing-real-world-ai-agents-workshop optimizing-streamlit-performance --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance .claude/skills/optimizing-streamlit-performance && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
optimizing-streamlit-performance
GitHub stars
513
Token cost
~2.2k tokens
SKILL.md length
432 words
Files
1
Skills in repo
23
Repo updated
First seen
Licence
Apache-2.0

At a glance

Optimizing Streamlit app performance. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

  • Rerunning too often
  • SKILL.md covers Caching, Fragments, Forms to batch interactions and Conditional rendering, plus 4 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Loading heavy content

What it does

Optimizing Streamlit Performance is an agent skill from iusztinpaul/designing-real-world-ai-agents-workshop. Optimizing Streamlit app performance. Use when apps are slow, rerunning too often, or loading heavy content. Covers caching, fragments, and static vs dynamic widget choices.

Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Caching. It works with Streamlit. The repository describes itself as: Hands-on workshop: Build a multi-agent AI system from scratch — Deep Research Agent + Writing Workflow served as MCP servers. Includes code, slides, and video. The licence is Apache-2.0.

When your agent uses it

  • Rerunning too often
  • Loading heavy content

Example prompts

  • “/optimizing-streamlit-performance”

Requirements

  • Python 3

What it can do on your machine

Read from SKILL.md and the folder at commit ea4f6e9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.streamlit.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Optimizing Streamlit Performance loads about 2.2k tokens when it runs. Until then it costs about 52 tokens; SKILL.md has 432 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~52
When it runs · the whole SKILL.md, loaded when a task matches
~2.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from iusztinpaul/designing-real-world-ai-agents-workshop at commit ea4f6e9, republished under its Apache-2.0 licence (© iusztinpaul). 432 words, ~2,183 tokens.

Download SKILL.mdSave it as .claude/skills/optimizing-streamlit-performance/SKILL.md (or your agent's skills folder).
name
optimizing-streamlit-performance
description
Optimizing Streamlit app performance. Use when apps are slow, rerunning too often, or loading heavy content. Covers caching, fragments, and static vs dynamic widget choices.
license
Apache-2.0

Streamlit performance

Performance is the biggest win. Without caching and fragments, your app reruns everything on every interaction.

Caching

@st.cache_data for data

Use for any function that loads or computes data.

python
# BAD: Recomputes on every rerun
def load_data(path):
    return pd.read_csv(path)

# GOOD: Cached
@st.cache_data
def load_data(path):
    return pd.read_csv(path)
@st.cache_resource for connections

Use for connections, API clients, ML models—objects that can't be serialized.

python
@st.cache_resource
def get_connection():
    return st.connection("snowflake")

@st.cache_resource
def load_model():
    return torch.load("model.pt")

Critical warning: Never mutate @st.cache_resource returns—changes affect all users:

python
# BAD: Mutating shared resource
@st.cache_resource
def get_config():
    return {"setting": "default"}

config = get_config()
config["setting"] = "custom"  # Affects ALL users!

# GOOD: Copy before modifying
config = get_config().copy()
config["setting"] = "custom"

Cleanup with on_release: Clean up resources when evicted from cache:

python
def cleanup_connection(conn):
    conn.close()

@st.cache_resource(on_release=cleanup_connection)
def get_database():
    return create_connection()
TTL for fresh data
python
@st.cache_data(ttl="5m")  # 5 minutes
def get_metrics():
    return api.fetch()

@st.cache_data(ttl="1h")  # 1 hour
def load_reference_data():
    return pd.read_csv("large_reference.csv")

Guidelines:

  • Real-time dashboards → ttl="1m" or less
  • Metrics/reports → ttl="5m" to ttl="15m"
  • Reference data → ttl="1h" or more
  • Static data → No TTL
Prevent unbounded cache growth

Important: Caches without ttl or max_entries can grow indefinitely and cause memory issues. For any cached function that stores changing objects (user-specific data, parameterized queries), set limits:

python
# BAD: Unbounded cache - memory will grow indefinitely
@st.cache_data
def get_user_data(user_id):
    return fetch_user(user_id)

# GOOD: Bounded cache with TTL
@st.cache_data(ttl="1h")
def get_user_data(user_id):
    return fetch_user(user_id)

# GOOD: Bounded cache with max entries
@st.cache_data(max_entries=100)
def get_user_data(user_id):
    return fetch_user(user_id)

Use ttl for time-based expiration OR max_entries for size-based limits. You usually don't need both.

Caching anti-patterns

Don't cache functions that read widgets:

python
# BAD: Widget inside cached function
@st.cache_data
def filtered_data():
    query = st.text_input("Query")  # Widget inside cached function!
    return df[df["name"].str.contains(query)]

# GOOD: Pass widget values as parameters
@st.cache_data
def filtered_data(query: str):
    return df[df["name"].str.contains(query)]

query = st.text_input("Query")
result = filtered_data(query)

Cache at the right granularity:

python
# BAD: Caching too much - new cache entry per filter value
@st.cache_data
def get_and_filter_data(filter_value):
    data = load_all_data()  # Expensive!
    return data[data["col"] == filter_value]

# GOOD: Cache the expensive part, filter separately
@st.cache_data(ttl="1h")
def load_all_data():
    return fetch_from_database()

data = load_all_data()
filtered = data[data["col"] == filter_value]

Fragments

Use @st.fragment to isolate reruns for self-contained UI pieces.

python
# BAD: Full app reruns
st.metric("Users", get_count())
if st.button("Refresh"):
    st.rerun()

# GOOD: Only fragment reruns
@st.fragment
def live_metrics():
    st.metric("Users", get_count())
    st.button("Refresh")

live_metrics()

For auto-refreshing metrics, use run_every:

python
@st.fragment(run_every="30s")
def auto_refresh_metrics():
    st.metric("Users", get_count())

auto_refresh_metrics()

Use for: live metrics, refresh buttons, interactive charts that don't affect global state.

Forms to batch interactions

By default, every widget interaction triggers a full rerun. Use st.form to batch multiple inputs and only rerun on submit.

python
# BAD: Reruns on every keystroke and selection
name = st.text_input("Name")
email = st.text_input("Email")
role = st.selectbox("Role", ["Admin", "User"])

# GOOD: Single rerun when user clicks Submit
with st.form("user_form"):
    name = st.text_input("Name")
    email = st.text_input("Email")
    role = st.selectbox("Role", ["Admin", "User"])
    submitted = st.form_submit_button("Submit")

if submitted:
    save_user(name, email, role)

Use border=False for seamless inline forms that don't look like forms:

python
with st.form("search", border=False):
    with st.container(horizontal=True):
        query = st.text_input("Search", label_visibility="collapsed")
        st.form_submit_button(":material/search:")

When to use forms:

  • Multiple related inputs (signup, filters, settings)
  • Text inputs where typing triggers expensive operations
  • Any UI where "submit" semantics make sense

When NOT to use forms: If inputs depend on each other (e.g., selecting a country should update available cities), forms won't work since there's no rerun until submit.

Show full SKILL.md (171 more words)Show less

Conditional rendering

This is critical and often missed.

Layout containers like st.tabs, st.expander, and st.popover always render all their content, even when hidden or collapsed.

To render content only when needed, use elements like st.segmented_control, st.toggle, or @st.dialog with conditional logic:

python
# BAD: Heavy content loads even when tab not visible
tab1, tab2 = st.tabs(["Light", "Heavy"])
with tab2:
    expensive_chart()  # Always computed!

# GOOD: Content only loads when selected
view = st.segmented_control("View", ["Light", "Heavy"])
if view == "Heavy":
    expensive_chart()  # Only computed when selected
python
# BAD: Expander content always loads
with st.expander("Advanced options"):
    heavy_computation()  # Runs even when collapsed!

# GOOD: Toggle controls loading
if st.toggle("Show advanced options"):
    heavy_computation()  # Only runs when toggled on

Pre-computation

Move expensive work outside the main flow:

  • Compute aggregations in SQL/dbt, not Python
  • Pre-compute metrics in scheduled jobs
  • Use materialized views for complex queries

Large data handling

For datasets under ~100M rows
python
@st.cache_data
def load_data():
    return pd.read_parquet("large_file.parquet")
For very large datasets (over ~100M rows)

Note: This is only an escape hatch when serialization becomes too slow. In most cases, data this large shouldn't be loaded entirely into memory—prefer using a database that queries and loads data on demand.

@st.cache_data uses pickle which slows with huge data. Use @st.cache_resource instead:

python
@st.cache_resource  # No serialization overhead
def load_huge_data():
    return pd.read_parquet("huge_file.parquet")

# WARNING: Don't mutate the returned DataFrame!
Sampling for exploration

When exploring large datasets, load a random sample instead of the full data:

python
@st.cache_data(ttl="1h")
def load_sample(n=10000):
    df = pd.read_parquet("huge.parquet")
    return df.sample(n=n)

Multithreading

Custom threads cannot call Streamlit commands (no session context).

python
import threading

def fetch_in_background(url, results, index):
    results[index] = requests.get(url).json()  # No st.* calls!

# Collect results, then display in main thread
results = [None] * len(urls)
threads = [
    threading.Thread(target=fetch_in_background, args=(url, results, i))
    for i, url in enumerate(urls)
]
for t in threads:
    t.start()
for t in threads:
    t.join()

# Now display in main thread
for result in results:
    st.write(result)

Prefer alternatives when possible:

  • @st.cache_data for expensive computations
  • @st.fragment(run_every="5s") for periodic updates

References

© iusztinpaul, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance of iusztinpaul/designing-real-world-ai-agents-workshop.

Open the folder on GitHubat commit ea4f6e9

Compare with similar skills

Optimizing Streamlit Performance next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Optimizing Streamlit Performance compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Optimizing Streamlit Performance this skilliusztinpaul/designing-real-world-ai-agents-workshop513—~2.2kAutomated safety check: PassApache-2.0
Writing Streamlit AppsPostHog/posthog40k—~1.5kAutomated safety check: PassCustom licence
Stripe Projectsfossasia/eventyay1.7k5 repos~2kAutomated safety check: NotesApache-2.0
FoundatioFoundatioFx/Foundatio2.1k—~3.9kAutomated safety check: PassApache-2.0
Wp Block Themesgambitph/Stackable3503 repos~985Automated safety check: PassGPL-3.0
Wp Performancegambitph/Stackable3503 repos~1.5kAutomated safety check: PassGPL-3.0

Similar skills

  • Writing Streamlit Apps

    PostHog/posthog

    Official

    Write Streamlit app source code that runs well in a PostHog sandbox — the posthogapps.query() bridge for reading PostHog data, the packages baked into the sandbox image, caching and session state…

    40k GitHub stars~1.5k tokensUpdated today
    DevelopmentAuto-check passed
  • Stripe Projects

    fossasia/eventyay

    A skill your agent uses when the user wants to provision infrastructure or third-party services using Stripe Projects.

    1.7k GitHub starsUsed in 5 repos~2k tokens
    Backend & APIsAuto-check: notes
  • Foundatio

    FoundatioFx/Foundatio

    A skill your agent uses when working with Foundatio infrastructure abstractions for .NET -- caching, queuing, messaging, file storage, distributed locking, or background jobs.

    2.1k GitHub stars~3.9k tokensUpdated today
    Backend & APIsAuto-check passed
  • Wp Block Themes

    gambitph/Stackable

    A skill your agent uses when developing WordPress block themes: theme.json (global settings/styles), templates and template parts, patterns, style variations, and Site Editor troubleshooting (style…

    350 GitHub starsUsed in 3 repos~985 tokens
    Backend & APIsAuto-check passed
  • Wp Performance

    gambitph/Stackable

    A skill your agent uses when investigating or improving WordPress performance (backend-only agent): profiling and measurement (WP-CLI profile/doctor, Server-Timing, Query Monitor via REST headers)…

    350 GitHub starsUsed in 3 repos~1.5k tokens
    Backend & APIsAuto-check passed
  • Effect Portable Patterns

    millionco/expect

    Portable Effect patterns for robust promise execution. An agent skill from millionco/expect.

    3.6k GitHub stars~3.7k tokensUpdated 5 mo ago
    Backend & APIsAuto-check passed

More from iusztinpaul/designing-real-world-ai-agents-workshop

All 23 skills in this repo
  • Building Streamlit Custom Components V2

    iusztinpaul/designing-real-world-ai-agents-workshop

    Builds bidirectional Streamlit Custom Components v2 (CCv2) using st.components.v2.component.

    513 GitHub stars~2.8k tokensUpdated 4 mo ago
    Auto-check passed
  • Building Streamlit Chat UI

    iusztinpaul/designing-real-world-ai-agents-workshop

    Building chat interfaces in Streamlit. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

    513 GitHub stars~1.4k tokensUpdated 4 mo ago
    Auto-check passed
  • Building Streamlit Dashboards

    iusztinpaul/designing-real-world-ai-agents-workshop

    Building dashboards in Streamlit. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

    513 GitHub stars~1.1k tokensUpdated 4 mo ago
    Auto-check passed
  • Building Streamlit Multipage Apps

    iusztinpaul/designing-real-world-ai-agents-workshop

    Building multi-page Streamlit apps. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

    513 GitHub stars~1.6k tokensUpdated 4 mo ago
    Auto-check passed
  • Choosing Streamlit Selection Widgets

    iusztinpaul/designing-real-world-ai-agents-workshop

    Choosing the right Streamlit selection widget. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

    513 GitHub stars~1.1k tokensUpdated 4 mo ago
    Auto-check passed
  • Connecting Streamlit To Snowflake

    iusztinpaul/designing-real-world-ai-agents-workshop

    Connecting Streamlit apps to Snowflake. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop.

    513 GitHub stars~1.3k tokensUpdated 4 mo ago
    Auto-check passed

Works with

Categories

Questions about Optimizing Streamlit Performance

What does Optimizing Streamlit Performance do?

Optimizing Streamlit app performance. An agent skill from iusztinpaul/designing-real-world-ai-agents-workshop. Optimizing Streamlit Performance is an agent skill from iusztinpaul/designing-real-world-ai-agents-workshop. Optimizing Streamlit app performance.

When should I use Optimizing Streamlit Performance?

Optimizing Streamlit Performance fits situations like: rerunning too often; loading heavy content.

How do I install Optimizing Streamlit Performance in Claude Code?

Run `npx skills add iusztinpaul/designing-real-world-ai-agents-workshop --skill optimizing-streamlit-performance -a claude-code`. Or copy the skill folder (.agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance in iusztinpaul/designing-real-world-ai-agents-workshop) into .claude/skills/optimizing-streamlit-performance in your project. Claude Code loads it when a task matches its description.

How do I install Optimizing Streamlit Performance in Codex?

Run `npx skills add iusztinpaul/designing-real-world-ai-agents-workshop --skill optimizing-streamlit-performance -a codex`. Or copy the skill folder (.agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance in iusztinpaul/designing-real-world-ai-agents-workshop) into .agents/skills/optimizing-streamlit-performance in your project. Codex loads it when a task matches its description.

Can I use Optimizing Streamlit Performance in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add iusztinpaul/designing-real-world-ai-agents-workshop --skill optimizing-streamlit-performance -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/optimizing-streamlit-performance, .gemini/skills/optimizing-streamlit-performance, .github/skills/optimizing-streamlit-performance and .opencode/skills/optimizing-streamlit-performance in your project.

What does Optimizing Streamlit Performance need to run?

SKILL.md names no scripts, command-line tools or credentials: Optimizing Streamlit Performance is instructions for the agent only. Our summary lists: Python 3.

Does Optimizing Streamlit Performance access the network?

SKILL.md names 1 domain. As links in the text: docs.streamlit.io. This is read from the text; nothing was executed.

Is Optimizing Streamlit Performance safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Optimizing Streamlit Performance use?

Optimizing Streamlit Performance is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Optimizing Streamlit Performance use?

About 2.2k tokens (SKILL.md is roughly 8.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Optimizing Streamlit Performance?

Skills that share tags, products or a category with Optimizing Streamlit Performance: Writing Streamlit Apps (PostHog/posthog, 40k stars), Stripe Projects (fossasia/eventyay, 1.7k stars), Foundatio (FoundatioFx/Foundatio, 2.1k stars) and Wp Block Themes (gambitph/Stackable, 350 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Optimizing Streamlit Performance?

iusztinpaul (a GitHub user) maintains it in iusztinpaul/designing-real-world-ai-agents-workshop, which has 513 GitHub stars. The repository holds 23 skills in this directory. The repository was last updated on June 3, 2026.

Source: iusztinpaul/designing-real-world-ai-agents-workshop on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.