
Choosing a database too early can become expensive for a solo builder. You start fast on a popular service, ship your first version, then watch your bills climb or your queries strain as the app grows. By the time the pain shows up, migrating off the platform can take time you do not have.
Match a database to your product by modeling reads, writes, sync needs, hosting costs, and security before you choose a vendor.
The mobile market makes these decisions matter: mobile internet made up 73.5% of regional web traffic in Africa and 69.4% in Asia by 2024. Offline behavior and sync deserve attention from the start. The right database choice depends on your data access patterns.
The database choice starts with your data model
Choose the data model before you choose the vendor. That keeps you focused on how your app reads, writes, and relates data.
Think in dimensions. First choose the data model: relational or NoSQL. Then decide where the data lives, how sync works, and how much managed infrastructure you want.
The categories often overlap. A cloud document store can be NoSQL, and a realtime database can also use JSON-like structures. Treat each choice as a trade-off.
Relational databases store data in tables with rows and columns and enforce a strict schema. They handle transactional, strongly consistent applications well. Many solo products can start with PostgreSQL when they need accounts, orders, profiles, posts, or other related records.
Relational databases fit apps with user accounts, orders, profiles, posts, and any need for joins. If your app needs to answer flexible questions across related data, SQL usually keeps you from fighting your database later.
NoSQL databases use flexible models, including document and key-value stores. They are optimized for large volume, low latency, and flexible data models. The catch is that you must know your read and write patterns early.
DynamoDB does not support JOIN operations, and you should not start designing your schema until you know the questions it needs to answer.
An indie hacker put the trade-off plainly after choosing Firestore for a project: "I initially thought there would not be any querying," but as the project grew, "I was screwed left and right for choosing Firestore." NoSQL fits simple, hierarchical, or rapidly evolving data where your access patterns are clear from day one.
How hosting and sync change the model choice
Once you know the model, identify where the data should live. Hosting changes the user experience during outages, cross-device use, and shared collaboration.
Local databases live on the device, so reads and writes need no network. SQLite is the workhorse here. It works well in devices that must operate without expert human support and runs on cellphones, watches, and game consoles.
On iOS, Core Data is the native framework for managing app data across Apple platforms.
Cloud realtime databases sync data to connected clients in milliseconds. Firebase Realtime Database stores everything as a large JSON tree. Data persisted locally keeps realtime events firing even while offline.
It scales to roughly 200,000 concurrent connections in a single database before you need sharding. These fit chat apps, collaborative tools, and dashboards with simple structures.
Cloud document stores like Cloud Firestore hold collections of documents. Firestore is positioned as the recommended enterprise-grade document database for more complex data models. It supports complex queries, scales automatically, and includes offline access.
Free tiers shape your architecture
Free tiers tell you how long you can validate before paying, but hidden limits matter more than storage alone. Compare shutdown rules, request ceilings, and project pauses before you commit. That discipline gives you a clearer cost ceiling while you test demand.
Firebase Firestore on the Spark plan gives you 1 GiB stored data, 50,000 reads per day, 20,000 writes per day, and 10 GiB monthly egress. Your app shuts off for the rest of the month if you exceed limits. Cloud Functions and Google Cloud features require the paid Blaze plan.
Supabase takes a different approach. The free plan includes a 500 MB database, 5 GB egress, 50,000 monthly active users, and unlimited API requests. The catch that surprises people: free projects pause after one week of inactivity, with a limit of two active projects.
The Pro plan at $25 per month removes pausing and bumps the database to an 8 GB database.
The permanent free tiers stack up like this:
- Firebase Firestore (Spark): 1 GiB storage, 50K reads per day, and the app shuts off if you exceed limits.
- Supabase Free: 500 MB storage, with projects paused after one week of inactivity and a cap of two active projects.
- MongoDB Atlas M0: 512 MB storage, roughly 100 operations per second, and no uptime SLA.
- AWS DynamoDB: 25 GB storage with ~200M requests per month included.
DynamoDB stands out on raw storage and included request volume. On-demand is the default and recommended mode for most workloads, including startups.
If you self-host, PocketBase costs nothing indefinitely. PocketBase supports collections and records, realtime subscriptions, auth, and an admin dashboard for self-hosted apps. A solo builder can ship auth and admin workflows without assembling a separate backend stack.
PocketBase is a personal open source project with intentionally limited scope and no promises for maintenance or support. That trade-off works for small projects, but it can become a support risk if customers depend on the app every day.
Choose local or cloud based on failure mode
Local storage protects the experience when connectivity fails. Cloud storage protects shared state when multiple people or devices need the same data.
After you compare cost ceilings, decide which failure mode would hurt users most. An offline app fails when data cannot save locally. A collaborative app fails when users cannot see the same shared state.
Use this decision split:
- Choose local storage when the app must keep working during outages or when privacy requirements make device storage attractive.
- Choose cloud storage when collaboration, multi-device state, or shared data matters more than offline writes.
- Choose an offline-first pattern when users need both local writes and later cloud sync.
Offline-first guidance starts by writing to the local data source, so local-first apps can support writes offline by default. If writes must reach shared cloud state before the app confirms them, spotty connectivity becomes a product risk.
Local storage on SQLite, Core Data, or CloudKit fits apps that need to keep working through outages or keep sensitive data on the device. SQLite has no built-in sync, so multi-device or multi-user apps require additional tooling.
Choose cloud when your app is multi-user, when real-time collaboration is core, or when you do not want to manage sync logic yourself. Firebase Firestore handles offline sync automatically: when the device comes back online, it synchronizes any local changes. Conflicts use last-write-wins. Bundled backend sync creates lock-in because the sync protocol is proprietary and tailored to that vendor.
A practical offline-first pattern
For critical data, official guidance says to write locally first, then queue the write to notify the network at the earliest opportunity. The user gets a fast local save, and the app can retry the network later.
A common SQLite schema for this uses a synced boolean flag and an updated_at timestamp:
CREATE TABLE notes (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
synced BOOLEAN DEFAULT 0
);Expose sync status and offer a manual sync action so users know when their data is safe and can recover from bad connectivity.
AI app builders still need a database strategy
AI app builders hide setup work while leaving database trade-offs in place. You still need to know who controls the data, how export works, and what happens when the app grows.
The platform you choose decides much of your database story. AI app builders and visual platforms often let you define fields and run reads and writes through guided interfaces. Some platforms run standard SQL underneath, which gives you more portability when you need to move.
With us, the database benefit is control without setup work. We use PostgreSQL via Neon with automatic database management, so you can build on a familiar relational model without wiring infrastructure by hand.
The surrounding infrastructure matters too. Built-in authentication and social login reduce login setup work. Stripe lets you collect money immediately, publishing removes hosting setup, and Full GitHub Sync gives you code ownership when you need to inspect or move the app.
A useful split shapes your future freedom. Some platforms keep your data inside a proprietary system. Others connect to a database you control.
Lock-in becomes real when you cannot export data, depend on software development kits you do not control, or generate an app with inaccessible code.
You can reduce that risk with a few choices:
- Pick platforms that offer code export or connect to a database you control, so migration stays possible.
- Favor open-source options like Supabase or PocketBase when portability matters more than bundled convenience.
- Run a proof-of-concept and confirm standard data export before you commit, so you avoid rebuilding under pressure.
Supabase can lower lock-in when portability matters because it is open-source, built on standard Postgres, and can be self-hosted. That portability is why it keeps showing up as the migration target when builders outgrow proprietary services.
Security mistakes can erase the value of a good database
A good database choice does not help if the app exposes private data. Lock down access before launch to reduce incident risk, support burden, and cleanup work.
Security misconfiguration creates practical risk for solo and AI-assisted builders. The errors are predictable, which means you can prevent them before launch.
Treat elevated database keys as server-only secrets. Keep public read and write rules out of production, turn on row-level controls where your database supports them, and require authentication before private data loads.
Mobile security guidance recommends you authenticate server-side and only load data on the device after successful authentication. It also says not to store user passwords on the device; use device-specific tokens that can be revoked.
Recent security rankings place cryptographic and authentication failures among the top risks.
Encryption is non-negotiable for sensitive data. For data in transit, TLS and IPsec protect confidentiality during transmission. For data at rest on iOS, sensitive files can be secured via hardware-backed 256-bit AES encryption when the APIs are used correctly.
If you serve users in regulated regions, the obligations apply to you too. European privacy rules treat personal data as including online identifiers, and privacy requirements apply when your app processes personal data. Supabase secures data with Row Level Security and is self-hostable for data residency needs.
Make the call by modeling your next queries
Your next queries usually point to the safest choice. Model reads, writes, offline behavior, and export needs before you commit.
Match the database to your data and your skills. Start relational when your data has clear relationships, and add NoSQL only when specific access patterns require it.
A few rules of thumb keep you on track:
- Need SQL, joins, and open-source portability? Start with a PostgreSQL database, so your data model stays easier to inspect and move.
- Need real-time sync with minimal backend work and simple data? Firebase fits, but you accept the vendor's sync model.
- If your app must work offline for a single user, use SQLite or Core Data locally. That keeps saves fast even when the network fails.
- Self-hosting on a tight budget points to PocketBase, which runs as an executable. That can cut hosting spend, but uptime and maintenance stay with you.
- Already living in AWS? Amplify with DynamoDB makes sense despite a steeper learning curve. This keeps your backend inside the same cloud stack.
Choosing without modeling your future query patterns creates risk. Picking Firestore because it is popular, then hitting its querying limits at scale, is the canonical example.
Start with a database that fits your current access patterns. Lock down your security rules before you ship. Confirm you can export your data if you ever need to leave.
If you want to build on managed PostgreSQL instead of wiring infrastructure by hand, describe the idea, refine it through prompts, and try us free.


