Skip to main content

Overview

Sessions are isolated execution environments in buntime.sh. Each session provides a complete Bun runtime with its own filesystem, processes, and resources. Sessions persist state across multiple executions, making them ideal for iterative development and multi-step workflows.

What is a Session?

A session is:
  • Isolated: Completely separate from other sessions
  • Persistent: Files and processes survive between executions
  • Temporary: Automatically expires after a configurable TTL
  • Identified: Has a unique session ID (format: ses_ + alphanumeric)
// Create a session
const session = await client.sessions.create();
console.log(session.id); // "ses_abc123def456"

// Use it multiple times
await client.execute({ sessionId: session.id, code: '...' });
await client.execute({ sessionId: session.id, code: '...' });

Session Lifecycle

1. Creation

When you create a session:
  • A unique session ID is generated
  • An isolated container is allocated
  • An empty /workspace directory is created
  • Metadata is stored in KV
  • A TTL (time-to-live) is set
const session = await client.sessions.create({
  ttl: 3600, // 1 hour in seconds
  metadata: {
    userId: 'user_123',
    purpose: 'data-analysis'
  }
});

2. Active State

While active, a session:
  • Executes code immediately
  • Maintains running processes
  • Keeps files in memory
  • Responds to API requests
  • Tracks resource usage

3. Idle State

After 5 minutes of inactivity:
  • Container sleeps to save resources
  • Filesystem remains in memory
  • Processes stay alive but suspended
  • Reduced billing rate
  • Wakes instantly on next request

4. Deep Sleep

After 30 minutes of inactivity:
  • /workspace filesystem is saved to R2 storage
  • Container is deallocated
  • Processes are terminated
  • No billing while sleeping
  • ~3 second wake time on next request

5. Expiration

When TTL is reached or session is deleted:
  • All files are permanently deleted
  • Container is deallocated
  • R2 snapshot is removed
  • KV metadata is deleted
  • Session ID becomes invalid
Session expiration is permanent. All data is deleted and cannot be recovered.

Session Properties

Session ID

Format: ses_ followed by 18-20 alphanumeric characters
ses_abc123def456ghi789
Used in all API calls to identify which session to execute code in.

Time-to-Live (TTL)

  • Default: 86400 seconds (24 hours)
  • Minimum: 300 seconds (5 minutes)
  • Maximum Free: 86400 seconds (24 hours)
  • Maximum Paid: 604800 seconds (7 days)
Sessions automatically expire after TTL:
const session = await client.sessions.create({
  ttl: 3600 // Session expires in 1 hour
});

Metadata

Attach custom metadata to sessions (max 16KB):
const session = await client.sessions.create({
  metadata: {
    userId: 'user_123',
    conversationId: 'conv_456',
    environment: 'production',
    createdBy: 'ai-agent'
  }
});
Metadata is useful for:
  • Tracking session ownership
  • Associating sessions with users or conversations
  • Debugging and analytics
  • Custom business logic

Preview URL

Every session gets a unique web preview URL:
https://{sessionId}.buntime.sh
This URL routes to any web server running on port 8080 in the session.

Resource Limits

Each session has resource limits:
ResourceFree TierPaid TierEnterprise
Memory1 GB4 GBCustom
CPU0.25 cores1 coreCustom
Disk1 GB5 GBCustom
ProcessesUnlimited*Unlimited*Unlimited*
*Subject to memory/CPU limits

Filesystem Persistence

Workspace Directory

All code executes in /workspace:
await client.execute({
  sessionId: session.id,
  code: `
    console.log(process.cwd()); // "/workspace"
    
    // Write a file
    await Bun.write('data.txt', 'Hello World');
    
    // File persists for next execution
  `
});

// Later...
await client.execute({
  sessionId: session.id,
  code: `
    // File still exists
    const data = await Bun.file('data.txt').text();
    console.log(data); // "Hello World"
  `
});

File Persistence Rules

  • ✅ Files in /workspace persist between executions
  • ✅ Files survive idle and deep sleep states
  • ✅ Files are saved to R2 during deep sleep
  • ✅ Files are restored when session wakes
  • ❌ Files outside /workspace may not persist
  • ❌ Files are deleted when session expires

Directory Structure

/workspace/
  ├── your_files/          # Your code and data
  ├── node_modules/        # Installed packages
  └── .buntime/            # Internal buntime.sh metadata
      ├── executions/      # Execution history
      └── processes/       # Running process info

