Unearned Revenue: Asset or Liability? Build the Answer Into an Excel Rev-Rec Schedule

A customer pays 24,000 up front for twelve months of service. The bank balance goes up by 24,000. Everything about that feels like an asset, and most answers will tell you the account is a liability without ever showing you why — or what the balance looks like three months later.

It is a liability, and the cleanest way to prove it to yourself and to an auditor is to build the schedule that unwinds it. This post gives the answer with the balance-sheet extract behind it, then builds a month-by-month deferred revenue schedule in Excel from a four-contract worked example: the register, the recognition grid, the roll-forward, the tie-out checks, the journal entry at each step, and the current/non-current split at year end.

The short answer: unearned revenue is a liability

When cash or an invoice lands before you have delivered, you have not earned anything. You have taken on an obligation to perform — deliver the service, ship the goods, or refund the money. That obligation is the liability. Under IFRS 15 and ASC 606 the formal term is a contract liability; "unearned revenue" and "deferred revenue" are the same balance under older names, and you will see all three in the wild. Presentation and disclosure detail differ between frameworks and get amended, so check the wording of the standard your accounts are prepared under rather than copying a template — and treat everything below as bookkeeping mechanics, not accounting advice on your specific contracts.

The word revenue in the account name is what trips people up. It is not revenue yet. Nothing hits the profit and loss account until you perform.

The cash is the asset; the obligation is the liability

Both things happen in the same transaction, on opposite sides of the balance sheet. The 24,000 in the bank is an asset. The 24,000 you now owe in service is a liability. They arrive together and they do not cancel: the balance sheet grows on both sides and net assets are unchanged, which is right, because you are no better off for having been paid early.

The four mirror-image accounts, in one table

Every timing difference between delivery and payment lands in one of four accounts. Learn the grid once and you never have to think about it again:

TimingAccountBalance sheet side
Customer pays or is invoiced before you deliverUnearned / deferred revenue (contract liability)Liability
You deliver before you invoice the customerAccrued or unbilled revenue (contract asset)Asset
You pay a supplier before they deliverPrepaid expenseAsset
Supplier delivers before you payAccrual / trade payableLiability

Rows one and two are the same contract seen from opposite ends of the billing cycle: bill quarterly in arrears but deliver monthly and the same customer sits in unearned revenue in month one and unbilled revenue in month three. That is the only circumstance in which a revenue-timing balance is an asset — and when it is, it is not called unearned revenue.

Where it sits on the balance sheet

Deferred revenue is presented within liabilities, split by when the obligation will be performed. An extract from our worked example at 31 December 2025:

Balance sheet extract at 31 Dec 2025
Current liabilities
Trade payables41,200.00
Accruals8,750.00
Deferred revenue — current portion54,513.81
Non-current liabilities
Deferred revenue — non-current portion15,000.00

The current portion is what you will recognise as revenue within twelve months of the reporting date; anything beyond is non-current. Plenty of small-company schedules skip the split, and it costs nothing until a contract runs longer than a year — the schedule below produces both numbers with one formula each. For the statement layout itself, see building a balance sheet in Excel.

The worked example

Four contracts, all amounts net of VAT, year end 31 December 2025:

#CustomerInvoice dateValueService startService endBasis
ANorthline Ltd01 Oct 202524,000.0001 Oct 202530 Sep 202612 months straight-line
BKarim Trading01 Nov 202536,000.0001 Nov 202531 Oct 202724 months straight-line
CVale Consulting12 Nov 20259,000.0012 Nov 202511 May 2026181 days, prorated
DAshford Group20 Dec 202512,000.0001 Jan 202631 Dec 202612 months, starts next year

Contract D is the one that catches people: invoiced in December, nothing earned in December because the service period has not started. It sits at its full 12,000 in the closing liability.

Building the schedule in Excel

Step 1 — the contract register

One row per contract, one reporting date driving the whole sheet. Put the reporting date in B1 and format it as a date. Column headings go in row 2, data from row 3 down:

ColFieldFormula (row 3)
ACustomertyped
BInvoice numbertyped
CInvoice datetyped
DContract value (net of tax)typed
EService starttyped
FService endtyped
GMonths in term=DATEDIF($E3,$F3+1,"m")
HMonthly amount=ROUND($D3/$G3,2)
IRecognised to datesee step 3
JClosing deferred balancesee step 3

DATEDIF counts whole months, and the +1 on the end date is what makes it come out right: 1 Oct 2025 to 30 Sep 2026 is one day short of twelve whole months, so DATEDIF(E3,F3,"m") returns 11. Adding a day gives 12. Get this wrong and every monthly amount on the sheet is out by roughly a twelfth.

Defer the net amount, never the gross. VAT or sales tax on an advance invoice goes to the tax control account on the invoice date — it is not yours to recognise and not part of the performance obligation. A schedule built on gross invoice values will never tie to the revenue in the profit and loss account.

Step 2 — the recognition grid

Start the monthly grid in K. In K2 type the first day of the earliest service month — 01/10/2025 — then in L2:

=EDATE(K2,1)

