A subscription may be $20 per month in January, $35 from June, and $300 per year after a later plan change. If I keep only the latest amount, the record is easy to edit but difficult to trust. Changing $20 to $35 can make the earlier months look as though they also cost $35.
The safer approach is to treat billing terms as a dated timeline. When the provider's plan changes, add a new stage. When the record itself was wrong, correct the existing stage.
That distinction works in a spreadsheet, database, or dedicated cost tool. It also prevents a current edit from changing the assumptions behind an earlier profitability review.
Begin with two different questions
Before editing a subscription, ask:
- Did the subscription plan change?
- Or were the recorded terms incorrect?
If the plan changed, preserve the earlier stage and create a new one from the first expected charge under the new terms. This is a plan change.
If the plan did not change and I typed the wrong amount, cadence, or date, edit the affected stage. This is a record correction.
These actions may use the same form fields, but they should not have the same result.
A plan change says, “The old record was valid for its period, and these terms apply next.” A correction says, “This stage never represented what I intended to record.”
Making the user choose between those meanings is safer than making a generic Save guess.
Store terms in stages, not one mutable row
A useful billing stage needs at least:
| Field | Purpose |
|---|---|
| Cost ID | Keeps every stage attached to one stable subscription record |
| Effective from | Defines when this stage begins |
| Amount and currency | Describes the expected amount for this stage |
| Cadence | Records monthly or yearly recurrence |
| First expected charge | Anchors the schedule for this stage |
The next stage implicitly ends the previous one. If Stage B begins on August 15, Stage A applies only to expected occurrences before August 15. Stage B applies to occurrences on or after that date.
Consider a fictional hosting plan:
| Effective period | Amount | Cadence | Expected billing date |
|---|---|---|---|
| Jan 15–Aug 14 | $20 | Monthly | 15th |
| From Aug 15 | $100 | Monthly | 15th |
The August 15 occurrence uses $100. July 15 remains $20. There is no need to create two visible Hosting costs, and there should not be two expected occurrences on the boundary.
This is a schedule of recorded expectations. It is not a confirmation of what a bank or vendor actually charged.
Price increases and decreases are the same operation
A price increase tends to receive more attention because it raises future spend, but a decrease has the same historical problem.
For a change from $20 to $100:
- keep $20 before the effective expected charge;
- use $100 from that occurrence forward.
For a decrease from $100 to $20:
- keep $100 before the boundary;
- use $20 from the boundary forward.
The direction does not require a different data model. The record needs an old stage, a new stage, and a date that separates them.
It should not infer a prorated difference, credit, refund, or extra collection from the amount change. Those depend on the provider's actual rules and invoice. If a separate known adjustment matters to the operating record, enter that known amount separately rather than inventing it from the price difference.
Use the first new expected charge as the boundary
For most confirmed changes, the next expected charge is the clearest default effective date.
Suppose a provider announces a new price on August 3, but the subscription renews on August 15. The announcement date is useful context, yet August 15 is the date on which the new billing stage begins for the schedule.
There are two important exceptions.
First, the new terms may begin at a later expected charge. Perhaps the provider granted one more cycle at the old rate. Choose the actual first expected charge under the new terms.
Second, I may learn about or record the change late. If the new price began in June and I update the ledger in August, I can add a stage effective from the June occurrence. June onward may be recalculated, while periods before June stay intact.
Backdating a real plan change is not the same as correcting the original stage. The old terms may still have been valid until the backdated boundary.
Preserve the billing date when only the amount changes
If the subscription remains monthly on the 15th and only its price changes, the schedule should remain anchored to the 15th.
It is easy for an edit form to combine “start date,” “next charge,” and “effective date” into one ambiguous field. A price-only edit should not quietly move future occurrences.
The review should state both facts:
- the new amount begins with the selected expected charge;
- the expected billing date remains unchanged.
That small confirmation prevents a data-entry task from becoming an accidental schedule edit.
Treat a billing-date change as new terms
When a provider moves a monthly charge from the 5th to the 15th, recording only the new day can rewrite the earlier schedule. Instead, add a stage anchored by the first expected charge on the new schedule.
For example:
| Effective period | Amount | Cadence | Expected billing date |
|---|---|---|---|
| Jan 5–Sep 14 | $40 | Monthly | 5th |
| From Sep 15 | $40 | Monthly | 15th |
The amount is identical, but the terms are not. The expected occurrences before the boundary still belong to the old schedule.
Do not infer what happened between the two dates. Whether the provider shortened, extended, prorated, or otherwise adjusted a billing period requires invoice information that a simple schedule does not contain.
A cadence change needs a fresh anchor
A monthly-to-yearly change is more than replacing the word “Monthly” with “Yearly.” The new annual schedule needs a confirmed first expected charge date.
If a $25 monthly plan becomes a $240 yearly plan on October 20, create a yearly stage beginning with the October 20 expected occurrence. Earlier monthly occurrences remain monthly.
The reverse works the same way. When a yearly plan becomes monthly, record the first expected monthly charge and generate later occurrences from that anchor.
For operating analysis, decide separately how annual costs appear. You may want the full annual amount visible in its expected billing month for cash planning and a normalized monthly equivalent in a forecast. Do not let a reporting convention replace the underlying schedule.
A recurring subscription becoming a one-time purchase is usually clearer as two records: stop the recurring Cost and add the known one-time Cost. That preserves the end of one obligation and the beginning of another.
Correction should be explicit and limited
Now consider a different case: the hosting plan was always $20, but I entered $200.
Creating a new $20 stage would preserve a false $200 period. This is the right time to correct the existing record.
A correction should target one selected stage:
- correcting the initial stage affects only the period it covers;
- correcting a middle stage stops at the next stage;
- later valid stages remain in place;
- deleting a historical stage should show which period will fall back to the preceding terms.
The interface or spreadsheet should make the affected range visible before the edit is committed. “Recalculate history” is too broad a warning if the system can identify the specific stage and dates.
If two adjacent stages become completely identical after a correction, they can be merged.
Why this matters for product decisions
Cost history feeds other questions. When I calculate product contribution, I am comparing revenue with direct costs and allocated shared costs. If today's subscription price overwrites six earlier months, the apparent trend changes even though the business did not.
The method in Contribution Profit for Indie Apps depends on consistent period boundaries. The broader inventory in The Real Cost of Running Multiple Software Products also becomes more useful when annual renewals, shared tools, and changing vendor plans retain their dates.
A historical view should answer: “What terms had I recorded for this period?” A future view should answer: “What does the current schedule imply next?” One mutable amount cannot answer both after the first change.
Cost allocation needs its own effective dates as well. Changing a provider price should not silently reassign the Cost between Products. Keep the billing-terms timeline and allocation timeline separate, then resolve both for the period being reviewed.
Keep expected and actual charges separate
A billing schedule is a planning record. It can generate expected dates and amounts, support an Upcoming view, and provide a useful review point before a renewal.
It cannot prove that the charge occurred.
A provider may change tax, apply a credit, delay an invoice, reject a payment, or use terms not represented in the schedule. Reconcile actual transactions separately if that level of accuracy is required.
The same boundary applies to reminders. A reminder based on an expected charge does not discover a subscription, verify a payment, or cancel a service. Local operating-system notifications can help prompt a review, but their delivery should not be treated as guaranteed.
Keeping these distinctions visible makes a modest cost ledger more trustworthy than one that implies access to facts it does not have.
A spreadsheet version of the workflow
You can implement the model without specialized software.
Create a Costs sheet with one stable row per subscription and a Billing Terms sheet with one row per stage. Include the Cost ID, effective date, amount, currency, cadence, and first expected charge.
When a plan changes:
- Leave the earlier row unchanged.
- Add a new row with the first expected charge under the new terms.
- Sort stages by Cost ID and effective date.
- Generate or review occurrences using the stage active on each date.
- Confirm that no boundary produces a duplicate occurrence.
- Check historical totals and upcoming costs.
When the record was wrong:
- Select the incorrect stage.
- Identify the period ending at the next stage.
- Correct only that row.
- Recalculate the affected period.
- Keep later stages unless they are independently wrong.
Add a note column for the provider notice, invoice reference, or reason for the correction. The note does not replace the effective date, but it helps explain why the timeline changed.
How I use this model in MarginDeck
Disclosure: I make MarginDeck. This article describes my own work on the product.
I built this separation into MarginDeck's upcoming-cost workflow in version 1.1.1 with Start with Next Expected Charge, Choose When the Change Starts, Correct an Existing Record, and Price & Billing History. The release also added optional local reminders derived from the expected schedule. The detailed product boundaries are in MarginDeck 1.1.1: Cost Changes and Local Reminders.
My preferred review before saving any subscription edit is short:
- Did the real plan change, or was my record wrong?
- What is the first expected charge under the new terms?
- Did the amount, cadence, billing date, or more than one of them change?
- Which earlier periods should remain untouched?
- Does the future schedule now match what I intend to review?
That checklist is more important than the tool. A spreadsheet can follow it. So can a database designed around dated stages.
Disclosure: I am Junhua Jin, and I build MarginDeck. The product uses user-recorded billing details to estimate cost schedules; it does not confirm transactions with banks or subscription providers.