Firebase Realtime Database vs Firestore (and the third option nobody mentions)
Last updated: November 2026
Cloud Firestore is a document database with compound indexed queries and per-operation billing. The Firebase Realtime Database (RTDB) is a single JSON tree billed by bandwidth and storage. Moving from RTDB to Firestore means redesigning your data into collections and rewriting your data layer, with no automated migration tool from Google. If you'd rather keep your RTDB code and data model, a wire-compatible alternative like Lark is a third option.
Almost every team running a production app on the Firebase Realtime Database eventually has the same meeting: Should we be on Firestore instead?
It's a natural question to ask. Google's documentation and console nudge new projects toward Cloud Firestore, and if you're hitting RTDB's query limitations or watching your bandwidth bill climb, moving to Google's newer database sounds like the obvious next step.
Then someone sits down to scope the migration and discovers that despite sharing the "Firebase" brand name, the Realtime Database and Cloud Firestore are two completely different databases with different data models, different SDKs, different security rules languages, and opposite pricing models.
Here's an honest look at how the Realtime Database and Firestore compare, what a migration between them actually looks like, and when it makes more sense to keep the RTDB model and swap the server underneath instead.
What's the difference between Realtime Database and Firestore?
The Firebase Realtime Database stores your entire database as one big JSON tree. You read, write, and subscribe to any path inside that tree (/rooms/42/players/alice/x). There are no collections or tables, and a write can touch a single number deep inside the tree or update multiple paths at once.
Cloud Firestore stores data as collections of documents. Documents look like flat JSON objects (up to 1 MiB each), documents live inside collections, and a document can point to subcollections below it. You can't subscribe to an arbitrary slice of a nested tree across documents; a query always returns whole documents from a collection or collection group.
That structural split drives three major technical differences:
First, queries. In RTDB, a query can only sort or filter on a single property at a time (orderByChild, orderByKey, orderByValue, or orderByPriority) combined with a range (startAt, endAt, equalTo, limitToFirst, limitToLast). If you want to filter by both status == "open" and region == "us-east", you have to denormalize those fields into a combined key like "open_us-east". Firestore indexes every field automatically and supports compound queries with multiple where() clauses and orderBy() sorts out of the box.
Second, latency and connection overhead. RTDB maintains a lightweight persistent WebSocket connection straight to an in-memory tree, which is why Google's own database comparison guide still recommends RTDB when low-latency state syncing is the priority. Firestore is backed by Google's distributed Spanner-based storage layer, which gives it strong multi-region horizontal scalability at the cost of higher per-write overhead.
Third, sustained write rates to the same data. Because Firestore maintains indexes across distributed storage tablets, rapidly updating the same document (or sequentially keyed documents) creates write contention. In RTDB, updating a small value at the same path twenty times a second is normal.
Is Firebase Realtime Database deprecated?
No. The Firebase Realtime Database is not deprecated, and Google continues to run and support it for production workloads.
At the same time, Google positions Cloud Firestore as its default recommendation for new projects, and most new Firebase console features, extensions, and AI integrations are built for Firestore first. For teams with long-lived RTDB applications, that leaves an awkward middle ground: the product isn't going away tomorrow, but it also isn't where Google is investing in new capabilities like better high-frequency transports or lower bandwidth pricing.
How does pricing compare?
This is where the two databases diverge the most, and where teams migrating from RTDB to Firestore sometimes get a nasty surprise on their first bill.
Firebase Realtime Database bills on two meters: how much data you store ($5.00/GB-month) and how many bytes your clients download ($1.00/GB). Reads, writes, and deletes are not billed per operation.
Cloud Firestore bills primarily per document operation (roughly $0.03 to $0.06 per 100,000 document reads and $0.09 to $0.18 per 100,000 document writes depending on region, plus per-delete fees), alongside much cheaper per-GB storage ($0.18/GB-month) and standard Google Cloud network egress.
The catch with per-operation billing in a realtime application is how listeners work. In Firestore, whenever a document changes, every connected client listening to a query that includes that document is billed for one document read, and they receive the entire document again.
Imagine a collaborative app or multiplayer game room with 25 people connected, where each person updates their state once per second:
- That's 25 writes per second, or 90,000 writes per hour.
- Each write fans out to the 25 listeners in the room: 625 document reads per second, or 2.25 million billed reads per hour -- from a single room of 25 users.
- Because each read sends the whole document, a 20-byte coordinate change inside a 4 KB document also multiplies your network egress.
Google's own documentation explicitly warns about this, noting that if your app relies on many small reads and writes, Firestore can cost significantly more than the Realtime Database, and that presence systems should still be built on RTDB rather than Firestore.
Lark Cloud keeps RTDB's byte-based billing model (no per-operation fees), cuts the storage and bandwidth rates in half ($2.50/GB-month storage and $0.50/GB outbound bandwidth), and adds volatile paths billed at $0.10/GB for high-frequency state like cursors and movement. Or, because Lark is open source, you can self-host it on your own servers and pay nothing per GB or per operation.
What does migrating from Realtime Database to Firestore involve?
Because both products live in the same Firebase console, it's easy to assume there's an automated upgrade path from RTDB to Firestore. There isn't. Google's official migration guide lays out a manual multi-stage process:
- First, you have to redesign your schema. Deeply nested RTDB trees have to be broken apart into flat documents, collections, and subcollections so you don't hit Firestore's 1 MiB document size ceiling or pay to re-download a giant document every time a nested field changes.
- Second, you have to rewrite your client and server SDK code. The
firebase/databaseAPI (ref,onValue,onChildAdded,set,update,onDisconnect) does not work with Firestore. Every read, write, listener, and transaction has to be rewritten againstfirebase/firestore(collection,doc,onSnapshot,setDoc,updateDoc). And because Firestore has no equivalent to RTDB's server-sideonDisconnect()hook, any presence or cleanup logic has to be re-architected (often by keeping a separate RTDB instance running just for presence!). - Third, you have to rewrite your security rules. Firestore Security Rules use a completely different language (
service cloud.firestore { match /databases/{database}/documents { ... } }) with different semantics from RTDB'srules.json. Your existing rules cannot be copied over. - Finally, you have to dual-write and backfill your data. For a live production app, Google recommends updating your clients to write to both databases simultaneously, running a custom script to transform and copy historical JSON into Firestore documents, switching reads over, and then removing the old RTDB code.
The one piece of your stack that doesn't have to change is Firebase Auth, since both databases share the same user authentication tokens.
When should you move to Firestore?
Even with the rewrite effort, Cloud Firestore is the right move in several common situations:
- Your application's biggest pain point in RTDB is querying. If you're constantly fighting
orderByChildlimitations and building awkward composite keys just to filter a list of records by two fields, Firestore's compound queries and automatic indexing will simplify your code immediately. - Your data is naturally document-shaped -- user profiles, e-commerce catalogs, project tickets, or blog posts -- where records are read and updated at human speed rather than ticked ten times a second.
- Your operation count is low relative to your total stored data size. Storing 100 GB of cold documents is much cheaper in Firestore ($0.18/GB-month) than in RTDB ($5.00/GB-month).
- You want to stay completely inside Google Cloud's managed ecosystem with turnkey multi-region replication.
When should you stay on the Realtime Database model?
You're better off keeping the JSON tree model when:
- Your app is genuinely realtime: multiplayer games, collaborative canvases, live whiteboards, cursor presence, live sports or auction tickers, or chatty IoT/telemetry streams.
- You rely on
onDisconnect()to clean up user state, locks, or presence the moment a connection drops. - Your data is a hierarchy where clients subscribe to a path and receive tiny delta patches as deeply nested keys change.
- Your workload generates millions of small updates that would make per-operation billing in Firestore prohibitively expensive.
The third option: keep the RTDB model, change the server
If your application fits the Realtime Database model well, and the reason you're looking around is cost, latency, high-frequency update limits, or vendor lock-in, you don't have to rewrite your app for Firestore.
We built Lark to be an open-source (AGPL v3), wire-compatible replacement for the Firebase Realtime Database:
- Your existing
firebase/databaseSDK calls (Javascript, Android, iOS, Flutter, C++, Unity) and REST API calls keep working without code changes. - Your existing
rules.jsonsecurity rules copy straight over and evaluate with the same semantics. - Your users stay on Firebase Auth, and Lark validates the same Google-signed ID tokens.
- Your migration is exporting your JSON from Firebase, importing it into Lark, and changing
databaseURLin your Firebase config.
Under the hood, Lark is a Rust engine running on a thread-per-core io_uring architecture with a custom on-disk binary JSON format (lark-blob) designed to patch small changes deep inside large trees without rewriting the whole document. And for high-frequency data like cursors or player positions, you can mark paths as .volatile in your security rules to batch updates in memory with no writes-per-second cap and 80% lower bandwidth cost on Lark Cloud.
Can you run Firestore and Lark side by side?
Yes -- and in fact, Google's own documentation already suggests running Firestore and the Realtime Database side by side in the same app so you can use Firestore for document queries and RTDB for presence and low-latency state.
You can do the exact same thing with Firestore and Lark. Because Lark validates Firebase Auth tokens directly using your Firebase Project ID, a user who signs in once with Firebase Auth is authenticated with both databases at the same time. You can keep your structured document collections and compound queries in Firestore, and point your realtime rooms, onDisconnect presence, and high-frequency volatile state at Lark.
Side-by-side comparison
| Feature | Firebase Realtime Database | Cloud Firestore | Lark |
|---|---|---|---|
| Data model | Single JSON tree | Collections of documents | Single JSON tree (with auto-routing across DBs) |
| Billing model | GB stored + GB downloaded | Per read/write/delete op + storage + egress | $10/mo base + GB stored + GB egress (or free self-hosted) |
| Storage rate | $5.00 / GB-month | $0.18 / GB-month | $2.50 / GB-month (Cloud) |
| Bandwidth (egress) rate | $1.00 / GB | ~$0.12 / GB + per-read op fee | $0.50 / GB ($0.10 / GB for volatile) |
| Queries | Single orderBy + range |
Compound multi-field indexed queries | Single orderBy + range (same as RTDB) |
Server-side onDisconnect |
Yes | No | Yes |
| High-frequency updates | 1,000 writes/sec per DB | Per-op cost & doc contention limits | Unlimited rate on .volatile paths |
| Migration from RTDB | N/A | Full schema redesign + SDK & rules rewrite | Change databaseURL + import JSON |
| Works with Firebase Auth | Yes | Yes | Yes |
| Open source / self-hostable | No | No | Yes (AGPL v3) |
Frequently asked questions
Is Cloud Firestore faster than the Firebase Realtime Database?
For simple realtime state syncing, no. Google's own documentation notes that the Realtime Database has lower latency than Firestore for frequent state-syncing workloads because connections talk directly to an in-memory tree. Firestore's strength is query scalability across large collections rather than raw per-message latency.
Can I use my Firebase Realtime Database security rules in Firestore?
No. Despite similar names, RTDB security rules (JSON with Javascript-like expressions) and Firestore Security Rules (a custom match / allow DSL) are two completely different languages. If you move to Lark instead, your existing RTDB rules.json works without changes.
Does Lark replace Cloud Firestore?
No. Lark implements the Firebase Realtime Database wire protocol and JSON tree model, not the Firestore document/collection protocol. If you're already happily running on Firestore, Lark isn't a drop-in replacement for it (though you can add Lark alongside Firestore if you need cheap, low-latency presence or volatile multiplayer state).
How long does it take to test an existing RTDB app on Lark?
Usually about fifteen minutes. Export your JSON data and rules.json from the Firebase console, import both into a Lark Cloud project (or a local make up-release Docker container), set your Firebase Auth Project ID, and swap the databaseURL string in your development config.
Firebase, Firebase Realtime Database, and Cloud Firestore are trademarks of Google LLC. Lark is an independent project and is not affiliated with, endorsed by, or sponsored by Google.