This post was written as part of my entry to the AWS x Vercel Hackathon. #H0Hackathon
I have a bit of a home automation problem. Not in a “my lights turn off automatically” way. More in a “I’ve built several apps to help me manage my own energy usage around the grid” way. Shifting EV charging, managing battery storage, trying not to consume electricity at the exact moment everyone else in the country is doing the same thing. I find it genuinely interesting.
Octopus Energy is one of the very few suppliers that has cracked this properly. Their Agile tariff is a good example: real-time pricing that incentivises consumers to shift load based on actual grid conditions. It works because they have the infrastructure, the data pipelines, and frankly the appetite to build it.
Most energy suppliers don’t have any of those things.
They have billing systems. Maybe an app. A general awareness that smart grid stuff is coming. And not much else. The engineering lift to run demand response campaigns properly (triggering consumers, rewarding them, tracking outcomes) is significant, and most suppliers are not going to prioritise it.
So I started wondering: what if there was a drop-in platform that just handled all of this for them?
I chatted with a couple of people from the industry. They didn’t laugh. They actually thought it was worth exploring. So here we are.

What GridShift Actually Does
GridShift is a multi-tenant platform that lets energy suppliers run energy demand response campaigns without building any of the underlying infrastructure themselves.
A supplier signs up, goes through a three-step onboarding wizard (branding, tariff, campaign), and they’re live. Their consumers get a white-labelled app showing their live grid energy demand data, their opted-in devices, their points balance, and any active events.
When the grid is under stress and a campaign fires, consumers get a push notification. Their smart devices (EV charger, battery storage, heat pump, whatever) are flagged as participating. Points get awarded based on their device’s rated power and how long the event runs. Those points can be redeemed for bill credit, smart devices, or other rewards the supplier sets up.
The whole thing is branded per supplier. Same codebase, completely different look and feel. More on that in a minute.
The Tech (Quick Version)
I’ll do a proper technical write-up separately, but the short version:
- Amazon Aurora PostgreSQL Serverless v2 as the database. The variable load profile of a demand response platform (quiet most of the time, chaos when a grid event fires) is exactly what serverless scaling is for.
- PgCache as a read proxy in front of Aurora. More on this below because it’s interesting.
- Next.js on Vercel for the frontend, built with v0.
- Row-Level Security keeping every supplier’s data completely isolated at the database layer.
- Real grid energy demand data from national operators: NESO for GB, SMARD for Germany, EIA for the US, Fingrid for the Nordics, OpenElectricity for Australia.

The Supplier Admin
Each supplier gets an admin portal where they can manage campaigns, configure tariffs, update their branding, and track onboarding progress.

The branding config is stored in Aurora and applied at runtime, so when a supplier updates their colours and hits Deploy, every consumer on their tenant sees the change immediately.
Tariff import is one of the things I’m quite pleased with. Suppliers paste in their billing API endpoint and GridShift fetches the data and automatically detects the rate structure, including base rate, peak rate, and off-peak rate. No mapping config needed.

The Consumer App
The consumer side is where the multi-tenant theming really shows. The same codebase renders completely differently depending on which supplier the consumer belongs to.



The grid demand chart on the dashboard is live data from the relevant national grid operator for that supplier’s geography. Acme Energy consumers see UK demand from NESO. GreenVolt consumers see German demand from SMARD. The bars are colour-coded: green for low demand, amber for high, red for peak.


The v0 Bit
I’ll be honest: I nearly skipped v0 entirely. I’d assumed the Vercel part of the hackathon was mainly about hosting, which I’ve done plenty of, and I’d already built a basic frontend before I properly engaged with it.
When I actually sat down with v0, I gave it my existing basic design and asked for two things: make it nicer, and make it re-skinnable on the fly based on a supplier’s branding config. It worked first try. The multi-tenant theming that I’d been quietly dreading as a fiddly half-day job took one iteration.
I came in sceptical. I came out a convert, with the caveat that you need a solid API contract and a clear sense of the user journey before v0 can do much for you. Give it those things and it moves fast.
PgCache: Worth the Hype?
I’d been following PgCache for a while before this hackathon and wanted to test it properly. The pitch is simple: it’s a wire-compatible Postgres proxy that caches your hot reads and keeps that cache current via CDC, so you get the performance benefit of a read replica without duplicating your entire database.
For GridShift, the hot read set is pretty small: event status, device opt-in state, points balance. Running a full Aurora read replica continuously to serve those reads would be wasteful. PgCache caches exactly what gets read most, and nothing else.

The complication I ran into: PgCache bypasses Row-Level Security, because it operates using a dedicated read-only database user. In a multi-tenant setup where RLS is doing the tenant isolation work, that’s a constraint you need to design around from day one. I got there, but it took longer than expected. Worth knowing before you commit to the combination.
Overall verdict: yes, it’s worth it, with that caveat factored in upfront.
The Simulation
Because this is a hackathon and not a live grid, I built a /demo/simulate endpoint that fires the full demand event lifecycle in a single API call. It creates a campaign, opts in all devices, awards points, sends push notifications, and marks the campaign complete.
The consumer app picks up the state changes in real time. Points balance updates, the event status card appears, the push notification arrives. It’s the full end-to-end flow without needing to wait for an actual grid stress event.
What I’d Do Differently
One of my biggest problems is knowing when to stop! A hackathon forces the issue. A few honest notes on what I’d change:
The PgCache EC2 instance is a single point of failure. In production, you’d want a second instance behind a load balancer with health checks failing back to Aurora. The fallback logic is in the app; the infrastructure redundancy isn’t there yet.
The points balance query does a full table scan per consumer. Fine now, not fine at scale. A trigger-maintained running total is the production fix.
And I’d make the multi-tenancy isolation decision even earlier next time. The RLS model is the right pragmatic call, but it shapes almost every other decision that follows: credentials, caching, migration tooling. It needs to be first, not retrofitted.
Have a Play
The demo is live at vercel-hackathon-zeta.vercel.app. Log in as any of the demo consumers or suppliers and have a look around. Passwords are in the readme. The code is on GitHub at github.com/kandmgawron/vercel-hackathon.
If you’re working in grid flexibility or energy demand-side response, or you’re just interested in the architecture, get in touch. I’d love to hear from anyone actually building in this space.
![]()