> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Background

> Execute shell commands in the background without blocking in HopX sandboxes. Run long-running shell commands asynchronously, monitor process status, and retrieve results when complete. Perfect for package installations, data processing, and time-consuming operations. Includes Python and JavaScript SDK examples and REST API endpoints.

Run shell commands in the background and return immediately. This is ideal for long-running commands that you want to monitor and manage separately.

## Overview

Background command execution is perfect for:

* Long-running commands (>5 minutes)
* Server processes that need to keep running
* Commands that don't need immediate results
* Parallel execution of multiple commands

<Note>
  Background commands return immediately with a `process_id`. Use process management to check status and manage background processes.
</Note>

## Starting Background Commands

Start a command in the background:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Start background command
    result = sandbox.commands.run(
        'sleep 30 && echo "Done!"',
        background=True
    )

    # Extract process ID from output
    process_id = result.stdout.split('cmd_')[-1].strip() if 'cmd_' in result.stdout else None
    print(f"Process started: {process_id}")
    print(f"Status: {result.stdout}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start background command
    const result = await sandbox.commands.runBackground(
      'sleep 30 && echo "Done!"'
    );

    console.log(`Process started: ${result.processId}`);
    console.log(`Status: ${result.status || 'running'}`);

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Checking Process Status

Check the status of background commands:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import time

    sandbox = Sandbox.create(template="code-interpreter")

    # Start background command
    result = sandbox.commands.run(
        'sleep 30 && echo "Task completed"',
        background=True
    )

    # Extract process ID
    process_id = result.stdout.split('cmd_')[-1].strip() if 'cmd_' in result.stdout else None

    # Check status using list_processes
    for i in range(5):
        processes = sandbox.list_processes()
        for proc in processes:
            if proc.get('process_id') == process_id:
                print(f"Status: {proc['status']}")
                if proc['status'] == 'completed':
                    print(f"Output: {proc.get('stdout', '')}")
                    break
        time.sleep(2)

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start background command
    const result = await sandbox.commands.runBackground(
      'sleep 30 && echo "Task completed"'
    );

    const processId = result.processId;

    // Check status using listProcesses
    for (let i = 0; i < 5; i++) {
      const processes = await sandbox.listProcesses();
      const proc = processes.find(p => p.processId === processId);
      
      if (proc) {
        console.log(`Status: ${proc.status}`);
        if (proc.status === 'completed') {
          console.log(`Output: ${proc.stdout || ''}`);
          break;
        }
      }
      
      await new Promise(resolve => setTimeout(resolve, 2000));
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Long-Running Servers

Start long-running server processes:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import time

    sandbox = Sandbox.create(template="code-interpreter")

    # Start a web server in background
    result = sandbox.commands.run(
        'python -m http.server 8000',
        background=True,
        timeout=3600,  # 1 hour
        env={"PORT": "8000"}
    )

    process_id = result.stdout.split('cmd_')[-1].strip() if 'cmd_' in result.stdout else None
    print(f"Server started: {process_id}")

    # Check if server is running
    time.sleep(2)
    processes = sandbox.list_processes()
    for proc in processes:
        if proc.get('process_id') == process_id:
            print(f"Server status: {proc['status']}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start a web server in background
    const result = await sandbox.commands.runBackground(
      'python -m http.server 8000',
      {
        timeout: 3600,  // 1 hour
        env: { PORT: '8000' }
      }
    );

    console.log(`Server started: ${result.processId}`);

    // Check if server is running
    await new Promise(resolve => setTimeout(resolve, 2000));
    const processes = await sandbox.listProcesses();
    const serverProc = processes.find(p => p.processId === result.processId);
    if (serverProc) {
      console.log(`Server status: ${serverProc.status}`);
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Environment Variables

Pass environment variables to background commands:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Start background command with environment variables
    result = sandbox.commands.run(
        'python -c "import os, time; print(os.getenv(\'API_KEY\')); time.sleep(60)"',
        background=True,
        env={
            "API_KEY": "sk-123456",
            "DEBUG": "true"
        }
    )

    print(f"Process started: {result.stdout}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start background command with environment variables
    const result = await sandbox.commands.runBackground(
      'python -c "import os, time; print(os.getenv(\'API_KEY\')); time.sleep(60)"',
      {
        env: {
          API_KEY: 'sk-123456',
          DEBUG: 'true'
        }
      }
    );

    console.log(`Process started: ${result.processId}`);

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Timeout Configuration

Set timeout for background commands:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Start background command with 10 minute timeout
    result = sandbox.commands.run(
        'long_running_task.sh',
        background=True,
        timeout=600  # 10 minutes
    )

    print(f"Process started with {600}s timeout")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start background command with 10 minute timeout
    const result = await sandbox.commands.runBackground(
      'long_running_task.sh',
      {
        timeout: 600  // 10 minutes
      }
    );

    console.log(`Process started with 600s timeout`);

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Complete Example

Here's a complete example showing background command workflow:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import time

    sandbox = Sandbox.create(template="code-interpreter")

    # Start multiple background tasks
    tasks = {
        'data-processing': 'python process_data.py',
        'ml-training': 'python train_model.py',
        'report-generation': 'python generate_report.py'
    }

    process_ids = {}
    print("🚀 Starting background tasks...\n")

    for name, command in tasks.items():
        result = sandbox.commands.run(
            command,
            background=True,
            timeout=600,
            env={"TASK_NAME": name}
        )
        
        process_id = result.stdout.split('cmd_')[-1].strip() if 'cmd_' in result.stdout else None
        process_ids[name] = process_id
        print(f"✅ Started: {name} (ID: {process_id})")

    # Monitor all processes
    print("\n📊 Monitoring processes...")
    while True:
        all_processes = sandbox.list_processes()
        active = [
            p for p in all_processes 
            if p.get('process_id') in process_ids.values() 
            and p.get('status') in ['queued', 'running']
        ]
        
        if not active:
            break
        
        print(f"\nActive: {len(active)}/{len(tasks)}")
        for proc in active:
            name = next(k for k, v in process_ids.items() if v == proc.get('process_id'))
            print(f"  {name}: {proc['status']}")
        
        time.sleep(3)

    # Show final results
    print("\n📋 Final Status:")
    all_processes = sandbox.list_processes()
    for name, proc_id in process_ids.items():
        proc = next((p for p in all_processes if p.get('process_id') == proc_id), None)
        if proc:
            status_icon = {
                'completed': '✅',
                'failed': '❌',
                'killed': '🛑'
            }.get(proc['status'], '⏳')
            
            print(f"{status_icon} {name}: {proc['status']}")
            if proc['status'] == 'completed' and proc.get('stdout'):
                print(f"   Output: {proc['stdout'].strip()[:50]}...")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Start multiple background tasks
    const tasks = {
      'data-processing': 'python process_data.py',
      'ml-training': 'python train_model.py',
      'report-generation': 'python generate_report.py'
    };

    const processIds = {};
    console.log('🚀 Starting background tasks...\n');

    for (const [name, command] of Object.entries(tasks)) {
      const result = await sandbox.commands.runBackground(command, {
        timeout: 600,
        env: { TASK_NAME: name }
      });
      
      processIds[name] = result.processId;
      console.log(`✅ Started: ${name} (ID: ${result.processId})`);
    }

    // Monitor all processes
    console.log('\n📊 Monitoring processes...');
    while (true) {
      const allProcesses = await sandbox.listProcesses();
      const active = allProcesses.filter(
        p => Object.values(processIds).includes(p.processId) &&
        ['queued', 'running'].includes(p.status)
      );
      
      if (active.length === 0) {
        break;
      }
      
      console.log(`\nActive: ${active.length}/${Object.keys(tasks).length}`);
      for (const proc of active) {
        const name = Object.keys(processIds).find(k => processIds[k] === proc.processId);
        console.log(`  ${name}: ${proc.status}`);
      }
      
      await new Promise(resolve => setTimeout(resolve, 3000));
    }

    // Show final results
    console.log('\n📋 Final Status:');
    const finalProcesses = await sandbox.listProcesses();
    for (const [name, procId] of Object.entries(processIds)) {
      const proc = finalProcesses.find(p => p.processId === procId);
      if (proc) {
        const statusIcon = {
          'completed': '✅',
          'failed': '❌',
          'killed': '🛑'
        }[proc.status] || '⏳';
        
        console.log(`${statusIcon} ${name}: ${proc.status}`);
        if (proc.status === 'completed' && proc.stdout) {
          console.log(`   Output: ${proc.stdout.trim().substring(0, 50)}...`);
        }
      }
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Best Practices

<Steps>
  <Step title="1. Extract Process IDs">
    Extract process IDs from the result to track and manage background commands.
  </Step>

  <Step title="2. Set Appropriate Timeouts">
    Set timeouts based on expected execution time. Default is 30 seconds, but increase for longer tasks.
  </Step>

  <Step title="3. Monitor Status Regularly">
    Check process status periodically to track progress and detect failures early.
  </Step>

  <Step title="4. Use Process Management">
    Use `list_processes()` and `kill_process()` to monitor and control background commands.
  </Step>

  <Step title="5. Handle Failures">
    Check for failed status and access stderr for error details when commands fail.
  </Step>
</Steps>

## Related

* **[Running Commands](/core-concepts/commands/running)** - Execute commands synchronously
* **[Process Monitoring](/core-concepts/observability/processes)** - Monitor background processes
* **SDK**: [sandbox.commands.run\_background()](/sdk/python/commands#run_background) - Python SDK method
* **API**: [POST /commands/background](/api/vm-agent/run-command-background) - VM Agent API endpoint

## Next Steps

* Learn about [Running Commands](/core-concepts/commands/running) for synchronous execution
* Explore [Process Management](/core-concepts/code-execution/process-management) to monitor background processes
* Review [Code Execution](/core-concepts/code-execution/background) for background code execution

## Related

* [CLI Commands](/cli/commands/cmd) - Shell commands from CLI
