Workspace

Sleep and wake on request

Enable Sleep when idle to let an app's workspace release its running compute and host RAM when it has no web traffic. Oblien saves the running workspace's memory to disk. The next request to an exposed port URL or connected custom domain restores the workspace and reaches your app.

Use the same setting for any HTTP app in a compatible Linux workspace. Your framework, language, and app port are your choice. The workspace scales between zero and one running instance, with concurrent requests served by the same app.

This is off by default. Enabling it does not change how you build or deploy your app.

Requirements

  • A persistent workspace (mode: 'permanent') with memory snapshot support. Check snapshot_supported in its lifecycle response. Nested KVM workloads currently do not support this mode.
  • An app listening on 0.0.0.0 at the port you expose. Port 3000 in the examples below is only an example.
  • A public port URL or connected custom domain, with enough available credit and running resources to wake the workspace.

Dashboard

  1. Start your app and open the workspace's Public Access tab.
  2. Expose the port your app listens on. Connect a custom domain if you want one.
  3. Enable Sleep when idle, choose an idle time of at least two minutes, and save.
  4. Use the app's public URL normally. Requests wake it when it is asleep.

The same sleep setting is available under Settings → Lifecycle.

One policy covers all public port URLs and custom domains connected to that workspace. Domains must already be connected, with DNS and HTTPS configured normally. There is no separate wake setting per domain.

The workspace shows Hibernated after its memory is saved and the VM process has exited. A request changes its status to Starting or Resuming until it is running again. The dashboard polls these transitions; refreshing the page keeps the current status.

SDK

import Oblien from 'oblien';

const client = new Oblien({
  clientId: process.env.OBLIEN_CLIENT_ID,
  clientSecret: process.env.OBLIEN_CLIENT_SECRET,
});

// Prepare your app and make it listen on 0.0.0.0:3000 first.
const ws = client.workspace('YOUR_WORKSPACE_ID');
const port = await ws.publicAccess.expose({ port: 3000 });
await ws.lifecycle.setIdle({ suspend_after: '15m' });
console.log(port);

// Changes apply immediately, without restarting the workspace.
await ws.lifecycle.setIdle({ suspend_after: '30m' });

// Turn automatic sleep and public-request wake off.
await ws.lifecycle.setIdle(null);

You can also include the policy when creating a workspace:

const workspace = await client.workspaces.create({
  image: 'YOUR_IMAGE', // Choose an image with memory snapshot support.
  mode: 'permanent',
  config: { idle: { suspend_after: '15m' } },
});

Creation still supports wait_ready: false and waitUntilReady(). Idle sleep uses the existing workspace; it does not create a new VM for every HTTP request.

REST and CLI

PUT /workspace/:workspaceId/lifecycle/idle
Content-Type: application/json

{ "suspend_after": "15m", "stop_after": 0 }

Use suspend_after: 0 to disable automatic sleep and wake. A sleeping workspace then stays asleep until you explicitly restore it. Read the effective policy and snapshot capability with GET /workspace/:workspaceId/lifecycle.

oblien lifecycle idle YOUR_WORKSPACE_ID --after 15m
oblien lifecycle idle YOUR_WORKSPACE_ID --disable
SettingDefaultMeaning
suspend_afterDisabledTime without web activity before saving memory. Minimum 120 seconds.
stop_after0Optional time spent hibernated before deleting the saved memory. Minimum one hour when enabled.

Values accept seconds or duration strings, such as "15m" and "2h30m". Leave stop_after at zero to retain the saved process state until the next wake. With a retention limit, workspace files remain after it expires, but the next request cold-boots the VM; configure your app to start at boot if you use this option.

What happens when a request arrives

While the workspace is running, requests go directly to your app through the gateway. While it is asleep, the gateway waits for the workspace to restore and its requested app port to accept connections, then forwards the original request. Memory restore preserves the running application processes and their memory; the app continues without a rebuild or restart.

Concurrent requests share one wake operation across the workspace's URLs and domains. Each waiting request is then forwarded separately, preserving its method, body, headers, and query. Normal rate limits still apply.

Wake time depends on the saved state, host load, and application dependencies. If wake takes longer than the gateway's wait budget, it returns 503 with Retry-After: 1; wake continues in the background. Clients can retry with backoff and a deadline. This provides a bounded HTTP wait rather than a durable request queue.

Application error responses pass through unchanged. Oblien retries a failed upstream connection only when it has not sent request bytes, so it does not automatically replay an ambiguous write. Use application idempotency keys when retrying writes yourself.

Prepare your app for sleep

AreaWhat your app should handle
Databases and external APIsOther services keep running while the workspace sleeps. Their connections, transactions, and credentials can expire. Use operation timeouts and reconnect when needed.
Retrying writesUse idempotency keys or another safe retry strategy. A timeout does not prove that a remote write failed.
CachesFiles and in-memory caches remain after a memory restore. Expire or refresh cached data using your app's normal rules.
Timers and background workExecution stops while the workspace sleeps; wall-clock time continues. Keep the workspace active while a job needs to run.
Application healthAn open app port signals readiness. Your app remains responsible for handling unavailable dependencies and unhealthy routes.

A database pool's connection timeout alone may be insufficient: a restored socket can appear connected even after the remote service has closed it. Bound database operations too, discard dead connections, and retry only operations that are safe to repeat.

Keep a workspace active

HTTP requests and open HTTP/WebSocket streams through the gateway renew the idle timer. A persistent connection can keep a workspace running indefinitely. Activity is batched, so suspension can occur about a minute after the configured idle period.

Enable the policy before opening long-lived streams. If you enable it while a stream is already connected, reconnect that stream so its activity is counted. Changing the policy does not close existing connections.

Background jobs, direct IP traffic, SSH, and native TCP connections do not count as gateway activity. Send ws.lifecycle.ping() periodically, well within the idle timeout, or leave automatic sleep disabled for those workloads.

Disable sleep and wake

Turn off Sleep when idle, call ws.lifecycle.setIdle(null), or use suspend_after: 0 through REST. This clears the idle policy without deleting workspace files. A workspace that is already asleep stays asleep until you explicitly restore it.

While the policy is enabled, public routes can wake a sleeping or stopped workspace. Disable the policy to prevent automatic wake. Revoke public ports and disconnect custom domains to remove public access entirely.

Resource behavior

Hibernation releases the running VM process and its host RAM. Writable disks, saved memory, and other retained resources still consume storage. Leave stop_after: 0 to keep the memory snapshot until wake; configuring retention expiry makes a later wake start the app from disk instead.

This policy manages one workspace. Additional replicas, automatic recovery on another host, and durable background job queues require their own setup.

Wake uses the normal credit and running-resource checks. A denied wake leaves the VM asleep. Removing a route prevents later requests from using it to wake the previous owner.