Many freelancers and agency owners know what each client pays. What they do not always know is how many hours of work that revenue consumes.
Here’s a system that helps you answer one question every week: Is this client still profitable? Based on the results, you can keep the account as it is, change the scope, raise the price, or fix the process.
Tools
- Jotform — collects information from your weekly review.
- Google Sheets — tracks margins and recurring issues.
- Zapier — automates the workflow.
- AI by Zapier — summarizes updates and drafts emails.
- Gmail — sends reminder emails and saves the report.
The workflow
This system uses three Zaps.
- Zap 1 sends you the form every Friday.
- Zap 2 sends each form response to Google Sheets.
- Zap 3 sends the spreadsheet data to AI and saves the report as a Gmail draft.
Google Sheets calculates the results. AI summarizes the results and drafts messages. You review the report and decide what to do next.
Let's get started.
Step 1 — Decide what “profitable” means
Open: Google Sheets
- Click: Blank spreadsheet
- Rename the spreadsheet: Weekly Margin Tracker
- Rename the first worksheet tab: Client Setup
- In cells A1:F1, enter these headings: Client, Monthly Revenue, Weekly Hours Budget, Internal Hourly Cost, Weekly Direct Cost, Minimum Margin
Create one row for each client and complete every column.
Enter the following information for each client:
- Monthly Revenue: how much the client pays each month.
- Weekly Hours Budget: how many hours you expect to spend on the client each week.
- Internal Hourly Cost: the cost of one delivery hour to your business. Don’t enter zero, even if you complete the work yourself.
- Weekly Direct Cost: any other weekly cost directly related to serving the client.
- Minimum Margin: the lowest acceptable margin, entered as a percentage.
You will use this info in the formulas added later.
Step 2 — Create the weekly form
Open Jotform and create a new Classic Form.
Name it Friday Client Review.
Next, add the fields listed below.
- Date Picker — Week Ending
- Dropdown — Client
- Number — Hours Worked
- Dropdown — Project Status
- Long Text — Work Completed
- Long Text — Blocker Notes
- Single Choice — Unpaid or Out-of-Scope Work?
- Long Text — Extra Work Notes
Add these options:
- Project Status: On track, At risk, Blocked, Complete
- Unpaid or Out-of-Scope Work?: Yes, No
Copy the client names from Client Setup into the Client dropdown.
Make Week Ending, Client, Hours Worked, Project Status, and Unpaid or Out-of-Scope Work? Required. Complete one form for each client every Friday.
Next, show Extra Work Notes only when Yes is selected.
- Open: Settings
- Click: Conditions
- Select: Show/Hide Field
Create this rule: IF Unpaid or Out-of-Scope Work? IS EQUAL TO Yes, SHOW Extra Work Notes
- Click: Save
- Click: Publish
- Click: Copy Link
Submit one test response. Select Yes and make sure Extra Work Notes appears. You'll use this test response when you connect the form to Zapier.
Step 3 — Send each response into Sheets
Return to Weekly Margin Tracker.
- Click: Add sheet
- Rename the worksheet: Weekly Updates.
- In cells A1:H1, enter these headings: Week Ending, Client, Hours Worked, Project Status, Work Completed, Blocker Notes, Unpaid Work, Extra Work Notes
Keep this worksheet for raw Jotform submissions only.
Next, go to Zapier and create a Zap:
- Select app: Jotform
- Select trigger: New Submission
- Choose form: Friday Client Review
- Click: Test trigger
Add an action.
- Select app: Google Sheets
- Select action: Create Spreadsheet Row
- Choose: Weekly Margin Tracker → Weekly Updates
Map each form field to the matching column.
Click: Test action
Check that the test row is correct and the value in column A is recognized as a date.
Step 4 — Add the calculations in Google Sheets
Open the _Weekly Margin Tracke_r spreadsheet.
Click: Add sheet:
- Rename the worksheet: Margin Review.
- In cells A1:Q1, enter: Week Ending, Client, Hours Worked, Project Status, Work Completed, Blocker Notes, Unpaid Work, Extra Work Notes, Monthly Revenue, Weekly Revenue, Hours Budget, Estimated Cost, Estimated Margin, Margin %, Hours Flag, Margin Flag, Boundary Flag
Start by displaying the client updates from Weekly Updates.
Click cell: A2
- Paste: =IFERROR(FILTER('Weekly Updates'!A2:H,'Weekly Updates'!A2:A<>""),"")
- Press: Enter
Columns A through H will automatically show every client update.
Next, add the formulas below to columns I through Q. Press Enter after each one.
Monthly revenue
- Click cell: I2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IFNA(VLOOKUP(B2:B,'Client Setup'!A:F,2,FALSE),"")))
Weekly revenue
- Click cell: J2
- Paste: =ARRAYFORMULA(IF(I2:I="","",I2:I/4.33))
Weekly hours budget
- Click cell: K2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IFNA(VLOOKUP(B2:B,'Client Setup'!A:F,3,FALSE),"")))
Estimated delivery cost
- Click cell: L2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IFNA(C2:C\*VLOOKUP(B2:B,'Client Setup'!A:F,4,FALSE)+VLOOKUP(B2:B,'Client Setup'!A:F,5,FALSE),"")))
Estimated margin
- Click cell: M2
- Paste: =ARRAYFORMULA(IF(J2:J="","",IF(L2:L="","",J2:J-L2:L)))
Margin percentage
- Click cell: N2
- Paste: =ARRAYFORMULA(IFERROR(IF(M2:M="","",M2:M/J2:J),""))
Hours flag
- Click cell: O2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IF(K2:K="","SETUP ERROR",IF(C2:C>K2:K,"OVER BUDGET","WITHIN BUDGET"))))
Margin flag
- Click cell: P2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IF(N2:N="","SETUP ERROR",IF(IFNA(VLOOKUP(B2:B,'Client Setup'!A:F,6,FALSE),"")="","SETUP ERROR",IF(N2:N
Unpaid-work flag
- Click cell: Q2
- Paste: =ARRAYFORMULA(IF(B2:B="","",IF(G2:G="Yes","UNPAID WORK","NONE")))
Finally, format the results.
Select column: N
- Click: Format
- Select: Number
- Select: Percent
Select column: A
- Click: Format
- Select: Number
- Select: Date
You only need to enter each formula once. New rows will be calculated automatically.
Before moving on, check the test row. If SETUP ERROR appears, check the client name and setup values.
Step 5 — Find repeated client problems
Create another worksheet to track problems that happen more than once.
- Click: Add sheet
- Rename it: Client Review
- In cells A1:E1, enter these headings: Client, Over-Budget Updates, Unpaid-Work Updates, Low-Margin Updates, Decision
Paste your active client names into column A, starting in cell A2.
Enter these formulas:
Enter:
- B2 =COUNTIFS('Margin Review'!$B:$B,$A2,'Margin Review'!$A:$A,">="&TODAY()-28,'Margin Review'!$A:$A,"<="&TODAY(),'Margin Review'!$O:$O,"OVER BUDGET")
- C2 =COUNTIFS('Margin Review'!$B:$B,$A2,'Margin Review'!$A:$A,">="&TODAY()-28,'Margin Review'!$A:$A,"<="&TODAY(),'Margin Review'!$Q:$Q,"UNPAID WORK")
- D2 =COUNTIFS('Margin Review'!$B:$B,$A2,'Margin Review'!$A:$A,">="&TODAY()-28,'Margin Review'!$A:$A,"<="&TODAY(),'Margin Review'!$P:$P,"LOW MARGIN")
- E2 =IF(OR(B2>=2,C2>=2),"REPEATED OVERAGE",IF(D2>=2,"REPEATED LOW MARGIN","STABLE"))
Select: B2:E2
Copy the formulas down for every client. Complete only one review for each client every Friday. Otherwise, the counts will be too high. COUNTIFS counts rows that match several conditions, such as the client, date range, and flag.
Step 6 — Send the weekly reminder
Create another Zap.
- Select app: Schedule by Zapier
- Select trigger: Every Week
- Choose: Friday
- Set: 8:00 AM.
Check your Zapier account time zone.
- Add app: Gmail.
- Select action: Send Email.
- Send the email to yourself.
- In the Subject, enter this (or something similar): Complete your Friday client reviews
In the email body, remind yourself to complete one review for every active client before 2:00 PM. Count all work completed, including calls, messages, revisions, admin work, and quick fixes. Use your calendar or time tracker instead of estimating your hours.
Paste the Jotform link into the email. Test the email and publish the Zap.
Step 7 — Create the founder report
Create a third Zap.
- Set the trigger:Schedule by Zapier → Every Week → Friday → 4:00 PM
- Add: Google Sheets
- Select: Get Many Spreadsheet Rows (Advanced)
- Choose: Weekly Margin Tracker → Margin Review
Set Columns to A:Q, First Row to 2, and Row Count high enough to include every populated row, up to 1,500.
Choose: A single JSON value
Repeat the action for Client Review, using columns A: E.
- Add: AI by Zapier
- Select: Analyze and Return Data
- Choose model tier: Standard
Paste this prompt (or something similar):
Review the supplied margin-review rows and client-review counts. Use only updates from the past 28 days. Do not recalculate financial figures. Use only the supplied data.
Return:
Clients needing attention.
Their latest hours, margin, status, and flags.
The main blocker in one sentence.
One action: reduce scope, raise price, change the process, or end the engagement.
A short client email only for REPEATED OVERAGE or REPEATED LOW MARGIN."No change needed" for stable clients.
Do not invent facts. Mark uncertain points for review.
Map both Sheets JSON outputs into the prompt.
- Add: Gmail
- Select: Create Draft
Address it to yourself. Use Friday Margin Review as the subject and map the AI output into the body.
Test the Zap, confirm the draft appears, then publish. Never auto-send a boundary email.
Review the figures, context, promises, and tone yourself first.
Run the 15-minute Friday review
Spend 15 minutes reviewing your client reports. Your goal is to find clients that need attention.
- Over-budget clients may need less work, more time, or an added fee.
- Low-margin clients may need a pricing or scope change.
- Repeated overages usually need a conversation with the client.
- Stable clients usually don't need changes, but you should still review their progress.
As a starting point, wait until you've collected four weeks of data before changing your margin target, unless there's an obvious problem that needs immediate attention.
The part that took me longest to learn is exactly your Step 1: refusing to put zero in "internal hourly cost" when I'm the one doing the work. As soon as I priced my own hours, two "good" retainers turned out to be barely break-even once revisions and Slack time were counted. One thing I'd add to the Friday form is a field for unbilled communication time specifically — for me that's where scope quietly leaks, not in the actual delivery work. I also found the "at risk / blocked" status only helps if the client sees it too, otherwise you're the only one tracking a problem you can't fix alone. Curious whether you ever share any slice of that weekly review with the client, or keep it strictly internal?
The part worth calling out is that this only works if internal hourly cost gets entered honestly, including your own time at real value. Most freelancers leave that field at zero without meaning to, since it does not feel like a real cost, then wonder why every client looks profitable. Keeping the raw form data separate from the calculated margin sheet is a good habit too, most people build the two together and regret it once they need to change a formula.
testing this one out stat! thanks again