Skip to content
Reviewed by Vikas Mittal Oct 28, 2026

Home › Guides › Streamlit Tutorial

Tutorial · 2026

Streamlit Tutorial 2026: Build Your First Data App, Free-Tier Limits and When Not to Use It

This Streamlit tutorial shows you how to turn a Python script into a shareable web app: you write plain top-to-bottom Python, Streamlit reruns the whole file on every click, and caching plus session state keep it fast. Community Cloud hosts it free, capped at 2.7 GB of memory per app.

28 October 202611 min readBy the 360 Digital Transformation Editorial Team
Key takeaways
  • One idea explains Streamlit. Every widget interaction reruns your whole script from line 1, so st.session_state holds what must survive and st.cache_data holds what you refuse to recompute.
  • The free tier is real but small. Streamlit's docs list 690 MB to 2.7 GB of memory per app on Community Cloud, and apps sleep after 12 hours without traffic.
  • Pin your version. The docs warn that an unpinned app can be upgraded without your knowledge, which is the most common cause of "it worked last week".
  • It scales further than critics admit. Snowflake's engineering blog describes more than 500 internal Streamlit apps covering financial reporting, security monitoring and product analytics.
  • It is still the wrong tool for customer-facing products needing per-user data isolation, instant interaction and real auth. Internal tools and demos are its lane.

You have a working Python notebook. It loads a CSV, cleans three columns, groups by region and plots a chart your manager wants every Monday. So on Monday you run the notebook, screenshot the chart, and paste it into an email. Again. Streamlit exists to end that loop, and about twenty lines of Python is all it takes, which is why it has become the default way Indian data and AI teams put a first interface over their work.

What Streamlit Is, and the Rerun Model Behind Every Streamlit Tutorial

Streamlit is an open-source Python library that renders a web app from a normal Python script. No route table, no template language, no JavaScript build step. You write st.selectbox("Region", regions) and a dropdown appears, and the function returns whatever the user picked. The latest release is 1.66.0, dated 14 October 2026 in Streamlit's own release notes.

The part most tutorials bury on page four is the execution model. Streamlit does not bind an event handler to that dropdown. When the user changes it, Streamlit reruns your entire script from the first line to the last, with the dropdown now returning the new value. Your app is not a long-lived object holding state. It is a function that gets called again, completely, on every interaction. Accept that and the two APIs below stop looking like workarounds: anything you want to keep has to live somewhere Streamlit does not throw away, and anything expensive has to be cached or you pay for it on every click.

The Streamlit rerun model

A click does not fire a callback. It re-executes your whole file, so only cache and session state carry anything forward.

How a Streamlit rerun works A widget interaction makes Streamlit re-execute app.py from the first line. Session state and cached functions survive the rerun, while ordinary Python variables are re-created from scratch each time. 1. User moves a slider or types, or clicks event 2. app.py reruns from line 1, every line new frame 3. Browser repaints widgets keep their values What the rerun on step 2 reads back, and what it destroys st.session_state Survives. One dict per browser tab, cleared on refresh. @st.cache_data Survives. Shared across all users, keyed on the arguments. Plain variables Destroyed and rebuilt. counter = 0 resets to 0 on every click. read back cache hit re-created Rule of thumb: if a value must outlive a click, it belongs in session state. If computing it costs more than a few hundred milliseconds, it belongs behind a cache decorator.

Behaviour described in Streamlit's caching and session state documentation, checked 28 October 2026.

Streamlit Tutorial: Build Your First Data App in 20 Lines

Install it and run the bundled demo first. If streamlit hello opens in your browser, your environment is fine and every later problem is your code, not your setup.

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install streamlit pandas
streamlit hello                     # opens the demo app on localhost:8501

Now the real thing. Save this as app.py. It takes a CSV upload, lets the user filter it, and draws a chart, which covers most of what internal data apps actually do.

import pandas as pd
import streamlit as st

st.set_page_config(page_title="Regional sales", layout="wide")
st.title("Regional sales explorer")

