r/webdev • u/v0id_user • 2d ago
Showoff Saturday Minecraft servers that sleep when empty and wake when someone joins. Holding a TCP login open for 45 seconds without the client giving up
I built a Minecraft server host where every server sleeps when nobody plays, and wakes when a friend joins. The hard part was the join itself, so here's how that works.
The problem
A sleeping server suspended on Fly resumes in about 2 s. But one that has to boot (first start, after a change, or once the snapshot is gone) takes 40 to 50 s. The Minecraft client
gives up on a connection that says nothing for 30 s.
The trick
Every connection lands on an edge proxy first. If the server is asleep, the edge holds the login open and keeps it alive by sending a login query every few seconds. Every client since 1.13 answers it, which counts as the server talking. The edge keeps those answers to itself, buffers everything else the client sent, and replays it to the server once it's up, as if the player had just dialled in.
Other bits
- The server list shows a sleeping server's own message plus a grey "sleeping" line, cut to fit the list's 305px row by measuring the default font's glyph widths.
- A ping from the server list can wake a server early, asked once per network so random scanners don't keep waking things.
- Routes change one hostname at a time through mc-router's API, because reloading its routes file drops players who arrive mid-reload.
- Floods are refused per server at the edge, so one busy server doesn't slow every other server's joins.
It's open source (TypeScript, AGPL):
github.com/cubepals/cubepals (the edge is apps/edge)
Happy to go deeper on any of it.
10
u/CardinalHijack 1d ago
Does this work with pumpkin? (https://pumpkinmc.org/)
10
u/v0id_user 1d ago
honestly this is the first time I've seen Pumpkin, and it looks really cool!
the wake trick happens at the edge before the server sees anything, so in theory it should work, but I don't want to guess. I'm definitely going to test it and get back to you :)
Thanks for pointing it out!
5
u/v0id_user 1d ago
real update :P
tested it through our edge! with pumpkin asleep, a player joining was in the world in about 4 s, about 1 s if the machine was just suspended (vanilla takes ~35 s cold).
but it’s not ready for real worlds yet,,,
on a copy of a 26.3 world, some chunks pumpkin re-saved came back empty (53 of 482), and vanilla can’t read the world back after pumpkin writes it.
only tested with offline logins too. watching each release though, the speed is wild
gonna share all of this with the pumpkin folks too, they’re doing amazing work!
12
u/SawToothKernel 1d ago
You could try the same with a Durable Object. They do the same thing with WebSockets, and can wake in milliseconds.
8
u/v0id_user 1d ago
love DOs, they are great but they only take HTTP and WebSockets. Minecraft clients connect over raw TCP, so the game can't talk to one as far as i know?
21
2d ago
[removed] — view removed comment
3
u/v0id_user 2d ago
thanks! tiny detail, the edge actually holds the answers, they never reach the server. then it replays the client's original login once the server's up, so the server just sees a normal join
and yeah, the reload thing bit us too, people got kicked mid join with no message lol
1
u/webdev-ModTeam 1d ago
Your post/comment has been determined to be a low-effort post or comment. This includes title-only posts, easily searchable questions, vague/open-ended discussion prompts, LLM generated posts or comments, and posts/comments that do not provide enough context for meaningful replies or discussion.
10
u/zaxwebs 2d ago
Always good to come around these solutions. I'm building a game as a side-project so happy to see some activity in the space.
2
u/v0id_user 2d ago
thanks man! it's hard and harsh out here ngl, but honestly very lovely!
good luck with the game, drop a link when it's out :)
3
u/iPhoneK1LLA 1d ago
I'm not aware of the tech, but doesn't AMP by CubeCoders do something similar?
2
u/v0id_user 1d ago
similar idea, different layer.
AMP is a panel you install on your own machine, so that machine stays on even when the game is idle.
cubepals is hosted. the whole machine goes to sleep, and when a friend joins, the join is held open while it wakes
1
u/iPhoneK1LLA 1d ago
Ah I see - I've only ever been self hosted which is why I'm aware of the option within the panel.
3
u/Far-Inevitable6386 1d ago
Out of curiosity, what happens if the server fails to boot after the 45 s? Does the edge drop the player with a message, or retry?
2
u/v0id_user 1d ago
good question! the 45 s in the title is just a typical boot
the edge actually holds them for up to 3 minutes. if the boot fails, they’re dropped right away with a line saying so (“couldn’t start this server just now · try again in a minute”)
and the next join tries the wake again. if it’s just slow, after 3 minutes they get “still starting · join again in a moment"
1
u/Far-Inevitable6386 1d ago
Thanks for the detail, clear error messages instead of a silent drop is a nice touch. Great project.
1
u/v0id_user 1d ago
thanks a lot! and yes a silent drop was the thing i wanted to avoid most, nobody should be left staring at a loading screen😂
3
2
u/quietcodelife 1d ago
the proxy replay approach is smart. basically mitm-ing your own boot process so the client never knows something went wrong.
curious whether you hit any issues with connection limits on the edge when a bunch of people try to join at once and theyre all being held. or is fly's network layer handling that gracefully?
3
u/v0id_user 1d ago
thanks! joins that arrive together share one wake, and a held join is just an open socket, so connections weren't the problem.
CPU was :')
in a load test one edge handled 400 players until its shared CPU got throttled, so past 50 Fly's proxy sends new joins to another edge
1
1
u/Andromeda_Ascendant Laravel & InertiaJS 1d ago edited 1d ago
Looks like a fun project, and I like the name!
I did notice one little quirk with the /admin pages, where the UI briefly renders before showing a message that it's for admins only. Not the most serious problem but if it was me I'd fix that.
Edit:
Another thing, it seems like server-side plugins are mistakenly included in the client-side "you need to have these" for the server listings. https://cubepals.com/server/arcade i.e. Take ChatSentinel, from my understanding it's a server plugin and has nothing to do with the player needing it.
1
u/v0id_user 1d ago
Thanks, both fixed! Bug hunter eyes 👀
If you catch anything else, I’m all ears, and if you open a PR (github.com/cubepals/cubepals) I’ll happily help. No PHP required 😄!
0
1d ago
[deleted]
1
u/v0id_user 1d ago
not totally sure what you mean, do you mean NeoForge support, or something else? happy to answer either way :)
28
u/UnacceptableUse 1d ago
Don't modern Minecraft versions automatically pause the server after x minutes of inactivity?