# Build (/docs/template/build)

<!-- agent-signals: reading_time_min: 3 · est_tokens: 1801 · updated: 2026-07-30 -->
Related: [Quickstart](/docs/template/quickstart.md), [How it works](/docs/template/how-it-works.md), [User and workdir](/docs/template/user-and-workdir.md), [Caching](/docs/template/caching.md), [Base image](/docs/template/base-image.md), [Private registries](/docs/template/private-registries.md)

## Build and wait for completion [#build-and-wait-for-completion]

The `build` method builds the template and waits for the build to complete. It returns build information including the template ID and build ID.

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript wrap  
      const buildInfo = await Template.build(template, 'my-template', {
        cpuCount: 2, // CPU cores
        memoryMB: 2048, // Memory in MB
        skipCache: false, // Configure cache skip (except for files)
        onBuildLogs: defaultBuildLogger(), // Log callback receives LogEntry objects
        apiKey: 'your-api-key', // Override API key
        domain: 'your-domain', // Override domain
      })

      // buildInfo contains: { name, templateId, buildId }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python wrap  
      build_info = Template.build(
          template,
          'my-template',
          cpu_count=2,  # CPU cores
          memory_mb=2048,  # Memory in MB
          skip_cache=False,  # Configure cache skip (except for files)
          on_build_logs=default_build_logger(),  # Log callback receives LogEntry objects
          api_key="your-api-key",  # Override API key
          domain="your-domain",  # Override domain
      )

      # build_info contains: BuildInfo(name, template_id, build_id)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

<Note>
  **Disk size is not a per-sandbox setting.** Unlike `cpuCount`/`cpu_count` and `memoryMB`/`memory_mb`, there is no disk-size parameter, neither on the template build nor on `Sandbox.create`. A sandbox's disk size is determined by your team's tier limit and applied when the template is built (see [Build limits](/docs/template/quickstart#build-limits)). `diskSizeMB` only ever appears in API response payloads (for example on sandbox and template info), never as an input. To get a larger disk, raise your tier or contact [support@e2b.dev](mailto:support@e2b.dev).
</Note>

## Build in background [#build-in-background]

The `buildInBackground` method starts the build process and returns immediately without waiting for completion. This is useful when you want to trigger a build and check its status later.

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript wrap  
      const buildInfo = await Template.buildInBackground(template, 'my-template', {
        cpuCount: 2,
        memoryMB: 2048,
      })

      // Returns immediately with: { name, templateId, buildId }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python wrap  
      build_info = Template.build_in_background(
          template,
          'my-template',
          cpu_count=2,
          memory_mb=2048,
      )

      # Returns immediately with: BuildInfo(name, template_id, build_id)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Check build status [#check-build-status]

Use `getBuildStatus` to check the status of a build started with `buildInBackground`.

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript wrap  
      const status = await Template.getBuildStatus(buildInfo, {
        logsOffset: 0, // Optional: offset for fetching logs
      })

      // status contains: { status: 'building' | 'ready' | 'error', logEntries: [...] }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python wrap  
      status = Template.get_build_status(
          build_info,
          logs_offset=0,  # Optional: offset for fetching logs
      )

      # status contains build status and logs
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Example: Background build with status polling [#example-background-build-with-status-polling]

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript wrap  
      // Start build in background
      const buildInfo = await Template.buildInBackground(template, 'my-template', {
        cpuCount: 2,
        memoryMB: 2048,
      })

      // Poll for build status
      let logsOffset = 0
      let status = 'building'

      while (status === 'building') {
        const buildStatus = await Template.getBuildStatus(buildInfo, {
          logsOffset,
        })

        logsOffset += buildStatus.logEntries.length
        status = buildStatus.status

        buildStatus.logEntries.forEach(
          (logEntry) => console.log(logEntry.toString())
        )

        // Wait for a short period before checking the status again
        await new Promise(resolve => setTimeout(resolve, 2000))
      }

      if (status === 'ready') {
        console.log('Build completed successfully')
      } else {
        console.error('Build failed')
      }
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python wrap  
      # Start build in background
      build_info = Template.build_in_background(
          template,
          'my-template',
          cpu_count=2,
          memory_mb=2048,
      )

      # Poll for build status
      import time

      logs_offset = 0
      status = "building"

      while status == "building":
          build_status = Template.get_build_status(
              build_info,
              logs_offset=logs_offset,
          )

          logs_offset += len(build_status.log_entries)
          status = build_status.status.value

          for log_entry in build_status.log_entries:
              print(log_entry)

          # Wait for a short period before checking the status again
          time.sleep(2)

      if status == "ready":
          print("Build completed successfully")
      else:
          print("Build failed")
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>
