Documentation is sparse, or not even available? The API docs don’t tell you much about the service itself, and a Google search for docs returns an inaccessible website as the first result (https://docs.sprites.dev). Blog posts and forum threads and Claude skills shouldn’t be a substitute.
The snappiness of the sprites is very cool and I can definitely see it integrating into future Claude Code workflows. But the lack of a base container images means you’re still doing setup work on the sprite before you can begin development. I understand the philosophy is that sandboxes should be persistent, but Claude Code sessions also work better when isolated from each other, so it’d be nice to have some precepts to get a workspace setup quickly (given agentic coding is clearly a target).
I also found the CLI unintuitive but maybe that was just me!
So very cool idea but left with the impression that the Fly.io team’s should have spent a couple weeks on polish before shipping.
I've been needling Kurt for several months now that if we wait until it's polished enough that we don't see comments like this, we're doing it wrong.
I just want an easier way to connect to and launch sprites from my phone.
any ideas there?
Is that what you guys are thinking of? I get that Sprites are a new primitive, but I feel confused as hell about what exactly I'd want to do with it.
tpmjs is a registry of ai sdk npm packages (i created them for sprites), which you can add to personal collections, we automatically server your collections as mcp servers if you want.
Creating sprites in an example chat bot -> https://imgur.com/a/ETNxR1o
Creating sprites in claude desktop -> https://imgur.com/myC0U28
Listing out my sprites in claude desktop -> https://imgur.com/rgBU0jm
---
You can view the collection of tools here -> https://tpmjs.com/ajax/collections/sprites (fork it to use it yourself)
I'm looking into exe.dev and sprites.dev to build out extra features into tpmjs, agent sandboxes make a lot of sense.
Also I like a lot of what you get built-in with Fly machines(ex:Grafana). So I am curious how this would fit in my workflow. Maybe Sprites for rapid development and toy projects, and move to a Fly machine when I need something a little more beefy?
Looking forward to checking this out.
I believe currently the sprites CLI is using websockets to handle the connection, and the external proxy when you make a sprite public doesn’t handle websockets correctly?
Does that sound right?
Frustrating that the best solution is still, “well, if that’s important to you, then set that up in your home lab or rent some extra (pet) VMs in the cloud.”
Of course you can do similar with a VPS, but this makes it very easy (and cheap!) to spin up an entire new machine with a public url and HTTPS whenever you want to.
I realize this is all very fresh, but still wondering…
Tried with xterm, tilix and ghostty, all of which support the title setter escape sequence locally. For some reason, these get messed up (smells like edge case with escaping) and the result looks like this:
$ sprite c ": history-search-backward'
\]\u@\h\[\]:\[\]\w\[\]\$ ' ": history-search-forward'sprite@sprite:~$
"sprite@sprite:~$
I'm guessing y'all use Zsh because that works flawlessly :)While looking into giving fly another shot as a cloud provider even though I think it's still pretty much a commodity for me, I found an issue in Google: I searched for "fly.io sao paolo" and the title of the first result on fly.io is "Regiones · Fly Docs", translated from english to Spanish. While I find the translation in titles on Google annoying, I haven't often seen the characters messed up like this. I reproduced this in Incognito at this URL: https://www.google.com/search?hl=es&q=fly.io%20sao%20paolo
It neatly did so and "registered" it as a sprite service. Then I exited my session, waiting for the sprite to go idle, but I don't think it ever does.. Still have it active. Don't know how to idle it.
Can't tell for sure if this means I'm losing credits as there is no billing usage shown anywhere.
Also waiting for the moment where I can launch a sprite from another's checkpoint.
The Fly Machines orchestrator goes through some trouble to keep the source of truth for each VM decentralized, owned by the physical it runs on. But there's still global state --- apps, organizations, services. That stuff is all on Postgres. Postgres keeps up with it just fine but I'd be lying if I didn't say we're always looking out the corner of our eyes on metrics.
The global state for Sprites is on object storage. Each organization gets a separate SQLite database, and that database is synchronized to object storage with Litestream.io (Lightstream is load bearing in a bunch of places here; solid as a rock for us).
I think people really still sleep on the "multiple SQLite database" backing store design.
Incredible (truly, incredible, world-class) engineers that somehow lack that final 10% of polish/naming/documentation that makes things...well, seriously usable.
I remember last time I tried them the bizarre hoops/documentation around database creation. I _think_ they solved that but I remember at the time it felt almost like I was getting looked down upon as a user. Ugh, you need clarity? how amateurish!
What did the bracket in the slack channel determine was “Chicago’s best sandwich”? Or the top three, even? I’m always looking for new sandwiches.
Off the top of my head, I might nominate,
- the pork tenderloin at JT’s
- the Big L from Fontano’s (hot take, I know; it might go to Graziano’s if they hinge-cut the bread, but not doing so is a fatal flaw to me)
- the Cambodian fried chicken sandwich that’s occasionally available at Hermosa
- honorable mention: the comically oversized chicken torta at Migos
(Edit: I inexcusably transposed Bari and Fontano’s; the nomination is intended for Fontano’s)
>Now, today, under the hood, Sprites are still Fly Machines. But they all run from a standard container.
So its basically a faster VM?
What are some use cases for this that benefit from the faster boot time?
I ended up using it (and enjoying yolo mode!) but then my sprites weren't pausing and i was worried about spending too much so i deleted them.
Faster create times. Sprites create (including booting up) in a second or two, per TFA.
One usecase for Sprites I see are disposable dev boxes (like for rapid prototyping with Coding Agents).
Pull from sprite to local: sprite exec -s my-sprite sh -c "tar -czf - /home/sprite/<my_dir>" | tar -xzf - -C ./
Push from local to sprite: COPYFILE_DISABLE=1 tar -czf - <my_dir> | sprite exec -s my-sprite sh -c "tar -xzf - -C /home/sprite/"
https://fly.io/blog/code-and-let-live/
Thomas characterizes this as “believ[ing] that the future belongs to malleable, personalized apps”, which I think describes the use case perfectly. As a “barefoot developer” (to borrow another localfirst term, thanks Maggie Appleton), does every app really need more than a persistent home and an URL?
And so to your question “is the idea that these things can also/should run production workloads”, I believe “can” is right - but suspect that supporting “should” is on Fly’s roadmap.
However, I do think it'll unlock "globally available" apps as a first class citizen moving forward. If Uber were made today, I suspect it'd follow the 1 DB per user and be deployed really close to the edge with providers like Fly.io, Koyeb, or Cloudflare.
Yes.
They won't horizontally scale. They're pretty good for hosting my side projects! Not good for, eg, hosting the API that orchestrates Sprites.
/fs/read?path=X | GET | Read file (supports Range headers)
/fs/write?path=X | PUT | Write file (body = raw bytes)
/fs/list?path=X | GET | List directory
/fs/delete?path=X | DELETE/POST | Delete files/dirs
/fs/rename | POST | Rename/move
/fs/copy | POST | Copy files/dirs
/fs/chmod | POST | Change permissions
/fs/chown | POST | Change ownership
/fs/watch | GET (WebSock) | Watch for filesystem changes
It'll get CLI support very soon.But I've just been using magic-wormhole for this.
Low and behold, yet another AI product selling advertisement + veiled promotion on HN.
It's almost as if the guidelines don't matter anymore. From [0].
'Please don't use HN primarily for promotion. It's ok to post your own stuff part of the time, but the primary use of the site should be for curiosity.'
Nhu Lan's Banh Mi #1 and JPG's Muffaletta are the top 2 current noms, but I think the Tempesta B. Franklin is a sleeper, and the Phodega Viet Dip has a cheering section and I haven't tried it yet. The joy of doing an actual bracket is that it'll involve people doing field trips to have their first Mr. D's Pork Shish-Ka-Bob sandwich, or the Alpine Combo.
It's a 16 sandwich tournament and we're at like 26 nominations right now so it'll be interesting to see what happens.
On the other hand, if I took the sandwich bracket app and made it a generic "run a bracket" app and that app (inexplicably) got popular, I'd need to move it to a Fly Machine setup.
and you should be good
Supposedly they auto-stop when inactive.
But I've tried multiple times and they don't stop, and it's not just Docker that prevents them from stopping.
I created a new sprite and installed ffmpeg. Then exited. Next day I run `sprite ls` and it's been running continuously for 23 hours.
No way to tell if I'm being billed for it or not.
And the per-hour pricing is extremely expensive.
So for now it's `sprite destroy -s spritename`.
Maybe I'll check it out again in a few months after the fly team has iterated on this a few times.
OrgTracker.with_repo(org_id, fn ->
repo.all(from sprite in "sprites", select: ...)
end)That will find or place an Elixir process on the cluster and rpc the target node with our code. Placements can be sticky so they pin to a machine so we don't have to suck down the db every start, but we also balance out the load and handle failover of durable processes automatically. Combined with litestream, the result is distributed sqlite with failover while treating it essentially like a locally reachable sqlite db. Yes there is the speed of light to contend with, but by sending the execution across the wire rather than individual queries, we only ever pay a single hop to reach the process/sqlite.
npm install hasn't bothered me, but I know of people with massive npm issues that would like faster first installs. Fortunately, it's incrementally quicker after that.
The storage performs pretty well for running claude + my dev. It'll improve immensely in the next few months, though. We should be able to get near native NVMe speeds for the working storage set on reads/writes/flush/fua.
I tried several things and this is going to be the next one.
I’d love to see a post of some kind when it’s all settled; you’re doing the lord’s work here.
Hm. The sprites.dev webpage goes,
Sprite is a hardware-isolated execution environment ... Sprites execute code in Firecracker VMs. Even we have a hard time seeing what they're doing.
Any plans for Fly.io to support CCA / TDX / SEV-SNP?I'm really jazzed about this particular product as a product (I just really enjoy using it), but the post is mostly about how we built it, and deliberately not much about how best to use it.
(Or in other words, a graphical object on screen that is not present in a framebuffer of any kind.)
* They're servicing an incoming HTTP request.
* You're interacting with a console.
They're hair-trigger inactive otherwise. They don't bill CPU unless they're active. The idea is that there isn't really any uncertainty about when it's running; when you stop interacting with it it stops metering.
This is a new shape for a cloud computing thingy and there'll be snags this week with it, but we don't make our money by billing people for stuff they don't want. We've always gone out of our way not to nickel-and-dime casual users and we're trying hard to find new ways to lean into that here.
(Destroying a Sprite you're done with is a perfectly reasonable move; they're disposable.)
1. A timeout after the last console session is exited 2. Force idle using the CLI
Are you using libluster or Distributed Erlang to reach the clusters? Or just simple networking over the Fly network.
> That will find or place an Elixir process on the cluster and rpc the target node with our code.
Is this similar to what you did with Flame? Or just a refinement of that idea.
https://www.merriam-webster.com/dictionary/sprite
I personally associate the term Shakespeare's The Tempest: https://en.wikipedia.org/wiki/Ariel_(The_Tempest)
They are advocated as Linux machines. How about daemons then, or cron jobs? What semantics can we expect from them?
Can't find any place in CLI or web UI to see how many minutes are charged for CPU, memory, storage.
$ sprite ls
Sprites in organization <redacted>:
┌────┬───────┬────────┐
│NAME│STATUS │CREATED │
├────┼───────┼────────┤
│duh │running│ 23h ago│
└────┴───────┴────────┘
Total: 1 sprite(s)I love the idea and most of the execution, I've really enjoyed getting my first sprite configured just the way I want it. It just needs the idling feature to work as advertised before I think I can use it as cost-effectively as it promises.
$ sprite version
sprite version v0.0.1-rc30
$ sprite create quk
Error creating sprite: failed to create sprite: Post "https://api.sprites.dev/v1/sprites": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
But despite the error, the sprite was apparently created, and it runs continuously. $ sprite ls
Sprites in organization <redacted>:
┌────┬───────┬────────┐
│NAME│STATUS │CREATED │
├────┼───────┼────────┤
│quk │running│14m ago │
└────┴───────┴────────┘
Total: 1 sprite(s)
Image by Annie Ruygt
We’re Fly.io, and this is the place in the post where we’d normally tell you that our job is to take your containers and run them on our own hardware all around the world. But last week, we launched Sprites, and they don’t work that way at all. Sprites are something new: Docker without Docker without Docker. This post is about how they work.
Replacement-level homeowners buy boxes of pens and stick them in “the pen drawer”. What the elites know: you have to think adversarially about pens. “The purpose of a system is what it does”; a household’s is to uniformly distribute pens. Months from now, the drawer will be empty, no matter how many pens you stockpile. Instead, scatter pens every place you could possibly think to look for one — drawers, ledges, desks. Any time anybody needs a pen, several are at hand, in exactly the first place they look.
This is the best way I’ve found to articulate the idea of Sprites, the platform we just launched at Fly.io. Sprites are ball-point disposable computers. Whatever mark you mean to make, we’ve rigged it so you’re never more than a second or two away from having a Sprite to do it with.
Sprites are Linux virtual machines. You get root. They create in just a second or two: so fast, the experience of creating and shelling into one is identical to SSH'ing into a machine that already exists. Sprites all have a 100GB durable root filesystem. They put themselves to sleep automatically when inactive, and cost practically nothing while asleep.
As a result, I barely feel the need to name my Sprites. Sometimes I’ll just type sprite create dkjsdjk and start some task. People at Fly.io who use Sprites have dozens hanging around.
There aren’t yet many things in cloud computing that have the exact shape Sprites do:
This is a post about how we managed to get this working. We created a new orchestration stack that undoes some of the core decisions we made for Fly Machines, our flagship product. Turns out, these new decisions make Sprites drastically easier for us to scale and manage. We’re pretty psyched.
Lucky for me, there happen to be three big decisions we made that get you 90% of the way from Fly Machines to Sprites, which makes this an easy post to write. So, without further ado:
This is the easiest decision to explain.
Fly Machines are approximately OCI containers repackaged as KVM micro-VMs. They have the ergonomics of Docker but the isolation and security of an EC2 instance. We love them very much and they’re clearly the wrong basis for a ball-point disposable cloud computer.
The “one weird trick” of Fly Machines is that they start and stop instantly, fast enough that they can wake in time to handle an incoming HTTP request. But they can only do that if you’ve already created them. You have to preallocate. Creating a Fly Machine can take over a minute. What you’re supposed to do is to create a whole bunch of them and stop them so they’re ready when you need them. But for Sprites, we need create to be so fast it feels like they’re already there waiting for you.
We only murdered user containers because we wanted them dead.
Most of what’s slow about creating a Fly Machine is containers. I say this with affection: your containers are crazier than a soup sandwich. Huge and fussy, they take forever to pull and unpack. The regional locality sucks; create a Fly Machine in São Paulo on gru-3838, and a create on gru-d795 is no faster. A truly heartbreaking amount of engineering work has gone into just allowing our OCI registry to keep up with this system.
It’s a tough job, is all I’m saying. Sprites get rid of the user-facing container. Literally: problem solved. Sprites get to do this on easy mode.
Now, today, under the hood, Sprites are still Fly Machines. But they all run from a standard container. Every physical worker knows exactly what container the next Sprite is going to start with, so it’s easy for us to keep pools of “empty” Sprites standing by. The result: a Sprite create doesn’t have any heavy lifting to do; it’s basically just doing the stuff we do when we start a Fly Machine.
You can create a couple dozen Sprites right now if you want. It’ll only take a second.