Process Management

Background Processes

Processes started in a session stay alive:
// Start a web server
await client.execute({
  sessionId: session.id,
  code: `
    Bun.serve({
      port: 8080,
      fetch() {
        return new Response('Server running!');
      }
    });
  `
});

// Server keeps running in background
// Access at https://{sessionId}.buntime.sh

Process Lifecycle

  • ✅ Processes survive between executions
  • ✅ Processes stay alive during idle state
  • ❌ Processes are terminated during deep sleep
  • ❌ Processes are terminated on session expiry

Stopping Processes

Kill specific processes:
await client.execution.kill({
  sessionId: session.id,
  pid: 1234 // Optional: specific process ID
});
Or restart the session by deleting and recreating.

Session Strategies

One Session Per Conversation

Best for AI assistants:
class ConversationManager {
  private sessions = new Map<string, string>();
  
  async getSession(conversationId: string) {
    if (!this.sessions.has(conversationId)) {
      const session = await client.sessions.create({
        ttl: 3600,
        metadata: { conversationId }
      });
      this.sessions.set(conversationId, session.id);
    }
    return this.sessions.get(conversationId);
  }
  
  async endConversation(conversationId: string) {
    const sessionId = this.sessions.get(conversationId);
    if (sessionId) {
      await client.sessions.delete({ sessionId });
      this.sessions.delete(conversationId);
    }
  }
}

One Session Per Task

Best for independent operations:
async function runTask(taskCode: string) {
  const session = await client.sessions.create({ ttl: 600 });
  
  try {
    const result = await client.execute({
      sessionId: session.id,
      code: taskCode
    });
    return result;
  } finally {
    await client.sessions.delete({ sessionId: session.id });
  }
}

Session Pool

Best for high-volume workloads:
class SessionPool {
  private pool: string[] = [];
  
  async getSession() {
    if (this.pool.length === 0) {
      const session = await client.sessions.create();
      return session.id;
    }
    return this.pool.pop()!;
  }
  
  releaseSession(sessionId: string) {
    this.pool.push(sessionId);
  }
  
  async cleanup() {
    await Promise.all(
      this.pool.map(id => client.sessions.delete({ sessionId: id }))
    );
    this.pool = [];
  }
}

Best Practices

Use shorter TTLs (1 hour) for ephemeral tasks, longer (24 hours) for conversations.
// Short-lived task
const task = await client.sessions.create({ ttl: 600 });

// Conversation
const chat = await client.sessions.create({ ttl: 86400 });
Always add metadata to help debug and track sessions.
const session = await client.sessions.create({
  metadata: {
    userId: req.user.id,
    source: 'web-app',
    version: '1.0.0'
  }
});
Delete sessions explicitly to free resources and reduce costs.
try {
  // Use session
} finally {
  await client.sessions.delete({ sessionId: session.id });
}
Never reuse sessions across different users or security contexts.
// ❌ Bad: Sharing session between users
const sharedSession = await client.sessions.create();

// ✅ Good: One session per user
const userSession = await client.sessions.create({
  metadata: { userId: user.id }
});

Monitoring Sessions

Get Session Info

Check session status and resource usage:
const info = await client.sessions.info({ sessionId: session.id });

console.log(info.createdAt);      // When session was created
console.log(info.lastActive);     // Last activity timestamp
console.log(info.expiresAt);      // When session will expire
console.log(info.filesCount);     // Number of files in workspace
console.log(info.activeProcesses); // Running processes
console.log(info.state);          // "active" | "idle" | "deep-sleep"

List Your Sessions

View all active sessions (coming soon):
const sessions = await client.sessions.list({
  limit: 50,
  offset: 0
});

Limits

PlanConcurrent SessionsMax TTLTotal Sessions/Month
Free1024 hoursUnlimited
Paid1007 daysUnlimited
EnterpriseCustomCustomUnlimited

Common Issues

Session Not Found

If you get a 404 error:
  • Session may have expired
  • Session ID might be incorrect
  • Session was deleted

Session Limit Reached

If you hit concurrent session limits:
  • Delete unused sessions
  • Upgrade to paid plan
  • Implement session pooling

Files Missing After Wake

If files disappear after deep sleep:
  • Ensure files are in /workspace
  • Check file paths are absolute from /workspace
  • Verify TTL hasn’t expired