uploaded = st.file_uploader("Upload a sales CSV", type="csv")
if uploaded is None:
    st.info("Waiting for a file. It needs region, month and revenue columns.")
    st.stop()

df = pd.read_csv(uploaded)
regions = sorted(df["region"].unique())
picked = st.multiselect("Regions", regions, default=regions)
floor = st.slider("Minimum revenue", 0, int(df["revenue"].max()), 0)

view = df[df["region"].isin(picked) & (df["revenue"] >= floor)]
st.metric("Rows shown", len(view), delta=len(view) - len(df))
st.bar_chart(view.groupby("month")["revenue"].sum())
st.dataframe(view, use_container_width=True)

Run it with streamlit run app.py. Two details are worth stealing. st.stop() halts the run cleanly instead of letting the rest of the page crash on a missing file, which is the idiomatic way to say "the user has not given me enough yet". And st.metric with a delta gives you the green or red arrow free. Notice what is absent: no if __name__ == "__main__", no server setup, no HTML. The script is the app.

Keep a two-person analytics team at a mid-size logistics firm in Pune in mind for the rest of this. One Postgres replica, a Monday reporting ritual, no front-end developer. That team is Streamlit's centre of gravity, and most of the calls below are theirs.

Streamlit Session State and Caching: The Two APIs That Decide Whether Your App Feels Fast

Here is the bug every beginner writes. Add a counter to the app above and it refuses to count.

# BROKEN: resets on every click, because the whole script reruns
count = 0
if st.button("Add one"):
    count += 1
st.write(count)        # prints 0 or 1, never 2

# WORKING: streamlit session state survives the rerun
if "count" not in st.session_state:
    st.session_state.count = 0
if st.button("Add one"):
    st.session_state.count += 1
st.write(st.session_state.count)

Streamlit session state is a dict scoped to one browser session. It survives reruns, not a page refresh, and it is not shared between users. Use it for anything with a sequence: a chat history, a multi-step form, a pointer to the selected row.

Streamlit cache_data, and the mistake that makes caching pointless

@st.cache_data memoises a return value keyed on the arguments, shared across every user of the app. @st.cache_resource is its sibling for things you want exactly one of, such as a connection or a loaded model.

@st.cache_data(ttl=600, max_entries=50, show_spinner="Querying Postgres...")
def load_sales(region: str, month: str) -> pd.DataFrame:
    # Runs once per (region, month), then served from memory for 600s
    return pd.read_sql(
        "SELECT * FROM sales WHERE region = %s AND month = %s",
        get_connection(), params=(region, month),
    )

@st.cache_resource
def get_connection():
    return psycopg2.connect(**st.secrets["postgres"])   # one per app, not per rerun

The mistake is caching a function whose arguments change on every rerun, which buys you a 0% hit rate and a growing memory footprint. Pass a DataFrame in and Streamlit has to hash it to build the key; on a wide frame that hashing can cost more than the work you were skipping. Pass the small things, the region code and the date range, and let the cached function fetch the big thing itself.

The opinionated bit: learn cache_data second, right after your first chart, not last. Most tutorials treat it as an optimisation chapter. On a free-tier host it is the difference between an app your manager opens twice and one they bookmark.

Call What it does The gotcha nobody mentions
st.dataframe(df) Interactive sortable table st.table is the static one. Sending 500k rows to the browser hangs the tab.
st.selectbox / multiselect Returns the chosen value The value, not an index. Changing it triggers a full rerun.
st.file_uploader Returns a file-like object There is a per-file cap; raise server.maxUploadSize before users meet it.
st.session_state Per-session dict that survives reruns Cleared by a browser refresh. It is not a database.
@st.cache_data Memoises a return value Shared across users. Never cache a per-user result without the user in the key.
st.form Batches widgets into one submit The cure for apps that rerun on every keystroke.
st.secrets Reads secrets like a dict A missing key raises at render time, in front of the user.
@st.fragment Reruns one part of the page Release 1.63.0 added event-scoped fragment reruns keyed on the decorator. Reach for it when the app is slow, not before.

API behaviour and the 1.63.0 note taken from Streamlit's API reference and 2026 release notes, checked 28 October 2026.

How to Deploy a Streamlit App Free on Community Cloud

The deploy story is the best thing about Streamlit: three files and about four minutes. Push to GitHub, point Community Cloud at the repo, branch and entrypoint, and it builds the container for you.

# requirements.txt : pin everything, including streamlit itself
streamlit==1.66.0
pandas==2.2.3
psycopg2-binary==2.9.9

# .streamlit/secrets.toml : local only, add to .gitignore
[postgres]
host = "db.internal"
user = "readonly"
password = "rotate-me-after-deploy"

Three things from Streamlit's deployment docs that will save you an afternoon. Do not list standard library modules such as math or random in requirements.txt; the docs call that out and it is a common cause of a failed build. Streamlit is preinstalled, so you list it only to pin the version, which the docs recommend because an unpinned app can be upgraded without your knowledge. And never commit secrets.toml: paste its contents into the Advanced settings box at deploy time and edit them from the app's settings later.

If you have worked through our Power BI tutorial for beginners, the contrast is instructive. Power BI gives you governed, licensed distribution; Streamlit gives you a URL in four minutes. Both answer different questions, and the Data Analyst course builds the licensed route live through PL-300.

Community Cloud free tier, in three numbers

Enough for a portfolio app or an internal tool. Not enough to load a large model into memory.

2.7 GB
Maximum memory per app, against a 690 MB minimum, on Streamlit's Manage your app page
12 hours
No traffic and the app sleeps; anyone with view access wakes it by visiting
1.66.0
Current Streamlit release, dated 14 October 2026 in the official release notes

From Streamlit's Community Cloud documentation and 2026 release notes, checked 28 October 2026. The docs state these limits may change at any time without notice.

Streamlit Community Cloud Limits: Where Apps Die, and the Arithmetic Behind It

Streamlit's docs say every Community Cloud user gets the same resources and the same limits, and that apps crossing them may be throttled or stop working. That stays abstract until you convert it into rows. A pandas DataFrame of 64-bit floats costs 8 bytes per cell, so ten numeric columns is 80 bytes per row. That is arithmetic, not a benchmark, and df.memory_usage(deep=True).sum() will confirm it on your own data.

How many rows fit in 2.7 GB

Ten float64 columns at 8 bytes per cell. String columns are far worse, often 5 to 10 times this.

1 million rowsa year of daily orders
80 MBcomfortable
5 million rowsa mid-size transactions table
400 MBfine
10 million rowsplus one cached copy
800 MBwatch the cache
20 million rowsfiltered copies add up
1.6 GBrisky
34 million rowsthe documented ceiling
2.7 GBapp dies

Row counts are arithmetic from 8 bytes per float64 cell against the 2.7 GB ceiling in Streamlit's docs, checked 28 October 2026.

Raw size is rarely what kills a free-tier app. Copies are. The cached loader holds the full frame, your filter makes a second, a groupby makes a third, and cache_data keeps one entry per argument combination anyone has tried; a 400 MB table becomes 2 GB of cache by Thursday. Set a ttl and max_entries, and push filtering into SQL. Also read: our DuckDB tutorial, which pairs with Streamlit perfectly here, because DuckDB aggregates in C++ and hands back a hundred rows to render.

For more headroom, Hugging Face's Hub docs list CPU Basic at 2 vCPU, 16 GB memory and 50 GB disk at no hourly cost, with CPU Upgrade at 8 vCPU and 32 GB for 0.03 US dollars per hour, though their docs note a compute Space can require a paid plan. Past that you provision your own container and own TLS, auth and uptime, which is where a cloud and DevOps skill set pays for itself.

Where Streamlit Shows Up in Real Work, and the 500-App Case Study

The most useful public example is Snowflake's engineering blog, which describes an internal estate of more than 500 Streamlit apps. The part worth reading twice is how it began: a handful of experimental dashboards from one team, which grew into a platform carrying financial reporting, security monitoring and product analytics. Nobody approved a Streamlit strategy. Analysts shipped apps because shipping one took an afternoon. Expect the same pattern in a job, in roughly this order of frequency:

