✦ For Durable Objects · WebSockets · Alarms · State Isolation ✦

01For Durable Objects

Your Durable Object crashed.
Its logs died with it.

Durable Objects are stateful isolates. When they crash, the entire isolate dies — and any logs buffered inside it are gone forever. FlareLog persists DO errors, WebSocket events, and alarm failures outside the isolate.

$npm install @flarelog/sdk
Live — durable-objectsTail Worker connected
nowERRORWebSocket error: Invalid frame header
12sWARNAlarm execution failed: upstream timeout
45sINFODO request — /increment
1mERRORDO evicted under memory pressure
3mWARNHibernation wake: state restored from storage
5mINFOAlarm completed
02FlareLog vs Cloudflare native

Durable Objects need
durable observability.

Capability
FlareLog
Cloudflare Native
Crash visibility
SDK + Tail Worker capture DO exit reason
Logs lost when the isolate dies
Alarm execution logs
Structured alarm lifecycle logs
No alarm-specific logging
DO ID context
Every log tagged with DO ID
Mixed with other Workers
WebSocket events
Full connect / message / error / close events
Close code only, no reason
Log retention
7 days free, 90 days on Pro
7 days on Workers Free/Pro
DO-to-DO RPC tracing
W3C trace context across DO calls
Black box
Hibernation / eviction
Capture wake and eviction events
No signal on wake or eviction
Alerting
Email + Slack alerts on DO errors
None
032-minute setup

HTTP, WebSockets, or alarms.
We see inside the isolate.

Whether your DO handles HTTP requests, WebSocket sessions, or scheduled alarms, FlareLog captures structured logs with the DO ID attached.

src/counter.ts
import { DurableObject } from "cloudflare:workers";
import { FlareLog } from "@flarelog/sdk";

export class Counter extends DurableObject {
  private logger: FlareLog;
  private count: number;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);

    this.logger = new FlareLog({
      apiKey: env.FLARELOG_API_KEY,
      environment: "production",
      serverName: `do-${ctx.id.toString()}`,
    });

    this.count = 0;
  }

  async fetch(request: Request) {
    const traceId = request.headers.get("x-trace-id") || crypto.randomUUID();

    return this.logger.withRequest(
      { request, traceId },
      { waitUntil: (p) => this.ctx.waitUntil(p) },
      async () => {
        this.logger.info("DO request", {
          doId: this.ctx.id.toString(),
          path: new URL(request.url).pathname,
        });

        this.count++;
        return new Response(`Count: ${this.count}`);
      }
    );
  }
}

Every request logged with DO ID as metadata.

wrangler.toml
# wrangler.toml
[vars]
FLARELOG_ENVIRONMENT = "production"

# Secret
wrangler secret put FLARELOG_API_KEY
04Durable Object failure modes

The nightmares only
DO operators understand

Logs die inside the crashing isolate

A Durable Object is a single isolate. If it throws during initialization or exhausts memory, the whole isolate terminates. Any logs buffered inside are lost. FlareLog flushes to the Tail Worker or OTLP endpoint before the isolate dies, so the crash still shows up in your dashboard.

Alarm execution failures

DO alarms are cron-like scheduled tasks that run inside the isolate. When they throw, Cloudflare retries them, but you get no insight into why. FlareLog records alarm start, completion, and failure with the DO ID and any context you attach.

WebSocket closes with no reason

A user disconnects, a proxy drops the connection, or your DO throws mid-message. Cloudflare shows a close code at best. FlareLog captures the full WebSocket lifecycle: open, message, error, and close with reason and DO ID.

Hibernation wake errors

DOs hibernate to save cost and wake on the next request. If state was corrupted, storage failed, or a dependency is unreachable on wake, the error happens before your handler runs. FlareLog captures wake-time failures via the Tail Worker.

DO-to-DO RPC tracing is a black box

Cloudflare's RPC lets DOs call each other directly. Without propagated trace context, a failure in one DO is impossible to link to the originating request. FlareLog injects W3C traceparent so you can follow the request across DO boundaries.

Rate limit / eviction with no signal

DOs can be evicted under memory pressure or rate limits. There's no native signal. FlareLog's Tail Worker records the eviction event so you can correlate unexpected disconnects with platform limits.

The 7-day retention cliff

Like all Workers logs, Cloudflare keeps DO logs for 7 days. Debugging a long-lived chat room issue or a recurring alarm bug from last week is impossible. FlareLog retains logs for 90 days on Pro.
05What you get

Built for Durable Object
production debugging

DO ID

Every log tagged with its DO

Use serverName or metadata to attach the DO ID to every log line. Search, filter, and group by DO across HTTP, WebSocket, and alarm handlers.

Tail Worker

Capture DO deaths

The Tail Worker sees failures outside the isolate — init crashes, OOM, CPU limits, evictions — even when your DO never logged in.

WebSockets

Full WS lifecycle logs

Log connect, message, error, and close events. Know why a session ended, not just that it did.

Alarms

Alarm execution observability

Record alarm schedule, fire, success, and failure. Get alerted when a scheduled task throws or retries too many times.

Traces

Cross-DO trace propagation

Inject W3C trace context into DO-to-DO RPC calls and service bindings. Follow a request across isolates as if they were one service.

Retention

90-day searchable history

Debug long-lived bugs, recurring alarms, and intermittent WebSocket issues with 90 days of searchable logs on Pro.

90d

retention on Pro

DO ID

on every log line

10k

free logs/mo

$19

flat Pro bucket

06FAQ

Questions Durable Objects
operators ask

Can I use the Tail Worker for Durable Object crash capture?

Yes. The Tail Worker attaches to any Worker or Durable Object producer. Because the Tail Worker runs outside the isolate, it can record DO exits caused by init failures, OOM, CPU limits, and evictions.

Does it work with hibernated DOs?

Yes. Logs written inside the DO are flushed before hibernation via ctx.waitUntil(). Wake-time errors are captured by the Tail Worker.

How do I correlate logs across multiple DOs?

Use logger.injectTraceContext() when making DO-to-DO or service-binding calls. The trace ID ties requests together across isolates.

What about alarm retries?

FlareLog records each alarm invocation, including failure and retry count. You can alert when an alarm fails repeatedly or hasn't run on schedule.

Will it slow down my DO?

No. Logging is asynchronous and uses waitUntil. For short-lived or alarm handlers, workerMode: true flushes aggressively so nothing is lost.

Can I run this on the Workers free plan?

Yes. The SDK and Tail Worker work on every plan. FlareLog's free tier covers 10,000 logs per month.

07Start today

Make your Durable Objects
actually observable.

Free tier includes 10,000 logs/month. Add one SDK import or the Tail Worker template and start seeing DO crashes, alarm failures, and WebSocket events in minutes.