2026-08-31 / BLOG

Engineering Software for Load Shedding and Unreliable Power

Engineering Software for Load Shedding and Unreliable Power

You’re in the middle of a batch run when the lights flicker twice and the UPS kicks in. In South Africa, this isn’t a hypothetical – it’s a Tuesday. Load shedding has become a permanent design constraint for any software that runs close to the physical world. If your system falls over every time the grid hiccups, you’re not just losing uptime; you’re losing trust, data, and revenue.

For the industrial and mission-critical systems we build at Silver Stack, power instability isn’t an edge case. It’s the normal operating environment. That means resilience isn’t a feature you bolt on at the end – it’s the foundation of the architecture.

Why power failure is a software problem

Power cuts don’t just kill processes. They corrupt state, strand transactions, and leave databases with half-written records. A factory automation system that forgets which step it was on during a 5-minute outage can cause hours of downtime sorting out the mess. A logistics platform that drops orders when the server loses power mid-write creates a reconciliation nightmare.

These aren’t hardware problems; they’re design problems. The hardware did its job – it powered off. The software, however, assumed clean, uninterrupted execution. When you’re engineering software for load shedding, you have to assume the opposite: that every operation can be interrupted at any point, and that the system must recover gracefully without human intervention.

Designing for resilience: core principles

Resilience application design starts with a few non-negotiable patterns. We apply them across .NET and TypeScript systems, and they translate to any stack.

Idempotency and command persistence

Every write operation must be safe to replay. If a command is sent but the response is lost, the system needs to retry without duplicating the effect. This means designing commands with unique correlation IDs and ensuring the handler can recognise a repeat. Couple that with persisting commands before execution, and you can pick up exactly where you left off after a restart.

Graceful degradation and offline-first logic

When the lights go out, it’s often the network that goes first. Edge devices and local services need to continue operating on cached data and local state. A well-designed system will queue up writes locally and synchronise when connectivity returns. In .NET, we lean heavily on message queues and durable storage; in TypeScript/Node.js, we use patterns like event sourcing with local persistence. The key is that the system doesn’t freeze – it degrades to a known, safe fallback mode.

Circuit breakers and back-off strategies

Even when the grid is up, voltage sags and brownouts cause intermittent failures. Services that hammer a failing dependency just make things worse. Circuit breakers – whether implemented in code or via infrastructure – stop cascading failures. Exponential back-off on retries gives downstream systems time to recover. We’ve seen simple retry logic with jitter reduce outage recovery time by an order of magnitude.

Building for the grid’s unpredictability

South Africa’s load shedding schedule is more of a suggestion than a timetable. Stages change without warning, and a “2-hour slot” can stretch to 4 hours or come in 30-minute bursts. Your software can’t bank on a predictable window.

That means all state transitions must be atomic and durable. A long-running business process – say, a multi-step assembly line orchestration – needs to checkpoint its progress at every stage. If the UPS only gives you 10 minutes of runtime, you can’t afford to lose 30 minutes of work. We use the Outbox pattern heavily: any change to business state is written to a local outbox table inside the same database transaction. After power returns, a separate process picks up the outbox messages and reliably publishes them. The system never loses a committed transaction.

Testing for chaos

You can’t know if your system survives load shedding unless you test it. We embed chaos engineering into the development cycle: random process kills, network partitions, and forced power-offs on test environments. In TypeScript backends, we simulate power loss by crashing the process mid-write and verifying recovery. In .NET, we exploit the robust transaction handling to ensure that after a simulated outage, the system comes back healthy and consistent.

The payoff: trust in a volatile grid

When you’ve engineered for power failure, the operational behaviour changes. Your Ops team stops dreading Stage 6 alerts. The factory floor doesn’t grind to a halt because a controller lost its state. You don’t have to explain to customers that “the system was down due to load shedding.”

At Silver Stack, we’ve found that the same patterns that handle power cuts also handle any kind of infrastructure failure – cloud zone outages, buggy third-party APIs, or unexpected hardware faults. Resilience isn’t just about surviving load shedding; it’s about building software that behaves like a reliable industrial machine, whatever the environment throws at it.

We work with engineering teams in Cape Town and beyond to design and build systems that stay reliable when the power doesn’t. If you’re facing these challenges, we’d like to hear from you.

Talk to us

READY TO IMPLEMENT THIS?

We specialize in turning these high-impact engineering concepts into production-grade systems.

CORE SERVICESESTIMATE PROJECT
BACK TO BLOG