The internal tool that replaced a spreadsheet. Our Pune team's Monday ritual becomes a URL with a date picker, and finance stops asking for the file. Least glamorous, highest value, fastest way for an analyst to get noticed.

The demo that sells the model. An AI engineer with a working retrieval pipeline needs a chat box in front of it for the stakeholder review, and st.chat_message plus st.chat_input gets there in thirty lines. Building that retrieval layer properly is what the AI Engineer course practises live on the Claude and Microsoft stacks. For the retrieval side first, read how to build production RAG.

The labelling and review harness. Someone has to read 400 model outputs and mark each good or bad. A session-state pointer, two buttons and a CSV write is a two-hour build, and it is standard MLOps plumbing that teams reinvent constantly.

Live course

A Streamlit app is the front door. Learn to build what sits behind it.

Live online·Sat–Sun, 8–11 PM IST·100+ hrs·Rs 24,999

The AI Engineer course teaches you to build agents that plan, use tools and act, certified on both Microsoft Copilot Studio and Claude Code, the two stacks real job postings are naming. Retrieval, tool calling and agent design are built live across 16 weeks.

Explore the course
AI Engineer Course: Generative AI, RAG & AI Agents (Microsoft + Claude Certified)

Four Things That Go Wrong in Every First Streamlit App

Here is the one that will actually bite you, warned the way a colleague would rather than the way docs do. You will put an API key in secrets.toml, add the file to .gitignore, feel responsible, and then two weeks later commit a notebook whose output cell contains the key. The leak almost never comes from the file you remembered to ignore. Rotate the key once you deploy, and never hand a Streamlit app a write-capable database credential. Read-only user, always.

Four failures and what to do instead

Each one has the same root cause: forgetting that the script reruns.

1

Reruns on every keystroke

A st.text_input next to an expensive query means a query per character typed. Wrap the inputs in st.form so nothing fires until submit.

Use st.form
2

Cache leaking between users

cache_data is shared across everyone using the app. Cache a per-user query without the user in the key and person A sees person B's rows.

Security
3

Unpinned Streamlit version

The docs warn an unpinned app can be upgraded without your knowledge. One morning it is broken and your repo has not changed.

Pin it
4

Loading the whole table

SELECT * FROM events is the fastest route to the memory ceiling. Aggregate in the database, render the summary, keep the detail one click away.

Push it down

Compiled from Streamlit's caching, session state and deployment docs, checked 28 October 2026.

Symptom What is actually happening Fix
"Over its resource limits", app goes blank Memory crossed the ceiling, usually from cached copies rather than one big frame Add ttl and max_entries, aggregate in SQL, cast float64 to float32 where precision allows
Button needs two clicks to work You read session state before the rerun that writes it Initialise the key at the top of the script, or use the widget's on_change callback
Chart redraws, numbers are stale Cache hit on arguments that did not change, even though the table did Set a ttl, or expose an admin button calling st.cache_data.clear()
Works locally, ModuleNotFoundError on deploy The dependency was in your virtualenv but not in requirements.txt Regenerate from a clean environment, and leave standard library modules out
KeyError on st.secrets in production only Secrets were never pasted into Advanced settings at deploy time Add them in the app's settings, then reboot the app

When Not to Use Streamlit

Every tool deep dive owes you this section, so here is the honest version. Streamlit is a poor fit the moment any of these is true, and no amount of clever engineering changes that cheaply.

Do not reach for Streamlit when
  • Different users must see different data. There is no built-in authorisation model. Streamlit documents tutorials for Google and Microsoft Entra authentication, but data isolation stays your problem and the shared cache works against you.
  • The interaction must feel instant. A full script rerun per click has a floor. Fragments help, but a drag-and-drop canvas or a smooth animated map wants a real front end.
  • It is a product, not a tool. Custom routing, SEO, mobile layouts and design systems all fight the framework. A competitor benchmark circulating in 2026 claims 15.6 seconds to first data for Streamlit on simulated slow 4G against 2.1 seconds for their own framework; it is vendor marketing measuring first paint rather than interactivity, so distrust the figures, but not the direction.
  • Many concurrent users on small hardware. Each session holds its own state in the same process. Fifty analysts at 9 am on one small container is a bad morning.

