What is a backend, actually?
Every blog post, event, and form submission has to live somewhere. Here's what actually goes into storing it properly, and the fast way to skip all of it.
What a backend actually does
The part of a website nobody sees, and the part that actually remembers things.
The frontend is the part you can point at: the homepage, the colors, the layout. A backend is everything behind it that a page can't do on its own — a place to durably store information, and the logic that reads and writes it safely. Two pieces, always: a data store and the code that talks to it.
Anything on a site that has to be remembered needs both. A blog post has to still be there tomorrow. An event needs a real, growing list of who registered. A contact form has to land somewhere a human will actually see it. None of that happens by accident — something has to store it, and something has to fetch it back out correctly, every time.
What Gravity gives you today: JSON files
Real storage, not a demo — and exactly the right amount of it to start.
Out of the box, Gravity stores everything — blog posts, events, form submissions, portal
accounts — as plain JSON files under data/content/. One file per record. No
database to install, nothing running in the cloud, nothing to configure. This genuinely
works. Plenty of small sites never need anything else.
It also has real limits, and they show up in a predictable order as a site grows:
So you add a database. Now what?
This is where “just use a real database” turns into its own project.
SQL isn't a database — it's the language you use to talk to one. A SQL database (Postgres, MySQL, SQLite) is software that stores rows in tables and enforces rules about them: a registrant has to reference a real event, two writes to the same row can't corrupt each other, a query across ten thousand rows comes back in milliseconds instead of a Python loop. That layer — SQL, sitting between your application and the actual stored bytes — is what JSON files don't have.
The default choice for most new projects. Powerful, free, and the deepest ecosystem — also the most to learn.
Older, still everywhere, slightly different tradeoffs. A safe, well-documented alternative to Postgres.
One file, zero setup — great for a prototype. Risky once real concurrent traffic starts writing to it.
Whichever one you pick, it has to run somewhere: a managed service you now pay for and depend on, or a server you patch, back up, and keep awake yourself. Either way, that's infrastructure you own now, not a file that just sits in your repo.
Migrations: the part nobody warns you about
Your schema will change. Every environment has to change with it, in the same order, without losing data.
Your schema changes constantly
You'll add a status column to events, a phone field to
contacts, a whole new table for something you didn't plan for on day one. In production,
you can't just hand-edit the database — your laptop, staging, and production all
need the exact same schema, applied in the exact same order.
A migration is a versioned, revertible script
A migration tool tracks every schema change as its own small script — add this column, backfill this default, drop that old table — that can be applied or rolled back on demand, and run in the same order everywhere.
In Flask, that's SQLAlchemy + Alembic
The standard pairing in the Python world: SQLAlchemy defines your tables as Python classes, and Alembic generates and runs the migration scripts that keep the real database's columns in sync with them — on your machine, in CI, and in production, every single time.
Everything you'd now own
None of this is impossible. It's just real, ongoing engineering work — not a weekend project.
Or connect Adhara, and skip all of it.
Adhara is EIM's managed backend: the database, the schema, the migrations, and the API layer for blog, events, forms, CRM, and commerce — already built, already hosted, already maintained. Gravity already knows how to talk to it.
No schema to design, no Alembic to learn, no server to patch. Set three environment variables and Gravity switches from local JSON to a real backend — the same way it already works today.
Parameterized queries, access control, backups, and uptime are Adhara's job, not yours. The engineering work in the section above is exactly what you're paying to not do.