How the Accounts Receivable Aging Report Buckets Your Invoices
In this article
The accounts receivable aging report sorts every unpaid invoice into one of five buckets based on how many days past its due date it is: current, 1-30, 31-60, 61-90, and 90+. It's a standard financial-reporting concept, but the exact mechanics of how an invoicing tool decides which bucket an invoice belongs in — and which invoices it excludes entirely — are usually invisible to the person reading the report. Understanding those mechanics matters if you're trying to reconcile the report against your own manual tally, or explain to an accountant why a number looks different than they expected.
How the Bucket Boundaries Actually Work
The bucket assignment is a straightforward comparison against days past the due date, calculated as of the moment the report is generated: an invoice with zero or fewer days past due (meaning it isn't due yet, or is due today) lands in "current." One to 30 days past due goes in the first aging bucket. 31 to 60 days past due goes in the second. 61 to 90 days past due goes in the third. Anything beyond 90 days past due — 91 days, 200 days, two years — all collapses into a single "90+" bucket with no further subdivision. There's no separate "180+" or "1 year+" tier; once an invoice crosses 90 days overdue, the report stops distinguishing further by age.
The days-past-due calculation itself is done by comparing calendar dates, not timestamps — both the due date and "today" are normalized to midnight UTC before the difference is taken, so the bucket an invoice falls into doesn't shift depending on what time of day you happen to load the report. An invoice due exactly today is treated as day zero, not day one, and stays in "current" until the calendar date actually passes.
Which Invoices Are Excluded Entirely
Not every invoice in your workspace appears on the aging report. Three categories are filtered out before bucketing even happens. First, invoices with a status of paid, cancelled, or archived are skipped — the aging report is specifically about money that's still outstanding, so a paid invoice contributes nothing to it regardless of how late the payment came in. Second, estimates are excluded — the report only considers documents of type "invoice," since an estimate isn't a receivable by definition; it hasn't been billed yet. Third, any invoice where the outstanding balance calculates to zero or less is skipped even if its status is technically something other than "paid" — this covers edge cases like an invoice that's been fully paid through partial payments but hasn't had its status field explicitly updated yet.
This matters in practice: if you're comparing the aging report's invoice count against a raw list of everything in your invoices table, the numbers won't match, and that's expected rather than a bug. The aging report is deliberately narrower than "every invoice you've ever created" — it's specifically "every invoice that currently represents money someone still owes you."
How the Outstanding Amount Is Calculated Per Invoice
For each invoice that survives the filtering, the report calculates an outstanding balance as the invoice total minus whatever has been paid against it so far, with the paid amount clamped between zero and the total — so a data anomaly where more was recorded as paid than the invoice was worth can't produce a negative outstanding balance that would throw off the bucket totals. If that clamped outstanding amount comes out to zero or less, the invoice is dropped from the report at this stage even if it passed the earlier status filter, which is how a manually-marked-paid invoice with no matching payment record can still disappear from the aging report despite its status not being "paid" in the strict sense used elsewhere in the product.
Currency Grouping, Not Currency Conversion
If your invoices span more than one currency, the aging report doesn't attempt to convert everything into a single number. Instead, it groups totals separately by currency — you'll see one set of bucket totals for USD invoices, a separate set for EUR invoices, and so on, each keyed by the currency code and symbol stored on the invoice itself. There's no exchange-rate lookup happening anywhere in the calculation. This is a deliberate simplification: converting foreign-currency receivables into a single reporting currency requires picking a specific exchange rate at a specific point in time, which introduces a number that's accurate only as of that moment and starts drifting the second real exchange rates move. Keeping currencies separate avoids presenting a blended total that implies more precision than it has.
Client Matching Uses Exact Comparison, Not Fuzzy Matching
Each invoice row on the aging report is matched to a client record so the report can display a client name rather than just a billing address. That matching happens two ways: first by an exact match on the client's email address against the invoice's billed email, and if that doesn't resolve, by an exact, case-insensitive match between the invoice's "bill to" text and the client's stored billing details. Earlier versions of this matching logic used substring matching on the client name, which had a real failure mode — if one client's name happened to be a substring of another client's full billing address, invoices would get misattributed to the wrong client on the report. That's why the matching was tightened to require an exact match rather than "contains." An invoice that doesn't match any saved client by either method is labeled "Unmatched" on the report rather than silently attached to the closest-looking name.
Sorting and the CSV Export
Once every remaining invoice has been bucketed, the report sorts the invoice-level rows by days past due, descending — so the invoices that have been outstanding longest appear at the top, which is generally the order you actually want to work through a collections list. The report is available both as a JSON response for the in-app view and as a CSV download for spreadsheet work or handing to an accountant, with the CSV using the same underlying bucketed data — client name, invoice number, due date, days past due, bucket, outstanding amount, and currency — so there's no discrepancy between what you see on screen and what you get in the export.
Reading the Report Correctly
The most common misreading of an aging report is treating the bucket totals as a full picture of revenue at risk, when they're really a picture of collection urgency sorted by time. A large 90+ bucket doesn't necessarily mean a large amount of bad debt — some of those invoices may simply belong to clients on unusually long payment terms, or clients you've already agreed to a payment plan with outside the invoice's stated due date. The report has no concept of a renegotiated timeline; it only knows the due date stored on the invoice. If you've verbally or contractually extended a deadline, the aging bucket won't reflect that until you update the invoice's due date to match, which is worth doing specifically so the report stays a useful proxy for "what actually needs a follow-up email today" rather than a list you have to mentally filter every time you look at it.
How the Aging Buckets Line Up With Automated Reminders and Late Fees
The aging report's bucket boundaries aren't arbitrary, and it's worth noticing how closely they track the platform's other overdue-related automation. Automated overdue reminders fire at fixed thresholds of 3, 7, 14, and 30 days overdue, and automated late fees apply after a configurable grace period measured in days past due. Both of those mechanisms are already independently working an invoice before it ever reaches the aging report's 31-60 bucket — by the time an invoice shows up there, it's very likely already triggered at least the 30-day reminder, and possibly a late fee, if you have those features turned on. The aging report doesn't drive either of those automations itself; it's a separate, read-only view calculated fresh each time you load it, while reminders and late fees are driven by their own scheduled background sweeps checking the same underlying due dates independently. Treat the aging report as the dashboard-level summary of exactly the same overdue population that reminders and late fees are already quietly acting on in the background — if an invoice looks stuck in your 61-90 bucket for weeks despite automated reminders being enabled, that's usually a signal the automation has run its course and the invoice needs a manual, personal follow-up rather than another automated nudge.
Why "Current" Still Matters on a Report About Overdue Money
It might seem odd that a report focused on aging receivables includes a "current" bucket for invoices that aren't even overdue yet, but it exists for a practical reason: it gives you the full outstanding balance across your entire receivables book in one place, not just the overdue portion of it. A workspace with a large "current" bucket and a small overdue bucket is in a fundamentally healthier position than one where the numbers are reversed, even though both workspaces might have an identical total amount outstanding. Watching how quickly invoices move from "current" into the 1-30 bucket over time — rather than only watching the overdue buckets in isolation — is often the earliest available signal that a particular client relationship, or your collections process generally, is starting to slip.
Related Articles
Client Statement vs. Accountant Report: What's the Difference
Two reports pull from the same data but serve opposite purposes — one is safe to hand to a client, the other very much isn't.
How the Reusable Service Catalog Speeds Up Invoicing
Why editing a rate in your service catalog never rewrites invoices you've already sent, and how the save-or-update logic actually works.
What's Actually Inside Your Account Data Export
A full breakdown of what the account data export includes, what it deliberately leaves out, and how it's generated on demand.
How Discounts Are Applied Before Tax on Your Invoices
Tax is calculated on the discounted amount, not the original subtotal — a discount reduces your tax bill too, not just the price the client pays.
How Expense Rebilling Status Works
Every logged expense carries one of three rebill statuses — unbilled, rebilled, or non-rebillable — and that field is what stops the same expense from being billed twice.