There is a quieter trap too. Streamlit is pleasant enough that teams build the app instead of fixing the pipeline, and a prettier interface onto a wrong number makes things worse. Fix the model layer first: a governed Microsoft Fabric lakehouse is the right home for that logic, and the DP-700 syllabus in that programme is largely about this discipline.

What to Build Next, in Order

With an hour a day, this beats working through the API reference. Build the twenty-line app above with your own CSV tonight. Add session state and a form tomorrow. Add cache_data with a ttl on day three, deploy on day four so the thing has a URL you can send someone. Only in week two go near fragments, custom components or multi-page apps.

So, what would I do in your position? Build it tonight with a messy CSV you already own, deploy it tomorrow, and send the link to one person who will actually use it. Streamlit's value is not sophistication, because it has none; it is that the gap between a notebook and a URL someone else can open shrinks to an evening, and little else in a data career compounds faster than being the person who closes that gap. If what you want behind that URL is a retrieval or agent system, the AI Engineer course is where to build one properly, a free webinar is the cheapest way to see the syllabus first, and the full certifications overview maps which exams sit on which route.

Frequently asked questions

Is this Streamlit tutorial enough to build a real app, or do I need web development?

No HTML, CSS or JavaScript is required. The twenty-line example above is a complete app with upload, filtering and a chart. Web skills only matter once you want custom layouts or components, which is also the point to ask whether Streamlit is still the right tool.

Is Streamlit free, and what are the Streamlit Community Cloud limits?

The library is open source and free, and Community Cloud hosting is free too. Streamlit's docs list memory per app as 690 MB minimum to 2.7 GB maximum, with apps put to sleep after 12 hours without traffic, and state that these limits can change without notice.

What is the difference between st.session_state and st.cache_data?

Session state is per browser session and remembers values such as a chat history or the selected row. Cache data is shared across all users and stores results you do not want to recompute, keyed on the arguments. Caching per-user data is a security bug, not a style choice.

Why does my Streamlit app reset the value every time I click a button?

Because the whole script reruns from line 1 on every interaction, so count = 0 executes again and the increment is lost. Move the value into st.session_state, guard the initialisation with an if "count" not in st.session_state check, and it survives.

How do I deploy a Streamlit app for free?

Push the app to a GitHub repo with a requirements.txt, sign in to Community Cloud, pick the repo, branch and entrypoint file, then paste your local .streamlit/secrets.toml contents into Advanced settings. Pin the Streamlit version in requirements, as the docs recommend.

Can Streamlit handle large datasets?

The constraint is your host's memory, not the library. At 8 bytes per float64 cell, ten numeric columns means roughly 34 million rows fills the documented 2.7 GB ceiling before cached and filtered copies. Aggregate in SQL or DuckDB and render only the summary.

Is Streamlit good enough for production, or only for prototypes?

It runs in production in plenty of places. Snowflake's engineering blog describes more than 500 internal Streamlit apps covering financial reporting, security monitoring and product analytics. It is production-grade for internal tools and weak for customer-facing products needing per-user authorisation and instant interaction.

About this guide. 360 Digital Transformation is an Anthropic Partner and a Microsoft Authorized Training Partner. Other certification bodies, vendors and employers named here are not affiliated with us. Tools and versions change quickly; commands and figures cited were checked on 28 October 2026.

Learn it live with 360 Digital Transformation

Turn this guide into a skill employers can see

Live weekend cohortEMI available

AI Engineer Course: Generative AI, RAG & AI Agents (Microsoft + Claude Certified)

Rs. 27,999Rs. 37,239 Save 24%

Tools and platforms you work with

  • Python
  • Claude API
  • FAISS
  • ChromaDB
  • LangChain
  • LangGraph
  • CrewAI
  • AutoGen (AG2)
Add bonus modules
See the syllabus and batch dates

Other live courses on this career path