Skip to content

Room cleanup

Use lifecycle APIs when your app creates temporary rooms, disposable documents, or closed collaboration spaces. Realtime keeps hot state in Durable Objects and persistent records in the Database product.

Terminal window
import { backend } from "@layeron/core"
import { realtime } from "@layeron/modules"
const app = backend()
const live = realtime({
name: "rooms",
lifecycle: {
idleTtlSeconds: 300,
destroyTtlSeconds: 86400,
allowRecreate: false,
},
})
app.use(live)
Terminal window
app.get("/rooms/:roomId/lifecycle", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
return await live.room(roomId).lifecycle()
})

A lifecycle response includes the room status and active connection count:

Terminal window
{
room: "room_123",
kind: "room",
status: "idle",
activeConnections: 0,
idleSince: "2026-05-25T00:00:00.000Z"
}
Terminal window
app.post("/rooms/:roomId/destroy", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
return await live.room(roomId).destroy({
deleteHistory: true,
deleteSnapshots: true,
})
})
Terminal window
app.post("/documents/:documentId/destroy", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const documentId = pathSegments[2]
return await live.crdtRoom(documentId).destroy({
deleteHistory: true,
deleteSnapshots: true,
deleteCrdtUpdates: true,
})
})

Use this for deleted documents or test documents whose collaborative update stream should be removed.

Terminal window
app.post("/rooms/:roomId/archive", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
return await live.room(roomId).destroy()
})

Calling destroy() without deletion flags closes the hot room and marks it as destroyed while retaining history and snapshots.