What happens when I close the lid

An idea I keep circling and have not built: your own machine as the real host, and somewhere to fall to when it goes away. This is me working through why it is harder than it looks.

There is a moment I have watched happen to other people and had happen to me. You get something running on localhost, you share it, someone on the other side of the world opens it, and it works. And the very next thought is: why can't putting this on the internet for real be exactly this easy?

It is not an idle thought. A surprising number of people never take the next step at all. They just leave the machine on. There are Telegram bots that have run for years off a desktop in someone's bedroom, personal sites served from a NUC under a monitor, internal tools that live on the founder's laptop. Not because those people don't know how to rent a server. Because renting a server is a different job, and the current setup already works.

So there are really two versions of the same wish. Move me to the cloud in one click. Or: let me stay where I am, and cover for me when I'm not there.

I find the second one more interesting, and I want to write down why — including the part where it falls apart.

The easy half is the half everyone shows you

Moving code is solved. Fly's fly launch reads your project, guesses a Dockerfile, and puts it somewhere. Kamal does the same onto a box you already own. Both are genuinely one command, and both have been for years.

If code were the obstacle, this problem would be over.

It isn't, and both of those tools are honest about where they stop. They deploy the part of your app that can be thrown away and rebuilt. Everything that has to survive that — the database, the uploads, the sessions — is left to you, with a link to a managed Postgres and best wishes.

Nobody hesitates because of the code. They hesitate because of the data.

And the hesitation is rational. Your SQLite file has the actual thing in it. Moving it means picking a moment, taking it down, copying it up, and hoping nothing was in flight. Doing that once, for a real launch, is fine. Doing it because you closed your laptop is not a thing anyone would agree to.

Someone already built the shape, twice

When I went looking, I found that both halves of this exist. Just never in the same product.

The availability half has been shipping since 2010 and I'd bet most people reading this have used it without noticing. Cloudflare's Always Online keeps serving your site when your origin is dead, out of a Wayback Machine snapshot. It is read-only, it is stale, and it is enormously better than a connection error. The idea that a dead origin should degrade rather than disappear is not new or controversial.

The data half got its answer more recently, and the answer is SQLite. Litestream streams a SQLite file's write-ahead log to object storage continuously, so the remote copy is seconds behind and restoring is just a file. LiteFS goes further and intercepts at the filesystem layer to get real replicas. Turso's embedded replicas put a live local SQLite file next to your app that syncs from a remote primary — reads are local and instant, writes go to the primary.

The pattern that keeps recurring is one primary that takes writes, and replicas everywhere else that take reads. Every version of this that works looks like that. Every version that doesn't, doesn't.

What nobody has done is join the two: run on the machine you already have, and have somewhere real to fall to.

The question I cannot answer for you

Here is the wall, and I want to be precise about it, because it is not an engineering problem I could solve with more effort.

Say your laptop is the primary. You close the lid. The cloud copy takes over and starts accepting writes — a form submission, a bot message, an order. An hour later you open the laptop.

Whose data is correct?

There is no automatic answer. Not a hard one — an absent one. Both sides are legitimately newer than the last point they agreed on. You can merge them if your data has a merge rule, and almost no ordinary app's data does. Every system that has claimed to solve this in general has either become a research project or quietly pushed the decision back onto the developer under a nicer name.

So the honest move is not to solve split brain. It is to make it structurally impossible: never have two writers.

Which leaves two designs, and only one of them is the fun one

You can put the primary in the cloud and make the laptop a replica. Close the lid, nothing happens, because the cloud was serving all along. This works, it's what Turso's model is for, and it is also — I notice — not the thing I was excited about. If the cloud is where the truth lives, I've just bought hosting with extra steps.

Or you keep the primary on your machine and let the cloud be a read-only mirror. Close the lid, and the site stays up: pages load, the archive is browsable, the reader on the other side of the world sees something real. Writes politely say the owner is offline, back shortly.

That second one is worse on paper and better in spirit. Nothing about it is ambiguous. There is exactly one writer, ever, and it's you. And it matches what the people leaving their machines on already believe: this is my server, and the internet copy is a courtesy.

Then I noticed the version that needs no database at all

This is the part that made me stop and reconsider how much I'd been planning.

Piperace already knows the exact moment your machine goes away — that is not a feature, it's just what a tunnel is. And it already puts something in front of visitors when that happens: two layers of fallback page, one at the tunnel server and one at the edge, both branded, both auto-refreshing, both saying some version of reconnecting…

The plumbing for "the origin is gone" is built. What it does with that moment is show a spinner.

The first useful version of this idea is not a hosting product. It's changing what the spinner does.

Keep the last good response for pages that were working, and when the tunnel dies, serve that instead of the spinner, with an honest banner saying it's a snapshot and when it was taken. No deploy. No replication. No database. For a portfolio, a landing page, documentation, a demo you shared in a thread — that is already "my laptop is the host, and it doesn't matter that it's asleep."

It is a much smaller idea than the one I started with, and I'm fairly sure it delivers most of what the original was actually for. I don't fully trust that conclusion yet, which is part of why I'm writing it down.

Where the one button stops being one button

The rest of the idea — the part with the database in it — I keep poking at, and it keeps growing edges:

Which suggests that if there's ever a version with data in it, it has to be aggressively narrow — one process, one SQLite file, read-only when you're away — and say so on the label instead of discovering the limits one support email at a time.

I don't know if I'm going to build this

What I'm reasonably confident about: the wish is real, the code half is a solved problem, the data half has exactly one workable shape, and split brain is a product decision wearing an engineering costume.

What I'm not confident about: whether the small version — the one that just stops showing a spinner — is a genuinely good idea or merely the one I can see how to build. Those feel identical from the inside and I've been wrong about the difference before.

If you've run something real off a machine at home, I'd like to know what actually went wrong. Not the theory. The night it broke.

Nothing here is a roadmap or an announcement. It's a problem I've been turning over, published at the stage where I'm still arguing with myself about it. If it ships it will look different from this, and if it doesn't ship, the reasoning is at least written down.

← Back to blog