Shiny Py Optimize
Diagnose and fix performance problems in Shiny for Python apps, slow startup, sluggish...
Install
npx skills add posit-dev/skills --skill shiny-py-optimize -g -a claude-code -y- Repository
- posit-dev/skills551
- Category
- Business
- Updated
- 7d ago
- License
- MIT
- Context cost
- Mediumabout 3,000 tokens
- Runs scripts
- No, instructions only
What it does
Diagnose and fix performance problems in Shiny for Python apps, slow startup, sluggish interactions, blocking operations, and apps that struggle beyond a handful of concurrent users. Use when a Shiny for Python app is slow, hangs, recomputes too much, times out, or must support more users; when the user asks to "speed up", "optimize", or "make faster" a Python Shiny app; or when preparing a prototyped app for real-world traffic.
Optimizing Shiny for Python App Performance
Make an existing Shiny for Python app faster without changing what it does. The typical user has an app that worked fine for one or two developers and is now too slow or must support more users. Keep all app logic intact; prefer code changes over deployment tuning; resist rewrites.
Order of preference for every fix:
- Eliminate work that isn't needed (don't compute outputs nobody is looking at; don't compute with inputs that aren't ready).
- Reuse work that repeats (shared
@reactive.calc, module-level caches). - Accelerate unavoidable work (faster data formats, polars, push-down).
- Relocate work that blocks (
@reactive.extended_task), last resort; it buys concurrency, not raw speed.
One fact drives most Python-specific advice: Shiny runs reactive functions
serially on a single asyncio event loop, never concurrently, even when they
are async def, even across sessions in the same process. One blocking call
in any reactive function freezes every session in the process. async/
await alone never fixes this; only @reactive.extended_task does.
Workflow
1. Understand the complaint
Pin down what "slow" means and write it as a benchmark to beat:
- What feels slow? First page load? Every interaction? One specific action? Only when several people use it at once?
- How many concurrent users must it support? (1, 5, ~20, hundreds?)
- Where does it run? Locally, Posit Connect, Posit Connect Cloud, self-hosted (uvicorn behind nginx)?
- How big is the data, where does it live, and how often does it change?
- Core or Express? (
from shiny import ...vsfrom shiny.express import ...). Express top-level code runs once per session, a common silent trap (data-loading.md).