Fill right for as many months as your longest contract runs; 30 columns covers most subscription books. Format row 2 as mmm-yy so the headers read Oct-25, Nov-25, Dec-25. They must be real dates, not text: every formula below tests them.

The straight-line spread, in K3, filled right and down:

=IF(AND(K$2>=EOMONTH($E3,-1)+1,K$2<=$F3),ROUND($D3/$G3,2),0)

Two conditions, both anchored on the header row with K$2. EOMONTH($E3,-1)+1 returns the first day of the month containing the service start, so a contract starting 12 November still earns in the November column. K$2<=$F3 stops the spread the month the service ends — the Sep-26 header (1 Sep 2026) is on or before 30 Sep 2026, the Oct-26 header is not.

That formula has one flaw: rounding. A 25,000 contract over 12 months is 2,083.333 a month, which ROUND cuts to 2,083.33; twelve of those columns sum to 24,999.96, four cents short of the invoice, and the schedule no longer agrees with what you billed. The direction varies with the number — a 25,004 contract rounds up and overshoots instead — but either way the grid stops tying. Put the difference in the final month rather than letting it drift:

=IF(AND(K$2>=EOMONTH($E3,-1)+1,K$2<=$F3),
   IF(K$2=EOMONTH($F3,-1)+1,$D3-ROUND($D3/$G3,2)*($G3-1),ROUND($D3/$G3,2)),
   0)

EOMONTH($F3,-1)+1 is the first day of the final service month, so that column becomes the contract value less all the earlier rounded months. Eleven months at 2,083.33 and a final month of 2,083.37 sums to exactly 25,000.00.

Step 3 — recognised to date and closing balance

Both columns read the grid against the reporting date in B1. In I3:

=SUMIF($K$2:$AN$2,"<="&$B$1,$K3:$AN3)

And the closing liability in J3:

=$D3-I3

For contract A at 31 December 2025: Oct, Nov and Dec at 2,000 gives 6,000 recognised and 18,000 still deferred. For contract D, nothing recognised and the full 12,000 deferred.

One caveat on J3: it assumes the whole contract was invoiced up front, true for all four rows here. If you bill in instalments, the deferred balance is billed to date less recognised to date — add a billing schedule and swap $D3 for a SUMIF over it. When recognised exceeds billed the result goes negative, and a negative deferred revenue balance is not a liability at all: it is a contract asset (unbilled revenue) and belongs on the asset side. Never present it as a negative liability.

Step 4 — the roll-forward

Auditors ask for the continuity schedule, not the grid. Four lines per month, and every figure comes from formulas you already have:

December 2025
Opening deferred revenue, 1 Dec62,555.25
Add: amounts invoiced in the month12,000.00
Less: revenue recognised in the month(5,041.44)
Closing deferred revenue, 31 Dec69,513.81

Additions come straight from the invoice date column:

=SUMIFS($D$3:$D$500,$C$3:$C$500,">="&K$2,$C$3:$C$500,"<="&EOMONTH(K$2,0))

Recognition is the column total of the grid for that month, =SUM(K3:K500). Closing must equal the sum of column J at that date — 18,000 + 33,000 + 6,513.81 + 12,000 = 69,513.81. If it does not, one of the three inputs is wrong, and the roll-forward tells you which.

Step 5 — the tie-outs

Three checks, all of which should read zero. Put them in visible cells, not in your head:

CheckFormulaCatches
Contract spreads fully=ROUND(SUM($K3:$AN3)-$D3,2)Wrong term, truncated grid, rounding drift
Schedule agrees to the GL=ROUND(SUM($J$3:$J$500)-GL_balance,2)Entries posted outside the schedule
Recognised agrees to revenue posted=ROUND(SUM(K3:K500)-JE_amount,2)A missed or duplicated month

The first is the one that saves you: forget to extend the grid when a 36-month deal is signed and the schedule quietly under-recognises for three years.

Mid-month starts: proration by days

Contract C runs 12 November to 11 May — 181 days, not six clean months. Straight-lining it over six columns overstates November and understates May. Swap the grid formula on that row for a days-based one:

=ROUND($D3*MAX(0,MIN($F3,EOMONTH(K$2,0))-MAX($E3,K$2)+1)/($F3-$E3+1),2)

MAX($E3,K$2) is the later of the service start and the first of the month; MIN($F3,EOMONTH(K$2,0)) is the earlier of the service end and the month end. The +1 makes the count inclusive, and MAX(0,...) returns nothing for months outside the term. Denominator: total contract days.

MonthDaysRecognised
Nov-2519944.75
Dec-25311,541.44
Jan-26311,541.44
Feb-26281,392.27
Mar-26311,541.44
Apr-26301,491.71
May-2611546.96
Total1819,000.01

That total is the point: seven rounded columns come to 9,000.01, a cent more than the contract, which is why the final month needs the same plug as before — contract value less the sum of the earlier months. A cent is trivial; the same drift across two hundred contracts is a reconciling item nobody can find in March.

The journal entries, month by month

Contract A, in the order they happen:

