Two winters on solar and a battery in Joburg: the real numbers, and what I'd do differently
Eskom trauma is permanent. So is the battery bill. What it cost, what it powers, and the one design rule it taught me at work.
Contents
Howzit. A few people asked after my comment in the homelab thread, so here's the long version. Ja, it's long. Make tea.
Context for the non-South Africans: for a few years "load shedding" was just life here. Scheduled power cuts, two to four hours at a time, sometimes three times a day, announced by stage (stage 2, stage 4, stage 6 when things were really bad). You planned your cooking, your gym, your deploys and your kid's bath around the EskomSePush app. The lights have been mostly on lately and I still don't trust it for one second. Nobody I know has taken their inverter out.
What we installed
Bought in two goes, because who has that money all at once.
- Round 1 (early 2023, peak panic): a 5 kW hybrid inverter and one 5.12 kWh LiFePO4 battery. Installed, with a proper COC (certificate of compliance), roughly R58,000. Prices were silly then, everyone was buying.
- Round 2 (2024): six 450 W panels on the north-facing roof (2.7 kWp) plus a second 5.12 kWh battery. Roughly R46,000 installed. Panels had come down a lot by then.
So about R104,000 all in, a bit under US$6,000 depending on what the rand is doing this week. Not small money. We financed half of round 2 through a bank solar loan.
What it actually does
On a clear winter day the panels make around 10 to 12 kWh, summer more like 13 to 15 (afternoon storms eat some of it). Our house uses about 14 kWh a day on average, more in winter because of a heater in my daughter's room. Over a year the solar covers somewhere between 55 and 60% of what we use. The geyser is still on the grid with a timer, because heating water off batteries is silly.
With 10 kWh of storage (you don't run LiFePO4 to zero, so call it 8 usable) the essentials ride through even a long cut: fibre ONT and router, the fridge, lights, the TV, two laptops, and the homelab. The oven and the kettle are on a separate non-essential circuit, which was the best R3,000 of the whole project, because it means nobody can boil a kettle at 7 pm and drain my battery.
The homelab bit
The homelab is small on purpose: a mini PC running Proxmox (about 15 W idle), a two-bay NAS (about 20 W with disks spinning), the router and a switch. All in it idles around 50 W, so roughly 1.2 kWh a day. I used to run an old tower server that idled at 110 W and I could literally watch it eat the battery on stage 6 evenings. Selling it was the single biggest "upgrade" I made.
The ONT and router are also on a little 12 V DC mini UPS (one of those R700 ones with barrel plugs) as a second layer, because inverters do occasionally trip, and when you're on call for payments you don't want the Wi-Fi to blink while the inverter thinks about its life.
What I'd do differently
- Panels first, not battery first. We did it backwards because of panic. A battery with no panels just charges from Eskom between cuts, which helps you survive but saves you nothing.
- Size the essential circuit honestly. Walk around the house and decide what really needs to stay on. The answer is less than you think.
- Get the installer to show you the monitoring app before they leave. I spent a month not knowing the battery was set to stop discharging at 50% (installer default "for longevity"), which halved what I'd paid for.
- Kill your idle watts before you buy kWh. Every 10 W of always-on is 240 Wh a day. That old server cost me more battery than my fridge.
The work bit
This is the part I actually wanted to write. Living through load shedding changed how I design systems. I build payment services in Go, and in my head the default assumption is now: the lights go out mid-transaction. Not "might". Will. Your pod dies, your node gets drained, the card network times out, your customer's phone dies in a taxi on the N1. So:
- Every request that moves money carries an idempotency key from the client, and the server stores the key with the result before replying. A retry gets the same answer, not a second debit.
- State changes go through an outbox table in the same Postgres transaction as the business write, and a separate worker publishes to Kafka. If we die between the commit and the publish, the worker picks it up after restart.
- Anything that talks to a third party is a state machine with a "we don't know" state (
PENDING_UNKNOWNin our code) and a reconciler that goes and asks. Timeouts are not failures. They're questions.
None of that is new. It's in every distributed systems book. But it lands differently when you've lived it with a cranky toddler and a fridge full of meat at stage 6.
Shame, this got long. Questions welcome, especially if you're in SA and trying to decide on sizing.
Written by
Lindiwe Mokoena
Senior backend dev, fintech, Joburg. Go, Kafka, AWS. Homelab runs on an inverter because Eskom trauma is permanent. Mom of one, owner of zero free time.
Get the best of Dynamo Geeks weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment