Skip to main content
All notes

When Google Sheets Is Enough as a Web App Database, and When to Move On

Google Sheets can work as a web app's database through Apps Script, cheap and fast, but it has cell limits, execution limits, and concurrent-access conflict risks. Here's how to tell when Sheets is still enough, and when it's time to move to MySQL or Firebase.

Share

Share to Instagram Stories

Preparing image…

  1. The link is copied.
  2. Download the image, then post it to Instagram Stories from your phone.
  3. Add a Link sticker to your Story and paste the link.
Download image

Instagram Stories can only be posted from the phone app.

Share to TikTok

Preparing image…

  1. The caption and link are copied.
  2. Download the image, then post it as a photo on TikTok.
  3. Paste the caption before you post.
Download image

Easiest to post from the TikTok app on your phone.

An overflowing filing cabinet drawer stuffed with paper documents next to a compact server module, lit in burgundy

Turning Google Sheets into a web app's backend through Apps Script is genuinely game changing. It's free, clients already know the interface, and it can go live in days, not weeks. Almost every system I build for small to medium clients starts with this pattern.

But Sheets still has limits, and those limits aren't just about "when it fills up." In this article I cover the actual limits, the problem that usually shows up before those limits ever do, and how I set expectations with clients about the safe range from the start, before the system is even built.

The limits of Google Sheets that rarely get read until they bite

A few of these limits are hard, they can't be bought or upgraded away:

  • 20 million cells per spreadsheet. This is a new number, just doubled from 10 million by Google, rolling out starting September 10, 2026. This limit applies to the whole file, not per tab, and empty cells count toward it.
  • 18,278 columns maximum (up to column ZZZ) per sheet.
  • 6 minutes per execution for Apps Script, the same for free accounts and Google Workspace, according to the official Apps Script documentation. The 30-minute limit often quoted for Workspace accounts no longer applies.
  • Daily trigger runtime: 90 minutes for free accounts, 6 hours for Google Workspace.
  • UrlFetch (for calling external APIs from Apps Script): 20,000 calls a day on free accounts, 100,000 on Workspace.
Cell limit per spreadsheet, up from 10 million starting September 2026
20 million
Apps Script execution limit per run, the same for every account tier
6 minutes
Daily trigger runtime on free accounts, 6 hours on Workspace
90 minutes

That cell number looks huge, but what actually matters is how many rows you get, and that depends on how many columns you use:

Estimated maximum rows, depending on column count(rows)

  • 5 columns4M
  • 10 columns2M
  • 20 columns1M
  • 26 columns±769K
Calculated from the 20-million-cell limit per spreadsheet. The more columns each row uses, the fewer rows fit.

The problem that usually shows up first: concurrent access conflicts

In my experience, projects rarely fail from running out of cells. What causes trouble more often is several people or processes hitting the same sheet at close to the same moment.

Google Sheets itself handles many people typing into it at once just fine at the UI level. The problem is at the Apps Script level: if two script executions both read the last row's position and then write to the next one, and that happens nearly simultaneously, the result can be two rows overwriting each other, or an ID that was supposed to be unique ending up duplicated.

A laptop showing a document interface with several overlapping colored cursors, representing multiple people editing at the same time
Concurrent access conflicts usually show up before capacity limits do.

Apps Script's LockService can force these operations to run one at a time, but that means requests arriving at the same moment get queued instead. If it isn't set up correctly, the failure mode isn't an error message, it's data quietly going wrong without anyone noticing.

Not every project needs a "fancier" database

Moving to MySQL or Firebase isn't just a technical decision, it brings new cost and complexity: a server or managed service to run, extra backend code to write, and the client can no longer just open a spreadsheet to see their own data directly.

Sheets is usually still enough when:

  • Writes don't happen that often within the same few seconds (a form filled out a few times a day, not hundreds of times a minute).
  • The data volume sits comfortably below the cell limit, with clear room to grow.
  • The client actually wants to open and check the data directly, without needing an admin panel.
  • The system doesn't need real-time sync across many screens at once.

It's worth considering a move once:

  • Reports of data getting "overwritten" or lost start showing up regularly.
  • Scripts start hitting the 6-minute timeout as the data grows.
  • The data needs complex relationships across many tables, not just independent rows.
  • The system needs a view that updates itself in real time across multiple devices at once.

Once it's time to move

Two directions I use most often:

  • MySQL or PostgreSQL: a regular relational database, running on your own VPS (I cover the specs and cost in more depth in What Is a VPS for AI, and What Can It Actually Do?). A good fit when the data has a lot of relationships across tables and you want full control.
  • Firebase/Firestore: a managed service from Google, strong at real-time sync across many users at once, with no server of your own to manage. A good fit for an app where several people need to see data changes live, without a manual refresh.

Setting expectations with the client from the start

This is the part that's easy to skip: the client needs to know the safe range while the system is still at the planning stage, not once it starts slowing down. Before building on top of Sheets, I always align on three things with the client:

  1. An estimate of how many users will access it at once, and how often they'll write data at the same moment.
  2. An estimate of data growth over the next year, so there's a safe margin to the cell limit.
  3. What happens if a database migration becomes necessary later, so it isn't a surprise.

Wrapping up

Google Sheets as a database isn't a shortcut you need to rush away from, but it's also not a fit for every scale forever. What matters is knowing the limits upfront, not discovering them once the client is already relying on the system.

If you're weighing whether to use Sheets or go straight to a bigger database, tell me about your system's needs, and we'll work out the right scale together.

Found this useful? Share it with a friend or your team.

Share

Share to Instagram Stories

Preparing image…

  1. The link is copied.
  2. Download the image, then post it to Instagram Stories from your phone.
  3. Add a Link sticker to your Story and paste the link.
Download image

Instagram Stories can only be posted from the phone app.

Share to TikTok

Preparing image…

  1. The caption and link are copied.
  2. Download the image, then post it as a photo on TikTok.
  3. Paste the caption before you post.
Download image

Easiest to post from the TikTok app on your phone.

Is your team still doing something by hand?

Tell me about it, and let's find the fix together.