Skip to main content

Overview

Computer sessions have configurable lifetimes with automatic cleanup. Understanding the lifecycle helps you optimize costs and avoid unexpected terminations.

Timeouts

Sessions have two independent timeout mechanisms:

Max Lifetime (timeout_seconds)

The absolute maximum duration a session can exist.
# Session expires after 1 hour regardless of activity
computer = client.create(
    kind="browser",
    timeout_seconds=3600  # 1 hour max
)
Default: Based on your plan tier (free: 1 hour, pro: 4 hours, enterprise: 24 hours)

Inactivity Timeout (inactivity_timeout_seconds)

How long a session can be idle before automatic termination.
# Terminate after 2 minutes of inactivity
computer = client.create(
    kind="browser",
    inactivity_timeout_seconds=120,
    auto_kill=True  # Enable auto-termination (default)
)
Default: 120 seconds (2 minutes)

auto_kill

Controls whether the session automatically terminates on inactivity.
ValueBehavior
true (default)Session terminates after inactivity_timeout_seconds of no activity
falseSession runs until timeout_seconds max lifetime, regardless of activity
Setting auto_kill=false means you’re billed for the full session duration even if idle. Always call terminate() when done.

Keepalive

For long-running sessions with intermittent activity, use keepalive to prevent inactivity timeout.
from tzafon import Computer

client = Computer()
computer = client.create(kind="browser")

# Reset the inactivity timer
computer.keep_alive()
When to use keepalive:
  • Processing data between actions (AI inference, API calls)
  • Waiting for external events before next action
  • Long pauses in interactive sessions
Every action automatically resets the inactivity timer. You only need explicit keepalive during periods with no actions.

Session Status

Check the current status and remaining time for a session:
# Get session status
status = client.computers.retrieve(computer.id)

print(f"Status: {status.status}")
print(f"Created: {status.created_at}")
print(f"Expires: {status.expires_at}")
print(f"Idle expires: {status.idle_expires_at}")
print(f"Last activity: {status.last_activity_at}")

Status Fields

FieldDescription
statusCurrent state: ready, running, terminated
created_atWhen the session was created
expires_atWhen max lifetime expires
idle_expires_atWhen inactivity timeout expires
last_activity_atTimestamp of last action or keepalive
max_lifetime_secondsConfigured max lifetime
inactivity_timeout_secondsConfigured inactivity timeout
auto_killWhether auto-termination is enabled

Plan Limits

Your plan determines session limits:
PlanMax Concurrent SessionsMax Duration
Free21 hour
Pro104 hours
EnterpriseUnlimited24 hours
Exceeding concurrent session limits returns HTTP 429 (Too Many Requests).

Billing Errors

HTTP 402 - Payment Required

If your account has insufficient credits or a payment issue:
import tzafon
from tzafon import Computer

try:
    client = Computer()
    computer = client.create(kind="browser")
except tzafon.APIStatusError as e:
    if e.status_code == 402:
        print("Payment required - add credits at tzafon.ai/billing")
    raise
Common causes:
  • Account balance depleted
  • Payment method failed
  • Credit card expired
Resolution: Add credits or update payment method at tzafon.ai/billing.

HTTP 429 - Rate Limited

Too many requests or concurrent sessions:
import tzafon
from tzafon import Computer
import time

try:
    client = Computer()
    computer = client.create(kind="browser")
except tzafon.RateLimitError:
    print("Rate limited - waiting before retry")
    time.sleep(60)
    # Retry...
Common causes:
  • Exceeded concurrent session limit for your plan
  • Too many failed authentication attempts (10 failures in 10 minutes blocks IP)

Best Practices

Use context managers or explicit terminate() calls to stop billing immediately.
# Good: Context manager handles cleanup
with client.create(kind="browser") as computer:
    # ...work...
    pass  # Auto-terminates
Match timeouts to your workload. Short tasks should have short timeouts.
# Quick scrape job
computer = client.create(
    kind="browser",
    timeout_seconds=300,  # 5 min max
    inactivity_timeout_seconds=60  # 1 min idle
)
If processing takes longer than inactivity timeout, send keepalives.
computer.screenshot()  # Capture
# Long AI processing...
computer.keep_alive()  # Don't timeout
# More processing...
computer.click(x, y)   # Continue
Check for 402 errors and notify users to add credits.
except tzafon.APIStatusError as e:
    if e.status_code == 402:
        notify_admin("Tzafon credits depleted")

Lifecycle Diagram

┌─────────────────────────────────────────────────────────────┐
│                     Session Lifecycle                        │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  create() ──► READY ──► RUNNING ──► TERMINATED              │
│                           │              ▲                   │
│                           │              │                   │
│                           ▼              │                   │
│              ┌────────────────────┐      │                   │
│              │  Action/Keepalive  │──────┤ inactivity        │
│              │  resets idle timer │      │ timeout           │
│              └────────────────────┘      │ (if auto_kill)    │
│                                          │                   │
│              max lifetime ───────────────┘                   │
│              terminate() ────────────────┘                   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Next Steps