Skip to content

Services

A Sprite pauses when nothing is using it, and processes don’t reliably survive the trip. A warm wake resumes them where they left off; a cold boot drops them entirely. Anything you started by hand in a shell, a dev server, a database, an agent, is gone after a cold wake unless something brings it back.

That something is a service. A service is a process the Sprite runtime owns: it starts when the Sprite boots, restarts if it crashes, and can receive the HTTP traffic that hits your Sprite’s URL. You define it once. The runtime keeps bringing it back.

What happens to a service depends on how the Sprite went down and how it came back:

  • Warm wake. The VM was suspended with your process inside it. The process resumes mid-thought; it is not restarted. Wakes take 100–500ms.
  • Cold boot. Process state was dropped. The runtime starts every service fresh, in dependency order. Wakes take 1–2s.
  • Crash. A service process that exits on its own gets restarted by the runtime.
  • Stop. A service you stop explicitly stays stopped until you start it again.

Services don’t keep a Sprite from pausing. A Sprite with ten services defined still pauses when it goes idle; the services come back on the next wake. A service that’s actively handling HTTP requests counts as activity, the same as any other traffic, but a quiet one doesn’t hold the Sprite in an active state. If you need a Sprite to stay up while work finishes, that’s a job for the Tasks API, not a service.

The sprite-env CLI ships in every Sprite and talks to the runtime’s management socket. Create a service with a name, a command, and its arguments:

Terminal window
sprite-env services create web --cmd python3 --args "-m,http.server,3000" --http-port 3000

--cmd takes the binary only. Arguments go in --args, comma-separated.

The command starts the service and streams its first few seconds of output as NDJSON, so a service that dies on startup fails in front of you instead of silently in the background:

{"type":"started","timestamp":1780420274555}
{"type":"complete","log_files":{"combined":"/.sprite/logs/services/web.log","stderr":"/.sprite/logs/services/web.log","stdout":"/.sprite/logs/services/web.log"},"timestamp":1780420276551}

The stream watches for 5 seconds by default. Pass --duration 30s to watch longer, or --no-stream to return immediately.

Confirm it’s serving:

Terminal window
curl localhost:3000
FlagWhat it does
--cmd <path>The executable to run. Required. Binary only, no arguments here.
--args <a,b,c>Comma-separated arguments: --args "-m,http.server,3000"
--env <K=v,...>Comma-separated environment variables: --env "PORT=3000,DEBUG=1"
--dir <path>Working directory for the process
--needs <svc,...>Services that must start before this one
--http-port <port>Route the Sprite’s URL to this port and auto-start the service on incoming requests
--duration <time>How long to stream logs after starting (default: 5s)
--no-streamDon’t stream logs after creation

Every Sprite has a URL, and the Sprite’s proxy routes incoming requests to port 8080 by default. A service created with --http-port changes that:

  • Requests to the Sprite’s URL route to the service’s port instead of 8080.
  • If the service isn’t running when a request arrives, the proxy starts it first, then forwards the request.
  • Only one service can have an HTTP port. Creating a second one fails with 409: another service already has an HTTP port configured.

Combined with wake-on-request, this gives you a server that costs nothing while idle. A request to a cold Sprite wakes the VM (1–2s), the proxy starts your service, and the request gets served. No traffic, no compute bill.

Terminal window
sprite-env services create web --cmd python3 --args "-m,http.server,3000" --http-port 3000

The Sprite’s URL requires authentication by default. See Working with Sprites for URL auth modes and testing from outside the Sprite.

Terminal window
sprite-env services list # all services and their state
sprite-env services get web # one service
sprite-env services restart web # stop, then start; streams logs
sprite-env services stop web # stop; stays stopped
sprite-env services start web # start a stopped service
sprite-env services signal web HUP # send any Unix signal
sprite-env services delete web # remove the service

get returns the definition plus live state:

{
"name": "web",
"cmd": "python3",
"args": ["-m", "http.server", "3000"],
"http_port": 3000,
"state": {
"name": "web",
"status": "running",
"pid": 7353,
"started_at": "2026-06-02T17:11:14.555839485Z"
}
}

Three behaviors worth knowing:

  • stop is sticky. A stopped service stays stopped. The runtime won’t restart it behind your back.
  • Killing the process is not. Send TERM or KILL via signal, or kill the PID directly, and the runtime treats it as a crash and restarts the service. The state’s restart_count increments each time. This means signal web TERM is effectively a restart; for clarity, use restart instead.
  • delete removes the definition, not the logs. The log file stays in /.sprite/logs/services/ after the service is gone.

Everything a service writes to stdout or stderr lands in /.sprite/logs/services/<name>.log, timestamped and tagged with the stream it came from:

2026-06-02T17:11:17.821Z [stderr] 127.0.0.1 - - [02/Jun/2026 17:11:17] "GET / HTTP/1.1" 200 -

Follow it like any other file:

Terminal window
tail -f /.sprite/logs/services/web.log

To watch output live while a service starts, use --duration on create, start, or restart.

There is no journalctl here. Sprites don’t run systemd; the log files and the create/start streams are how you see service output.

A service with --needs starts after the services it names. Use it when one process can’t come up until another is ready:

Terminal window
# The database starts first
sprite-env services create postgres \
--cmd /usr/lib/postgresql/16/bin/postgres \
--args "-D,/home/sprite/pgdata"
# The app starts after postgres
sprite-env services create app \
--cmd npm --args "start" \
--dir /home/sprite/myapp \
--needs postgres

On a cold boot, the runtime starts postgres before app, every time.

There are three ways to run something in a Sprite, and they solve different problems:

ServiceSession (sprite exec)Task
Survives a cold bootYes, restarts automaticallyNoNo, it’s a hold, not a process
Keeps the Sprite in an active stateOnly while handling trafficYes, while producing outputYes, until it expires
Best forServers, databases, daemonsInteractive work, builds, debuggingHolding the Sprite up while an agent or worker finishes

They compose. A common pattern for background agents: a service launches the agent at boot, the agent registers a task while it works, the task expires when the work is done, and the Sprite pauses until something needs it again. See Keeping a Sprite Running for the task side of that pattern.

The service died immediately.

The create stream tells you, with an exit event:

{"type":"started","timestamp":1780420024883}
{"type":"exit","exit_code":1,"timestamp":1780420025035}

Check the log file for the reason:

Terminal window
cat /.sprite/logs/services/web.log

A bad --cmd path looks like this:

2026-06-02T17:07:38.805Z [stderr] executable file `/usr/bin/does-not-exist` not found: No such file or directory

The service keeps restarting.

The runtime restarts crashing services, so a crash loop shows up as a climbing restart_count in sprite-env services get <name>. Read the log file to find out why it’s crashing, and test the command by hand in a shell with the same --dir and --env.

Requests to the Sprite’s URL aren’t reaching the service.

Check that the service actually has the HTTP port: sprite-env services list and look for http_port. Without it, the proxy routes to port 8080, not to your service.

Everything on this page uses the in-Sprite CLI. The same operations are available from outside through the Sprites REST API at /v1/sprites/{name}/services and the SDKs, which is how you’d configure services as part of provisioning a fleet of Sprites. See the Services API reference for endpoints and request schemas.

Keeping a Sprite Running

Use the Tasks API to hold a Sprite open while work finishes

Working with Sprites

Lifecycle, networking, and URL authentication

CLI Commands

The full sprite CLI reference