Every Sprite comes with 100GB of durable storage. We’re able to do that because the root of storage is S3-compatible object storage.
You can arrange for 100GB of storage for a Fly Machine. Or 200, or 500. The catch:
flyctl); we can’t reasonably default it in.[†] we print a big red warning about this if you try to make a single-node cluster
We designed the storage stack for Fly Machines for Postgres clusters. A multi-replica Postgres cluster gets good mileage out of Fly Volumes. Attached storage is fast, but can lose data† — if a physical blows up, there’s no magic what rescues its stored bits. You’re stuck with our last snapshot backup. That’s fine for a replicated Postgres! It’s part of what Postgres replication is for. But for anything without explicit replication, it’s a very sharp edge.
Worse, from our perspective, is that attached storage anchors workloads to specific physicals. We have lots of reasons to want to move Fly Machines around. Before we did Fly Volumes, that was as simple as pushing a “drain” button on a server. Imagine losing a capability like that. It took 3 years to get workload migration right with attached storage, and it’s still not “easy”.
Object stores are the Internet’s Hoover Dams, the closest things we have to infrastructure megaprojects.
Sprites jettison this model. We still exploit NVMe, but not as the root of storage. Instead, it’s a read-through cache for a blob on object storage. S3-compatible object stores are the most trustworthy storage technology we have. I can feel my blood pressure dropping just typing the words “Sprites are backed by object storage.”
The implications of this for orchestration are profound. In a real sense, the durable state of a Sprite is simply a URL. Wherever he lays his hat is his home! They migrate (or recover from failed physicals) trivially. It’s early days for our internal tooling, but we have so many new degrees of freedom to work with.
I could easily do another 1500-2000 words here on the Cronenberg film Kurt came up with for the actual storage stack, but because it’s in flux, let’s keep it simple.
The Sprite storage stack is organized around the JuiceFS model (in fact, we currently use a very hacked-up JuiceFS, with a rewritten SQLite metadata backend). It works by splitting storage into data (“chunks”) and metadata (a map of where the “chunks” are). Data chunks live on object stores; metadata lives in fast local storage. In our case, that metadata store is kept durable with Litestream. Nothing depends on local storage.
(our pre-installed Claude Code will checkpoint aggressively for you without asking)
This also buys Sprites fast checkpoint and restore. Checkpoints are so fast we want you to use them as a basic feature of the system and not as an escape hatch when things go wrong; like a git restore, not a system restore. That works because both checkpoint and restore merely shuffle metadata around.
Our stack sports a dm-cache-like feature that takes advantage of attached storage. A Sprite has a sparse 100GB NVMe volume attached to it, which the stack uses to cache chunks to eliminate read amplification. Importantly (I can feel my resting heart rate lowering) nothing in that NVMe volume should matter; stored chunks are immutable and their true state lives on the object store.
Our preference for object storage goes further than the Sprite storage stack. The global orchestrator for Sprites is an Elixir/Phoenix app that uses object storage as the primary source of metadata for accounts. We then give each account an independent SQLite database, again made durable on object storage with Litestream.
In the cloud hosting industry, user applications are managed by two separate, yet equally important components: the host, which orchestrates workloads, and the guest, which runs them. Sprites flip that on its head: the most important orchestration and management work happens inside the VM.
Here’s the trick: user code running on a Sprite isn’t running in the root namespace. We’ve slid a container between you and the kernel. You see an inner environment, managed by a fleet of services running in the root namespace of the VM.
I wish we’d done Fly Machines this way to begin with. I’m not sure there’s a downside. The inner container allows us to bounce a Sprite without rebooting the whole VM, even on checkpoint restores. I think Fly Machines users could get some mileage out of that feature, too.
With Sprites, we’re pushing this idea as far as we can. The root environment hosts the majority of our orchestration code. When you talk to the global API, chances are you’re talking directly to your own VM. Furthermore:
*:8080, we’ll make it available outside the Sprite — yep, that’s in the root namespace too.Platform developers at Fly.io know how much easier it can be to hack on init (inside the container) than things like flyd, the Fly Machines orchestrator that runs on the host. Changes to Sprites don’t restart host components or muck with global state. The blast radius is just new VMs that pick up the change. We sleep on how much platform work doesn’t get done not because the code is hard to write, but because it’s so time-consuming to ensure benign-looking changes don’t throw the whole fleet into metastable failure. We had that in mind when we did Sprites.
Sprites running on Fly.io take advantage of the infrastructure we already have. For instance: Sprites might be the fastest thing there currently exists to get Claude or Gemini to build a full-stack application on the Internet.
That’s because Sprites plug directly into Corrosion, our gossip-based service discovery system. When you ask the Sprite API to make a public URL for your Sprite, we generate a Corrosion update that propagates across our fleet instantly. Your application is then served, with an HTTPS URL, from our proxy edges.
Sprites live alongside Fly Machines in our architecture. They include some changes that are pure wins, but they’re mostly tradeoffs:
Sprites are optimized for a different kind of computing than Fly Machines, and while Kurt believes that the future belongs to malleable, personalized apps, I’m not so sure. To me, it makes sense to prototype and acceptance-test an application on Sprites. Then, when you’re happy with it, containerize it and ship it as a Fly Machine to scale it out. An automated workflow for that will happen.
Finally, Sprites are a contract with user code: an API and a set of expectations about how the execution environment works. Today, they run on top of Fly Machines. But they don’t have to. Jerome’s working on an open-source local Sprite runtime. We’ll find other places to run them, too.
I can’t not sound like a shill. Sprites are the one thing we’ve shipped that I personally experience as addictive. I haven’t fully put my finger on why it feels so much easier to kick off projects now that I can snap my finger and get a whole new computer. The whole point is that there’s no reason to parcel them out, or decide which code should run where. You just make a new one.
So to make this fully click, I think you should just install the sprite command, make a Sprite, and then run an agent in it. We’ve preinstalled Claude, Gemini, and Codex, and taught them how to do things like checkpoint/restore, registering services, and getting logs. Claude will run in --dangerously-skip-permissions mode (because why wouldn’t it). Have it build something; I built a “Chicago’s best sandwich” bracket app for a Slack channel.
Sprites bill only for what you actually use (in particular: only for storage blocks you actually write, not the full 100GB capacity). It’s reasonable to create a bunch. They’re ball-point disposable computers. After you get a feel for them, it’ll start to feel weird not having them handy.
They do suspend even when they say they are “running”.
I think people can get bogged down in the technical weeds over what a sprite is in graphics. Historically it started out as mini graphics overlays in hardware. There was a transition period motivated by Amiga documentation to have Sprites and Bobs, to distinguish, and perhaps advertise, the use of the Blitter. When software or Blitter Sprites became nearly ubiquitous, they returned to simply being called Sprites, the fairly rare use of the original form became known as Hardware Sprites. Usually it was only mouse pointers that remained as Hardware Sprites
Obviously the term Hardware Sprites is not strictly a distinguishing label either. They are all controlled by software using hardware with some degree of balance between the two.