Run SQL in Google Sheets without writing Apps Script JDBC
Apps Script’s JDBC service works, and this page shows you the honest version of it: the code, the six-minute limit, the IP ranges, the password in the script. Then it shows the other way: a small Agent next to your database runs the SQL, and a Google Sheets add-on pulls the rows into your sheet. No JavaScript, no firewall changes, and the Free plan covers it.
If you still want Apps Script JDBC, here is the honest version
Google’s JDBC service connects Apps Script to MySQL, Google Cloud SQL for MySQL, PostgreSQL, Microsoft SQL Server and Oracle. The smallest working script that fills a sheet looks like this:
function loadCustomers() { const props = PropertiesService.getScriptProperties(); // keep the password out of the code const conn = Jdbc.getConnection('jdbc:mysql://db.example.com:3306/sales', props.getProperty('DB_USER'), props.getProperty('DB_PASS')); const rs = conn.createStatement().executeQuery('SELECT customer_id, name, city FROM customers LIMIT 1000'); const rows = []; while (rs.next()) rows.push([rs.getString(1), rs.getString(2), rs.getString(3)]); rs.close(); conn.close(); const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Customers'); sheet.clearContents(); sheet.getRange(1, 1, rows.length, 3).setValues(rows); }
The sample uses MySQL. For the other engines only the connection string changes: jdbc:postgresql://, jdbc:sqlserver:// and jdbc:oracle:thin:@ follow the same shape, and Cloud SQL uses jdbc:google:mysql://. Before that runs, your database has to accept connections from Google’s servers. Google publishes the address ranges as a JSON file that you add to your database firewall and keep in step with, and the database must listen on a port of 1025 or higher. The limits that bite in practice come from Google’s quotas page:
| Limit | Personal Google account | Google Workspace account |
|---|---|---|
| Script runtime, per execution | 6 minutes | 6 minutes |
| Custom function runtime (a formula that calls JDBC) | 30 seconds | 30 seconds |
| JDBC connections per day | 10,000 | 50,000 |
| Simultaneous executions per user | 30 | 30 |
| Time-driven triggers, total runtime per day | 90 minutes | 6 hours |
Two things the sample above hides. Google’s own examples pass the user name and password as plain strings in the code, and most scripts in the wild copy that; the script properties trick keeps them out of the source but anyone who can edit the script can still read them. And every row has to fit in the script’s memory and finish inside the six minutes, so a slow query or a wide table means chunking the work by hand. If your table is small, your database is already reachable from the internet, and one developer owns the script, JDBC is fine. The rest of this page is for everyone else.
What you’ll end up with instead
A Google Sheet that holds the result of a SQL query against your database, with a Run Query button in the side panel that pulls the latest rows whenever you want them. Like this:
| A | B | C | D | E | |
|---|---|---|---|---|---|
| 1 | customer_id | first_name | last_name | country | total |
| 2 | 1042 | Maria | Alvarez | USA | 1,284.50 |
| 3 | 1043 | Daniel | Okafor | USA | 612.00 |
| 4 | 1047 | Priya | Nair | USA | 2,090.75 |
| 5 | 1051 | Thomas | Berg | USA | 338.20 |
| 6 | 1056 | Lucía | Ferreira | USA | 1,455.00 |
| 7 | 1060 | Kenji | Sato | USA | 874.10 |
| 8 |
Live from your databaseThe difference is where the query runs. With JDBC, Google’s servers open a connection into your database, so your firewall has to let them in and the script has to hold the password. With Query Streams, a small program called the Agent runs on a computer that can already reach the database, makes one outbound connection to Query Streams, and runs the SQL there. The Google Sheets add-on asks for the rows and only the rows travel. Nothing is opened on your firewall, and the password never leaves the Agent.
What you’ll need
The Agent on a computer that can reach the server
A small program that runs in the background and queries the database when Google Sheets asks. Often the database server itself, or any always-on computer on the same network.
Your own connection details
The server name, the database name, and a username and password that can read it. If someone else manages the database, this is the bit to ask them for.
Which computer gets the Agent? Any always-on machine that can already reach your own database, often the database server itself or a computer on the same network. Google Sheets can be anywhere; it runs in your browser.
Set it up in four steps
-
Create your account
Go to my.querystreams.com and sign up with the Google account you use for Sheets. Pick the Free plan. It is a real plan, not a trial, and it covers two connections and ad-hoc SQL from Google Sheets.
Install the Agent on a computer that can reach the server



Sign in, open Download, and install the Agent on a machine that can already reach your own database: often the database server itself, or any always-on computer on the same network. It takes a minute and starts on its own from then on.
Why a small program instead of a driver? The Agent is one install for Windows, Mac or Linux (about 85 MB on Windows, a little over 100 MB on Mac and Linux) that runs quietly in the background. It makes one outbound, encrypted connection to Query Streams, the same way a browser does, so you open no firewall port and set up no VPN. Your database stays on your network, and the rows travel to wherever you are, across the internet if need be. The only thing on your side is the add-on.
The Download page shows Your Access Key. Paste it into the Agent when it asks, and wait for the badge to read Connected to Query Streams. That is the only thing you do on the Agent itself.
-
Add your database connection
In the portal open Data → Data Agents, click Add connector on your Agent, choose the database type and fill in the host, port, database and a read-only login. Click Test connection, then Save. The connection reaches the Agent within a few seconds. Each database has its own walkthrough with the exact fields: MySQL, PostgreSQL, SQL Server, Oracle. Cloud SQL, Amazon RDS and Azure databases connect the same way; the Agent just needs to be able to reach them.
No IP allowlist. The Agent connects to your database from inside your network and to Query Streams outbound over HTTPS. There is no list of Google addresses to add to the firewall and nothing to keep in step with.
-
Run the SQL from Google Sheets
Open your spreadsheet and install the Query Streams add-on from the Google Workspace Marketplace if you have not yet. It recognises the Google account you are already signed in with; there is no separate login. In the side panel click Query Streamer, pick your connection, and paste the same SELECT you would have put in the script:
Example · SQLSELECT customer_id, name, city FROM customers ORDER BY name LIMIT 1000;
Choose the tab under Destination Sheet and click Run Query. The rows land under your column headers. Click Run Query again whenever you want the latest data. To have the sheet refresh on its own, save the query in Query Builder and set up an Automation, which runs it on a schedule from every five minutes to weekly.
That’s it. Your data is in the sheet and stays current with one click. Nothing left your network except the rows you asked for.
Side by side, only what holds up
| Apps Script JDBC | Query Streams | |
|---|---|---|
| What you write | JavaScript around your SQL | The SQL |
| Where the query runs | On Google’s servers, connecting into your database | On the Agent, next to your database |
| Database password | In the script or its properties, readable by anyone who can edit it | On the Agent only; Sheets users never see it |
| Firewall | Allow Google’s published address ranges, port 1025 or higher | Nothing inbound; the Agent connects out over HTTPS |
| Time limit | 6 minutes per execution, 30 seconds for a custom function | No script to time out; the Agent runs the query and streams the rows |
| Quotas | 10,000 or 50,000 JDBC connections a day, 90 minutes or 6 hours of trigger time | A monthly data allowance per plan, from 5 MB on Free |
| Giving a colleague the data | Copy the script, and the credentials with it | Share the query’s results; the recipient runs it, never sees the login |
| Refresh on a schedule | Time-driven trigger inside the daily runtime quota | Automation, every 5 minutes to weekly |
| Databases | MySQL, Cloud SQL, PostgreSQL, SQL Server, Oracle | Those five plus MariaDB, Snowflake, BigQuery, SQLite, Access, DuckDB, folders of files, and APIs such as Stripe, HubSpot and Shopify |
What the plans allow
Ad-hoc SQL from the Google Sheets add-on is on every plan, including Free. Free includes two connections and a monthly data allowance of 5 MB of results, enough for a table like the one above refreshed many times a day. Running queries you saved in Query Builder from the add-on starts at Personal Core; queries a colleague shares with you run on every plan. See the pricing page for the allowances by plan.
Free is a plan you keep. It is not a trial that expires. See exactly what it includes on the pricing page.
Questions people ask
Can I keep my existing Apps Script and just fix the password problem?
Yes. Move the user name and password into script properties as in the sample above, and give the database login read-only rights. That fixes the worst of it. It does not change the six-minute limit, the daily connection quota, or the firewall allowlist, which is why most people move the query out of Apps Script once the sheet matters to more than one person.
Does the Agent have to run on the database server?
No. Any always-on computer that can reach the database works: a workstation in the office, a small virtual machine, or the server itself. It only needs outbound HTTPS to Query Streams.
Is there a row limit like JDBC’s memory ceiling?
The Agent streams rows rather than holding the whole result in a script, so the practical ceilings are your plan’s data allowance and Google Sheets itself, which caps a spreadsheet at 20 million cells (10 million on accounts Google’s September 2026 rollout has not reached yet). Keep the SELECT to the columns and date range you need and both stay comfortable.
I use Cloud SQL. Does that change anything?
Only where the Agent runs. Put it on a computer or virtual machine that can reach the Cloud SQL instance, either over its public address with the Agent’s address authorised, or inside the same network, and connect it as MySQL, PostgreSQL or SQL Server. There is no Google address range to maintain.
Does your own database have to be on the computer I use Sheets on?
No. Only the Agent has to be where your own database is. Google Sheets runs in your browser on any device. Open the add-on with the same Google account and your connections are there.
Does my data get copied to Query Streams?
No. The Agent runs the query where your data is and sends only the rows it returns. Nothing is synced or stored in between.
Does the Free plan really cover this?
Yes. Free is a plan you keep, not a trial that expires. See exactly what it includes on the pricing page.
Does the sheet refresh by itself?
Click Run Query again whenever you want the latest rows. For a sheet that refreshes on a schedule without anyone pressing anything, set up an Automation in the Query Streams portal (Streams → Automation). It is on every plan.
Related guides
Setup trouble?
- Agent shows Offline, or Test connection and Browse are greyed out? Check that the Agent is online → Is the Agent online?

