Deutschlandticket WorthIt Analysis
Some years ago I aggregated my travel costs in a post to show the savings I had because of the 9€-Ticket. Since then I tracked all my Deutschlandticket saving using a hledger virtual entries.
Tracking in hledger
The "WorthIt Sum" in table below is based on a hledger virtual entries. For example one trip, without Deutschlandticket:
2025-12-30 VVS Ticket (Stuttgart -> Schorndorf) Expenses:ÖPNV:VVS €6.80 Assets:Girokonto (worthIt:Deutschlandticket) €6.80
And one trip where I only track the usage, because it is paid via Deutschlandticket:
The value tracked in the virtual entry is negative, because it is the amount saved.
The Deutschlandticket itself in my ledger looks like this:
2025-10-01 Deutschlandticket Expenses:ÖPNV:Deutschlandticket €58 Assets:Girokonto (worthIt:Deutschlandticket) €58
To get the worthIt data from the ledger files into Python I use subprocess and call this one:
The first lines of my data:
"txnidx","date","code","description","account","amount","total" "4928","2023-05-01","","Deutschlandticket bei der SSB","(worthIt:Deutschlandticket)","€49.00","€49.00" "4970","2023-05-04","","Bahn: Stgt -> Reutlingen","(worthIt:Deutschlandticket)","€-11.00","€38.00" "4970","2023-05-04","","Bahn: Tübingen -> Herrenberg","(worthIt:Deutschlandticket)","€-6.00","€32.00" ... "5011","2023-05-30","","VVS: Office day","(worthIt:Deutschlandticket)","€-2.75","€-52.55"
The total column from the last entry of a month is the value you see in the table below (€-52.55 for 2023-05).
So the virtual entry sums per month are calculated by hledger.
Data analysis
The Python script is analysing the csv and returns a table with additional columns.
Actually a second hledger csv export is needed: the one returning all Expenses:ÖPNV:Deutschlandticket to know if I booked a Deutschlandticket that month.
For the months where I didn't buy a Deutschlandticket, the script still needs to know what it would have costed. The ticket price increased in the last years, so I have this in my Python code to track the price that month:
def get_ticket_price_for_month(year_month): if year_month >= "2026-01": return Decimal("63") elif year_month >= "2025-01": return Decimal("58") return Decimal("49")
With all this data a table is generated. The "WorthIt Sum" is exactly the virtual value at the end of the month, as described above. The "Actual Cost" is either the Deutschlandticket, or in months without one, the virtual entry. This virtual entries are always postive, because no Deutschlandticket to save with. And finally a "Not WorthIt" column. For this the actual costs need to be over the costs of the Deutschlandticket (I never had such a month, yet). Or the "WorthIt Sum" is positive, so not enough was saved to reach the costs of the Deutschlandticket. I had this 4 times in the past as you can see in the table below. As a result of the months where I didn't save enough with the Deutschlandticket I started to not have a ticket in winter months.
Year-Month |
Ticket Bought |
WorthIt Sum |
Actual Cost |
Not WorthIt |
|---|---|---|---|---|
2025-12 |
No |
€42.67 |
€42.67 |
|
2025-11 |
No |
€11.70 |
€11.70 |
|
2025-10 |
Yes |
€-5.35 |
€58.00 |
|
2025-09 |
Yes |
€-141.15 |
€58.00 |
|
2025-08 |
Yes |
€-219.87 |
€58.00 |
|
2025-07 |
Yes |
€-55.03 |
€58.00 |
|
2025-06 |
Yes |
€-234.21 |
€58.00 |
|
2025-05 |
Yes |
€-184.15 |
€58.00 |
|
2025-04 |
Yes |
€-21.47 |
€58.00 |
|
2025-03 |
Yes |
€20.01 |
€58.00 |
x |
2025-02 |
No |
€45.56 |
€45.56 |
|
2025-01 |
No |
€13.22 |
€13.22 |
|
2024-12 |
Yes |
€-3.63 |
€49.00 |
|
2024-11 |
Yes |
€-80.49 |
€49.00 |
|
2024-10 |
Yes |
€-184.65 |
€49.00 |
|
2024-09 |
Yes |
€-76.91 |
€49.00 |
|
2024-08 |
Yes |
€-31.20 |
€49.00 |
|
2024-07 |
Yes |
€-135.47 |
€49.00 |
|
2024-06 |
Yes |
€-135.79 |
€49.00 |
|
2024-05 |
Yes |
€-109.42 |
€49.00 |
|
2024-04 |
Yes |
€-143.54 |
€49.00 |
|
2024-03 |
Yes |
€-16.84 |
€49.00 |
|
2024-02 |
Yes |
€39.95 |
€49.00 |
x |
2024-01 |
Yes |
€7.86 |
€49.00 |
x |
2023-12 |
Yes |
€-51.02 |
€49.00 |
|
2023-11 |
Yes |
€9.65 |
€49.00 |
x |
2023-10 |
Yes |
€-4.88 |
€49.00 |
|
2023-09 |
Yes |
€-154.49 |
€49.00 |
|
2023-08 |
Yes |
€-158.42 |
€49.00 |
|
2023-07 |
Yes |
€-144.95 |
€49.00 |
|
2023-06 |
Yes |
€-227.04 |
€49.00 |
|
2023-05 |
Yes |
€-52.55 |
€49.00 |
I am a bit torn in not having the Deutschlandticket. On the one hand the Deutschlandticket is not worth it for me in the winter. On the other hand I am limiting myself using public transport, because I have to buy a single trip ticket or daily ticket.


