Choosing the Right GCP Storage Service: Cloud Storage, Cloud SQL, Firestore, Bigtable, BigQuery, and More
GCP offers seven major storage services. The right one depends entirely on what your data looks like and how your application accesses it, not which service sounds the most powerful. This page gives you a plain-English explanation of each option, a decision flow, a comparison table, and honest guidance on when each service fits and when it does not.
Simple explanation: what each service is for
Here is a one-line summary for each service. These are deliberately simplified. The rest of the page covers the nuance.
- Cloud Storage: stores files and objects (images, videos, PDFs, backups, any blob)
- Cloud SQL: relational database (MySQL, PostgreSQL, SQL Server) for app data that needs SQL
- Firestore: flexible document database with real-time sync, serverless, no capacity planning
- Bigtable: wide-column NoSQL for very large datasets (>1 TB) with very high write throughput
- Spanner: globally distributed relational SQL, consistent across regions, significantly more expensive
- BigQuery: data warehouse for analytics and reporting, not for day-to-day app reads and writes
- Memorystore: managed Redis or Memcached for caching; not a primary durable database
Think of GCP storage services like a well-equipped workshop. Cloud Storage is the shelving unit: stack anything on it and retrieve it by location. Cloud SQL is the filing cabinet: organised, indexed, and good for finding specific records quickly. Firestore is the noticeboard that updates itself the moment something changes. Bigtable is the industrial conveyor belt, built for enormous throughput but overkill for smaller workloads. BigQuery is the analysis desk at the back, where you study and report on everything that came through, not where you do live work. A real workshop uses all of these in combination.
If one of the services above immediately matches your use case, you likely have your answer. If you are still unsure, work through the decision flow below.
How to choose a GCP storage service
Work through these questions in order. Most workloads reach a clear answer by question three.
Step 1: Are you storing files, or data your app needs to query?
If you are storing files (images, PDFs, videos, audio, database dumps, log archives, compiled binaries, ML training data, Terraform state), use Cloud Storage. There is no schema, no querying inside file contents, and no practical size limit per bucket. It is cheap, durable, and integrates with every other GCP service.
See Cloud Storage Overview for storage class selection and lifecycle configuration, and Storage Buckets Explained for how bucket organisation works.
If your data needs to be queried, filtered, or joined by your application, continue to Step 2.
Step 2: Does your application need SQL?
If you need JOINs across tables, multi-row transactions, foreign key constraints, complex WHERE clauses, or you are migrating an existing relational application, you need a relational database.
Use Cloud SQL for standard relational workloads within a single region. It runs MySQL, PostgreSQL, or SQL Server on a managed instance. It is cost-effective, familiar, and handles the vast majority of application use cases. See Cloud SQL Overview.
Use Spanner only if you need globally distributed writes with strong consistency across multiple regions, or your write throughput exceeds what a single Cloud SQL instance can handle and horizontal scale is a hard requirement. Spanner is substantially more expensive. Do not default to it. Start with Cloud SQL.
If you do not need SQL, continue to Step 3.
Step 3: Is your dataset very large with very high write throughput?
If you are ingesting millions of events per second (IoT sensor readings, clickstream data, time-series metrics) and your dataset is at or approaching 1 TB, use Bigtable. It handles key-based lookups and range scans at petabyte scale with sub-10ms latency.
A common mistake is choosing Bigtable because you expect your dataset to grow large someday. If your dataset is under 1 TB today, Bigtable will cost you hundreds of dollars per month for capacity you are not using. Choose based on what you have now, not what you hope to have in two years. Start with Firestore or Cloud SQL and migrate when the data genuinely justifies it.
See Bigtable Overview. If you do not have this kind of scale, continue to Step 4.
Step 4: Is your data document-shaped, or do you need real-time client updates?
If your data is naturally document-shaped (user profiles, settings objects, product catalogues, posts, game state, notifications), or you need to push updates to mobile or web clients without polling, use Firestore. Firestore is serverless, scales automatically, supports offline sync, and has client SDKs with real-time listeners. The trade-off: query patterns must be designed upfront, and complex multi-field queries require composite indexes.
See Firestore Overview and Firestore Data Model for how documents and collections work.
Step 5: Is this an analytical workload?
If you need to run aggregations, group-by queries, window functions, or joins across very large result sets for reporting or business intelligence, use BigQuery. BigQuery is a managed data warehouse. It is not an OLTP database. It is billed per query (bytes scanned) and optimised for scanning large volumes of data efficiently. Do not use it for row-by-row application reads and writes. See BigQuery Overview.
Do you just need a cache?
If you need sub-millisecond access to frequently-read values (session tokens, rate-limit counters, computed results, leaderboards), use Memorystore (managed Redis or Memcached). It is not a primary durable database. Data in Memorystore can be lost on restart unless persistence is configured. Use it to reduce load on a backend database, not to replace one.
Comparison table
| Service | Best for | Data model | Key strength | Main limitation | Typical beginner use case |
|---|---|---|---|---|---|
| Cloud Storage | Files and objects | Object (blob) | Cheap, durable, no size limit | No querying inside files | Store user-uploaded images |
| Cloud SQL | Relational app data | Relational (tables, rows) | Full SQL, ACID transactions | Vertical scale, single region | E-commerce app database |
| Firestore | Flexible app data, real-time | Document (JSON-like) | Serverless, real-time sync, offline SDKs | Query patterns designed upfront | User profiles, chat messages |
| Bigtable | High-throughput NoSQL at scale | Wide-column | Petabyte scale, sub-10ms latency | Very expensive below 1 TB | IoT sensor time-series |
| Spanner | Global relational SQL | Relational (distributed) | Globally consistent, horizontally scalable | High cost, complex to operate | Multi-region payments system |
| BigQuery | Analytics and reporting | Columnar (warehouse) | Huge dataset queries, low cost per scan | Not for OLTP, seconds of latency | Business dashboards, reporting |
| Memorystore | Caching | Key-value (in-memory) | Sub-millisecond access | Not durable primary storage | API response caching, sessions |
Service-by-service guidance
When to use Cloud Storage
Cloud Storage is the right choice whenever you are storing files that your application needs to serve, archive, or process rather than query internally. It works as a content delivery origin, a backup target, a data lake for raw files, a source for ML training jobs, and a staging area for data pipelines.
Use it when: storing images, videos, documents, backups, exports, or any binary object. Files are referenced by a URL or path stored in your database.
Do not use it when: you need to filter or query the contents of your data, for example “find all users who signed up this week.” Cloud Storage cannot look inside files.
See Storage Classes in GCP for cost-saving class selection, Object Lifecycle Management to automate transitions and deletions, and Signed URLs Explained for secure file access.
When to use Cloud SQL
Cloud SQL is managed relational database-as-a-service. It runs MySQL, PostgreSQL, or SQL Server and handles backups, patching, replication, and failover for you. For most applications that need a database, Cloud SQL is the right starting point.
Use it when: your app needs SQL queries, multi-table JOINs, transactions, foreign keys, or you are migrating from an existing relational database.
Do not use it when: you need to distribute writes across multiple regions with strong consistency (use Spanner), or your data is document-shaped and you want serverless scaling without managing instance size (consider Firestore).
Example: an e-commerce site uses Cloud SQL (PostgreSQL) for users, orders, products, and inventory. The schema is fixed, joins are common, and transactions are essential.
If you are not sure which database to start with for a new application, Cloud SQL is a safe default. It is familiar, well-documented, cost-effective at development scale, and easy to migrate away from later if your requirements change. Getting started is more important than choosing perfectly.
See PostgreSQL on Cloud SQL and Connecting to Cloud SQL Securely.
When to use Firestore
Firestore is a serverless NoSQL document database. Documents are JSON-like objects stored in collections. It scales automatically with no capacity provisioning, supports real-time listeners that push changes to connected clients, and has SDKs with offline sync built in.
Use it when: your data is naturally document-shaped and does not require complex JOINs; you want real-time updates pushed to mobile or web clients; you want a database that scales without managing instance size; or you are building a mobile app and want offline sync included.
Do not use it when: you need complex ad-hoc queries across many fields, or your data is fundamentally relational with many foreign-key relationships. Firestore requires query patterns and composite indexes to be planned upfront.
Example: a messaging app uses Firestore to store conversations and messages. Clients subscribe to real-time listeners so new messages appear instantly without polling.
See Firestore Data Model and Firestore Queries.
When to use Bigtable
Bigtable is a wide-column NoSQL database built for very large datasets and very high write throughput. It stores data in rows identified by a row key, with columns grouped into column families. Queries are key-based or range-scan-based. There is no SQL and no flexible ad-hoc querying.
Use it when: your dataset is at or beyond 1 TB, you are ingesting millions of writes per second (IoT, telemetry, clickstream), and your access patterns are key-based lookups or range scans.
Do not use it when: your dataset is under 1 TB (the cost is not justified), or you need flexible querying, SQL, or a document structure. Bigtable is a specialist tool for a specific class of workload.
Example: a fleet tracking system ingests GPS coordinates from tens of thousands of vehicles per second. Bigtable stores billions of time-series records and allows fast range scans by vehicle ID and timestamp.
See Bigtable Overview and the detailed comparison at Cloud SQL vs Bigtable.
When to use Spanner
Spanner is Google’s globally distributed relational database. It supports SQL, ACID transactions, and strong consistency across multiple geographic regions simultaneously. It is what Google uses internally for large-scale, globally consistent workloads.
Use it when: you need relational SQL with strong consistency across more than one region, your write throughput exceeds what a single Cloud SQL instance can handle, or you are building global financial, payments, or multi-region SaaS systems where data must always be consistent regardless of where a user connects.
Do not use it when: a single-region relational database satisfies your requirements, as it does for the vast majority of applications. Spanner costs significantly more than Cloud SQL and requires a different approach to schema and query design.
When to use BigQuery
BigQuery is a managed data warehouse for analytical workloads. It stores data in columnar format, is billed per byte scanned for on-demand queries, and is optimised for queries that scan large amounts of data and return aggregated results.
Use it when: you need to run analytical SQL over millions or billions of rows: business dashboards, growth reports, ad-hoc analysis, ML feature engineering. It is the right home for collected data that needs to be understood rather than updated.
Do not use it when: your app needs low-latency individual row lookups. BigQuery is not designed for OLTP. Even simple queries have latency measured in seconds.
See BigQuery Overview and BigQuery vs Cloud SQL.
When to use Memorystore
Memorystore provides managed Redis and Memcached. Reads and writes happen in memory, which means microsecond-range latency. Use it to cache data that is expensive to compute or fetch repeatedly from a primary database.
Use it when: you need sub-millisecond reads for session data, rate-limit counters, feature flags, search autocomplete, or leaderboards that are expensive to regenerate from a database on every request.
Do not use it when: you need durable primary storage. In-memory stores can lose data on restart unless configured with persistence, and even with persistence they are not a replacement for a primary database.
How this works in real applications
Production applications almost always use more than one storage service. Each service is chosen for the specific workload it handles best.
Using multiple storage services in the same application is not over-engineering. It is the standard pattern. Each service does one thing well; using the right one for each workload is simpler and cheaper than forcing a single service to do everything.
E-commerce application
Cloud SQL (PostgreSQL): users, products, orders, inventory, payment records. Relational schema, ACID transactions, JOIN queries across tables.
Cloud Storage: product images, PDF invoices, bulk data exports. Files are served directly via signed URLs or a CDN origin.
Memorystore (Redis): product listing cache and session tokens. Reduces Cloud SQL load for high-traffic category pages.
BigQuery: daily export of order data for reporting dashboards. Analytics run in BigQuery without touching the production Cloud SQL instance.
SaaS team collaboration app
Cloud SQL: organisations, users, subscription plans, billing records. Core relational model.
Firestore: real-time document collaboration, activity feeds, notification state. Real-time listeners push changes to all connected users instantly.
Cloud Storage: file attachments, profile avatars, exported reports.
Memorystore: API rate limiting and short-lived invite tokens.
Event analytics platform
Bigtable: raw event ingestion at high throughput. Billions of events keyed by user ID and timestamp, with fast range scans for recent user activity.
Cloud Storage: raw event exports and long-term archival storage.
BigQuery: analytical queries over processed event data. Business dashboards, funnel analysis, cohort reports.
Firestore: real-time dashboard widgets showing live event counts pushed to users without polling.
See Reference Architecture for a broader look at how GCP storage and compute services fit together in system design.
When to use this page
This page is most useful in four situations:
Starting a new application. You are designing the data layer from scratch and want to choose the right service before writing code.
Migrating from another cloud provider. You know AWS S3, RDS, or DynamoDB and want to understand the GCP equivalents and where the differences matter.
Working on a side project. You want the simplest, most cost-effective option that will not require a database engine change if the project grows.
Deciding where files versus structured data should live. A common early architectural decision with downstream cost and performance implications.
Key comparisons to understand
Cloud Storage vs Cloud SQL
Cloud Storage stores files; Cloud SQL stores structured data in rows and tables. These are not competing choices and most applications use both. Store files in Cloud Storage and save the file URL as a field in Cloud SQL. See Cloud Storage vs Filestore for a related question about when to use network-attached file storage instead.
Cloud SQL vs Firestore
Cloud SQL is the right choice when your data is relational and you need JOINs, complex queries, or strong transactions. Firestore is the right choice when your data is document-shaped, your schema changes frequently, you need real-time client sync, or you want serverless scaling without managing instance size. See Cloud SQL vs Firestore for a detailed breakdown.
Cloud SQL vs Spanner
Both are relational databases with SQL and ACID transactions. Cloud SQL is a managed instance within a single region. Spanner spans multiple regions with consistent writes globally. For most applications, Cloud SQL is correct. Spanner is the upgrade path when you genuinely need global distribution or cannot scale a single instance vertically any further.
BigQuery vs Cloud SQL
Cloud SQL is an OLTP database for application reads and writes. BigQuery is an OLAP warehouse for analytical queries. They serve different purposes and are commonly used together, with Cloud SQL serving as the live application database and BigQuery receiving daily exports for analysis. See BigQuery vs Cloud SQL.
Bigtable vs Firestore
Both are NoSQL, but they serve different ends of the scale spectrum. Firestore is serverless, developer-friendly, and cost-effective at small to medium scale with a flexible document model. Bigtable is a specialist tool for petabyte-scale, high-throughput workloads with key-based access patterns. If your data is under 1 TB, Firestore is almost always the better fit. See Cloud SQL vs Bigtable for context on the query model trade-offs.
Regional vs multi-regional storage
For Cloud Storage specifically, you also choose a location type: single region, dual-region, or multi-region. This affects availability, latency, and cost. See Regional vs Multi-Regional Storage.
Cost considerations
Choosing the wrong service is one of the fastest ways to accumulate unexpected cloud costs. Here is the practical cost logic for each service.
Cloud Storage is very cheap for files. Fractions of a cent per GB per month for cold storage; a few cents per GB per month for standard storage. Retrieval costs apply on Nearline, Coldline, and Archive tiers, so match the class to how often you actually access the data.
Cloud SQL is billed per vCPU, per GB of RAM, and per GB of storage provisioned. You pay for instance uptime even when the database is idle. A small development instance costs very little; production costs grow with CPU and memory.
Firestore is billed per document read, write, and delete, plus storage per GB. Very low cost for small and medium workloads. A free daily quota covers most development use. On read-heavy workloads at scale, reading millions of documents per day accumulates cost quickly.
Bigtable is billed per node per hour plus storage. A minimum production cluster costs several hundred dollars per month before you store any data. Only economical above 1 TB with high write throughput.
Spanner is billed per processing unit and per GB of storage. Significantly more expensive than Cloud SQL. Justified only when global distribution or extreme horizontal scale is a genuine requirement, not a hypothetical future need.
BigQuery is billed per byte scanned for on-demand queries, or by capacity reservation. Cheap for infrequent analytical queries over large datasets. Costs grow if you run many full-table scans without partitioning or clustering. See BigQuery Pricing Explained.
Memorystore is billed per GB of memory provisioned per hour. Cost is predictable but you pay for provisioned capacity whether you are using it or not.
For broader cost management across GCP services, see Cost Optimisation Strategies.
Common mistakes
Never store image or file data inside a database column or document field. Even a few thousand rows with embedded image data will make your database slow to query, expensive to back up, and difficult to serve to users. Store a file path or URL in your database and the actual file in Cloud Storage.
Storing files inside a database. Storing images, videos, or binary blobs in a Cloud SQL column or a Firestore document bloats the database, slows queries, and makes file serving much harder. Store a URL or path reference in your database and the actual file in Cloud Storage. This is cheaper, faster, and easier to serve at scale.
Choosing Bigtable before the dataset justifies it. Bigtable is a specialist tool for petabyte-scale workloads. If your current dataset is under 1 TB, you are paying hundreds of dollars per month for nodes you do not need, and taking on key-design complexity that provides no benefit at that scale. Start with Firestore or Cloud SQL and migrate when the data genuinely justifies it.
Using BigQuery as an application database. BigQuery is a warehouse, not a transactional database. Row-by-row reads and writes at low latency are not what it is built for. If your application needs to read and write individual records quickly, BigQuery is the wrong tool. Use Cloud SQL or Firestore for live app data, and export to BigQuery for analysis after the fact.
Defaulting to Cloud SQL because SQL is familiar. Cloud SQL is the right choice for relational workloads, but it is not the right default for everything. For document-oriented data with variable schemas, Firestore scales without instance management. Choosing Cloud SQL for a use case Firestore handles better adds capacity planning overhead you could avoid.
Treating Memorystore as durable primary storage. Memorystore is a cache. Without persistence configured, data is lost on restart. Even with persistence enabled, it is not designed to be a reliable primary store. Use it to reduce load on a backend database, not to replace one.
Running analytical queries directly against the production Cloud SQL instance. Heavy reports and aggregations compete with application queries for CPU and I/O. Export data to BigQuery for analytics. If you must query the production database, use a read replica so analytical load does not degrade response times for your users.
Quick chooser
- Store files → Cloud Storage
- Relational SQL for an app, single region → Cloud SQL
- Relational SQL distributed globally → Spanner (significantly more expensive)
- Flexible document database or real-time client sync → Firestore
- Huge NoSQL dataset with very high write throughput (>1 TB) → Bigtable
- Analytics, reporting, and data warehouse queries → BigQuery (not for OLTP)
- Caching → Memorystore (not primary durable storage)
- Most applications use several of these together. Pick each service for what it handles best.
Frequently asked questions
What is the difference between Cloud Storage and Cloud SQL?
Cloud Storage holds files and objects: images, videos, PDFs, backups, raw data blobs. It has no schema and no way to query inside file contents. Cloud SQL stores structured relational data in tables, supports SQL queries, and handles relationships between rows. If you are storing files, use Cloud Storage. If you are storing queryable structured data, use Cloud SQL.
Should I use Firestore or Cloud SQL for my app?
Use Cloud SQL if your data is relational and you need JOINs, complex queries, or strong ACID transactions. Use Firestore if your data is naturally document-shaped (user profiles, settings, posts), you need real-time updates pushed to clients, or you want a serverless database that scales automatically without managing instance size. Most apps that would reach for MongoDB on another platform should look at Firestore on GCP.
Is BigQuery a database for applications?
No. BigQuery is a data warehouse designed for analytical queries: aggregations, joins across large tables, reporting. It is billed per byte scanned and optimised for full-table scans, not individual row lookups. Do not use it as the primary database for a web or mobile application. Use Cloud SQL or Firestore for that, and export data to BigQuery for analytics separately.
When should I use Spanner instead of Cloud SQL?
Use Spanner when you need strong consistency across multiple geographic regions, very high write throughput that exceeds what a single Cloud SQL instance can support, or a relational database that spans continents without replication lag. Spanner is significantly more expensive than Cloud SQL. For regional workloads, which covers the vast majority of applications, Cloud SQL is the right and more affordable choice.
Can I use multiple GCP storage services together in one application?
Yes, and this is the normal pattern in production systems. A typical app uses Cloud SQL for relational data, Cloud Storage for files, Firestore for real-time features, Memorystore for caching, and BigQuery for analytics. Each service handles what it is designed for. You are not required to pick one storage service for everything, and doing so usually creates problems.
Should I store images in Firestore or Cloud SQL?
Neither. Store the image file in Cloud Storage and save the URL or path as a field in Firestore or Cloud SQL. Storing binary image data inside a document or database row bloats storage, slows queries, and makes it harder to serve files efficiently. Cloud Storage is purpose-built for objects like images, and pairs naturally with signed URLs for access control.