DateEventDrCr
01 Oct 2025Invoice raisedAccounts receivable 24,000Deferred revenue 24,000
15 Oct 2025Cash receivedBank 24,000Accounts receivable 24,000
31 Oct 2025Month 1 earnedDeferred revenue 2,000Revenue 2,000
30 Nov 2025Month 2 earnedDeferred revenue 2,000Revenue 2,000
31 Dec 2025Month 3 earnedDeferred revenue 2,000Revenue 2,000

Three things worth saying out loud. The invoice entry never touches revenue — that is the whole mechanism. The cash receipt is a balance-sheet-only move between two assets and has no effect on the liability. And the recognition entry is a debit to deferred revenue, unwinding the obligation as you perform, with the credit to revenue. If cash arrives without an invoice — a deposit, a prepayment — the first entry becomes Dr Bank / Cr Deferred revenue and the receivable never appears.

In practice you post one summarised entry per month for the whole book, not one per contract: the grid's column total is the credit to revenue, split by revenue account if you need the analysis, with the schedule as the supporting workpaper. Laid out as a journal, that entry imports straight back into the accounting system — mechanics in importing journal entries into QuickBooks Online from Excel.

The current / non-current reclass

At each year end, split the closing balance by when it will be earned. Current portion, in a spare column on the register row:

=SUMIFS($K3:$AN3,$K$2:$AN$2,">"&$B$1,$K$2:$AN$2,"<="&EDATE($B$1,12))

Non-current:

=SUMIFS($K3:$AN3,$K$2:$AN$2,">"&EDATE($B$1,12))

For contract B at 31 December 2025: 18,000 falls in the twelve months to December 2026 and the remaining 15,000 in 2027 — which is where the balance sheet extract above came from. Contracts A, C and D are all current, giving 54,513.81 current and 15,000.00 non-current.

The reclass entry moves the balance across as it ages in: at the following year end, Dr Deferred revenue — non-current 15,000 / Cr Deferred revenue — current 15,000. Reverse the prior-year reclass first so you are not double-counting. Two accounts, one entry, once a year.

How HISAB 360 helps

The schedule above is fifteen minutes of work for four contracts and a full day for two hundred — most of it spent extending grids, redoing the proration for mid-month starts, and chasing the difference between the closing balance and the general ledger.

HISAB 360 is a paid Excel add-in with an AI chat panel docked inside Excel that builds this kind of schedule in the live workbook. Describe the contract register and it writes the recognition grid, the days-based proration, the recognised-to-date and closing-balance columns and the roll-forward — formulas and formatting, into the sheet you already have, rather than text to paste.

The half that usually stays manual is the posting. HISAB connects to QuickBooks Online, Xero, Zoho Books, Odoo, FreshBooks and Sage Accounting with read and write access: it pulls invoices and GL activity into sheets so the register is built from the ledger rather than a stale export, and it creates the monthly recognition journal back in the accounting system from the schedule you approved. That closes the loop the tie-out checks exist to police — the entry posted and the workpaper supporting it come from the same numbers.

Honest limits: Windows desktop Excel only (Microsoft 365 / 2016+), not Mac and not Excel on the web, and it is paid — the trial runs 15 days with 50 AI credits and no card. Every generated journal deserves the review you would give a junior's: check the term, check one contract by hand, then approve.

Where these schedules break

Frequently asked questions

Is unearned revenue an asset or a liability?

A liability. Cash received in advance creates an obligation to deliver the goods or service, and that obligation is what sits on the balance sheet — presented as a contract liability under IFRS 15 and ASC 606, split between current and non-current. The cash itself is an asset, which is why the transaction increases both sides of the balance sheet and leaves net assets unchanged.

Why is unearned revenue a liability if we already have the money?

Because having the money is not the same as having earned it. Until you perform, the customer is owed either the service or their money back, and that claim against you is the definition of a liability. The balance only becomes revenue as you deliver, month by month, which is exactly what the recognition schedule documents.

What is the journal entry for unearned revenue?

On invoice: Dr Accounts receivable, Cr Deferred revenue for the net contract value — revenue is untouched. On cash receipt: Dr Bank, Cr Accounts receivable, again with no P&L effect. Then each month as you perform: Dr Deferred revenue, Cr Revenue for that month's earned portion. If cash arrives with no invoice, the first entry is Dr Bank, Cr Deferred revenue.

How do I build a deferred revenue schedule in Excel?

One row per contract with value, service start, service end and term in months, then a grid of month columns to the right. Each cell tests whether that month falls inside the service period and returns the monthly amount if so, with the final month plugged to the contract value so rounding cannot drift. Add recognised-to-date and closing-balance columns driven by a reporting date, then a monthly roll-forward: opening plus billings less recognised equals closing.

Try HISAB 360 on your own workbook

HISAB 360 is an AI assistant inside Excel for accountants and finance teams — it writes macros, Power Query and formulas from plain English, and connects two-way to QuickBooks, Xero, Zoho Books, Odoo, FreshBooks and Sage. The 15-day trial is the full product, no card required.

Start free → See pricing