Most professionals are paying for more subscriptions than they can count — Netflix, Spotify, SaaS tools, hosting plans, software licenses. One missed renewal and you're either locked out of a critical service or quietly charged for something you meant to cancel three months ago.
The fix doesn't require a paid app or a complex system. A Google Sheet and fifteen minutes is all you need to build an automated subscription tracker that emails you reminders on any schedule you choose.
Here's exactly how to build it.
What You'll Build
By the end of this guide you'll have:
- A Google Sheet that tracks all your subscriptions in one place
- An Apps Script that checks renewal dates daily
- Automatic email reminders sent directly to any address you specify
- A system that works for personal use or an entire team
No coding experience required. Every line of code is provided and explained.
Why Google Sheets + Apps Script?
There are paid subscription management tools out there. Most of them add friction — another login, another monthly fee, another tool your team won't actually use consistently.
Google Sheets works because everyone already uses it. It's free, accessible from any device, shareable with your team, and — when combined with Apps Script — surprisingly powerful as an automation platform.
For teams already exploring AI-powered business automation, this kind of lightweight automation is a great starting point for understanding what automated workflows can look like in practice.
Step 1: Set Up Your Google Sheet
Open Google Sheets and create a new spreadsheet. Rename the first tab to Subscription Tracker.
In row 1, create these column headers exactly as shown:
| Column | Header | Purpose |
|---|---|---|
| A | Client Name | Person or account tied to the subscription |
| B | Service Name | Name of the service (Netflix, Spotify, etc.) |
| C | Renewal Date | When it renews — format: YYYY-MM-DD |
| D | Reminder Days Before | How many days before renewal to send the alert |
| E | Email To Notify | Email address that receives the reminder |
| F | Details | Notes, plan type, cost — anything useful |
Tip: Format column C as a Date field to avoid issues. Go to Format → Number → Date.
Sample Data to Test With
Add these two rows to verify everything works before going live:
| Client Name | Service Name | Renewal Date | Reminder Days Before | Email To Notify | Details |
|---|---|---|---|---|---|
| John Doe | Netflix | 2026-08-25 | 3 | john@example.com | Entertainment TV plan |
| Jane Smith | Spotify | 2026-08-28 | 2 | jane@example.com | Premium monthly plan |
Step 2: Open Google Apps Script
In your Google Sheet, go to Extensions → Apps Script.
Delete any default code in the editor. Paste the following script in full:
function checkSubscriptions() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Subscription Tracker');
const data = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0,0,0,0);
for (let i = 1; i < data.length; i++) {
const client = data[i][0];
const service = data[i][1];
const renewalDate = new Date(data[i][2]);
renewalDate.setHours(0,0,0,0);
const reminderDays = Number(data[i][3]);
const email = data[i][4];
const details = data[i][5];
const diffTime = renewalDate - today;
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays <= reminderDays && diffDays >= 0) {
const subject = `Subscription Renewal Reminder: ${service}`;
const message =
`Hi ${client},\n\n` +
`This is a reminder that your subscription is coming up:\n\n` +
`Service Name : ${service}\n` +
`Renewal Date : ${renewalDate.toDateString()}\n` +
`Reminder Set For : ${reminderDays} day(s) before renewal\n` +
`Details : ${details}\n\n` +
`Please take any necessary action before the renewal date.\n\n` +
`Thank you!`;
MailApp.sendEmail(email, subject, message);
Logger.log(`Email sent to ${email} for ${service}`);
}
}
}
How the Script Works
The logic is straightforward:
- It reads every row in your sheet
- Calculates how many days remain until the renewal date
- If the days remaining are within your reminder window — it sends the email
- If the renewal is still far away — it does nothing and moves to the next row
The setHours(0,0,0,0) call strips the time component from both dates so
comparisons are always day-accurate regardless of what time the script runs.
Step 3: Authorize the Script
Click the Run (▶) button in the Apps Script editor.
Google will ask for permissions — this is expected. The script needs access to your sheet and the ability to send emails on your behalf.
- Click Review Permissions
- Select your Google account
- Click Allow
You'll only need to do this once.
Step 4: Set Up Automatic Triggers
Running the script manually works for testing, but the power is in automation. Here's how to make it run on its own:
- In Apps Script, click the Triggers icon (clock icon on the left sidebar)
- Click Add Trigger (bottom right corner)
- Configure it as follows:
| Setting | Value |
|---|---|
| Function to run | checkSubscriptions |
| Deployment | Head |
| Event source | Time-driven |
| Trigger type | Hour timer |
| Frequency | Every 8 hours |
- Click Save
The script will now run automatically every 8 hours. If a renewal is within your reminder window, the email goes out — no manual action required.
Step 5: Test It
Before going live, verify it actually works:
- Add a test subscription with a renewal date 2–3 days from today
- Set Reminder Days Before to
3 - Click Run manually in Apps Script
- Check the email address you entered — the reminder should arrive within a minute
- Go to View → Logs in Apps Script to see a full record of which rows were checked and which emails were sent
If no email arrives, check the Logs output for errors — the most common issue is a misformatted date in column C.
Optional Enhancements
Once the basic system is working, these upgrades make it significantly more useful:
Add Dropdown Menus
Use Data → Data Validation to create dropdown lists for Service Name or Category. This prevents typos and keeps your data consistent.
Extra Columns
Extend the sheet with additional columns and include them in the email:
- Amount — monthly or annual cost
- Category — software, entertainment, infrastructure
- Subscription Link — direct URL to manage or cancel
HTML Email Formatting
Replace the plain text email with a formatted HTML version for a more professional look:
const htmlContent = `
<h2>Subscription Renewal Reminder</h2>
<p>Hi ${client},</p>
<table>
<tr><td><strong>Service:</strong></td><td>${service}</td></tr>
<tr><td><strong>Renewal Date:</strong></td><td>
${renewalDate.toDateString()}</td></tr>
<tr><td><strong>Details:</strong></td><td>${details}</td></tr>
</table>
`;
MailApp.sendEmail(email, subject, '', { htmlBody: htmlContent });
Notify Multiple People
To send reminders to more than one person, separate email addresses with
commas in column E. Apps Script's MailApp.sendEmail() handles
comma-separated recipients natively.
Common Mistakes to Avoid
- Wrong date format — always use
YYYY-MM-DD. Other formats cause the script to misread the renewal date entirely - Sheet tab renamed — if you rename the tab away from "Subscription Tracker", update the sheet name in the script to match
- Columns moved or deleted — the script references columns by position (A=0, B=1, etc.). Moving columns breaks the script
- Trigger not saved — always click Save after configuring your trigger or it won't run automatically
Scaling This for a Team or Business
This setup works well for personal use and small teams. If you're managing subscriptions across a larger organization — multiple departments, dozens of vendors, complex approval workflows — you'll eventually hit the limits of what a spreadsheet can handle cleanly.
At that point, the right move is purpose-built tooling integrated into your existing systems. If you're evaluating what that looks like for your business, a strategic technology review can help you identify where automation adds the most value without over-engineering the solution.
Frequently Asked Questions
Does this work if I'm not a developer? Yes. The entire script is provided — you just copy, paste, and authorize it. No coding knowledge is needed to get the basic system running. The optional enhancements require minor edits but each one is explained step by step.
Will it send duplicate emails if the trigger runs multiple times a day? It will send an email every time the script runs while a subscription is within the reminder window. If your trigger runs every 8 hours and your reminder window is 3 days, you could receive up to 9 emails per subscription. To prevent this, add a "Notified" column and update it after sending — the script can then skip already-notified rows.
Can I track subscriptions for multiple clients or team members? Yes. Just add each subscription as a separate row with the relevant email address in column E. The script sends reminders to whichever email is specified per row — you can mix personal and team addresses freely.
What happens if the renewal date has already passed?
The condition diffDays >= 0 means the script only triggers for today or
future dates. Past renewals are ignored automatically.
Is there a limit to how many rows the script can handle? Google Apps Script has a daily execution time limit of 6 minutes on free accounts. For a typical subscription tracker with under 500 rows, this is never an issue. Very large datasets may need optimization.
Can I use this for client billing reminders instead of subscriptions? Absolutely. The same logic applies to any date-based reminder — invoices, contract renewals, project deadlines, or license expirations. Just rename the columns to match your use case and update the email template accordingly.

