The first real argument on any web app build is about the database. Not the framework. Not the hosting. The data model.
That order surprises people. Founders expect us to open with screens or auth or which cloud. We start one layer below that. We start with what the app is actually storing and how those things relate.
Here is the reason. Almost every other decision is cheap to reverse. The data model is not.
You can swap a frontend. You can't swap a schema on Tuesday.
A React component is throwaway. Rewrite it in an afternoon and nobody notices. A button moves, a color changes, a whole page gets redrawn. None of that touches the thing your business runs on.
A schema is different. Once you have real rows in a table, every change is a migration. Every migration is a risk against live data. The longer you wait, the more code depends on the shape you picked early. That dependency compounds quietly until it does not.
So we resolve the part that is hard to undo first. Then the easy parts stay easy.
The questions we ask before any code
The interview is short and boring on purpose. Boring questions surface the expensive answers.
What are the core entities. Who reads them, who writes them, how often. What has to be consistent the instant it changes. What can lag a few seconds. How big does the largest table get in two years, not two months. What query has to stay fast when everything else is slow.
The answers decide more than the database brand. They decide whether you need relational at all. They decide your access patterns, which on AWS decide your cost. Pick the wrong access pattern on a managed table and the bill arrives later. Most AWS bills hide savings nobody is tracking, and a chunk of that traces straight back to a data model that fought the platform instead of fitting it.
Where the failure mode lives
The classic mistake is modeling the screens instead of the domain. You build tables that mirror the first three pages of the UI. It ships. It demos well. Then the second feature needs the same data sliced a different way, and the schema has no answer.
Now you are denormalizing under pressure. You are bolting a cache onto a query that should have been a table. You are writing application code to enforce a rule the database should have owned. Each patch is reasonable alone. Together they become the thing nobody wants to touch.
We have shipped 17 production products, 10 of them in our first 7 months as a 2-person team. The builds that stayed fast did one thing the slow ones skipped. They got the data model right before the features piled on top of it.
What this looks like on a Web App engagement
Our Web App work is fixed price, $6K to $25K, delivered in 3 to 5+ months. See pricing for the bands. The number does not move after we agree on scope, which means we have a direct stake in getting the foundation right. A schema rewrite in week six is our problem to absorb, not yours to fund.
So the database conversation is not a formality. It is where we spend our own risk budget. We would rather argue about entities for two hours in week one than rebuild a table in week six.
The same discipline carries past the build. An ex-AWS Federal SA on a 2-person team means the person modeling your data has seen what bad schemas cost at scale. The same thinking shows up when we wire a RAG chatbot to your content, or when a support agent we built and run goes into production. None of that works if the data underneath is shaped wrong.
When the engagement ends, you own the code. Schema, migrations, the reasoning behind both. We exit clean. Fixed price every time, and the foundation is yours to build on without us.
The short version
Start where reversal is hardest. That is the database, almost always.
If you are scoping a web app and the data model has not been settled, that is the conversation to have first. We will have it for free. Book a 30-minute call and bring your entities, not your screens.