<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 10.11.0 -",
    "tvOS: -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/MTLCommandBuffer",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "Metal"
    ],
    "preciseIdentifier" : "c:objc(pl)MTLCommandBuffer"
  },
  "title" : "MTLCommandBuffer"
}
-->

# MTLCommandBuffer

A container that stores a sequence of GPU commands that you encode into it.

```
protocol MTLCommandBuffer : NSObjectProtocol
```

## Overview

A command buffer represents a chunk of work for the GPU that stores the commands you encode to it, as well as any resources those commands need. You primarily use a command buffer to:

- Create command encoders and call their methods to add commands to the buffer
- Optionally reserve a place for the command buffer in its command queue by *enqueuing* the command buffer, even before you encode any commands into it
- Submit, or commit_,_ the contents of the command buffer to the command queue that creates it to run on the GPU device the queue represents

Create a command encoder from an [`MTLCommandQueue`](/documentation/Metal/MTLCommandQueue) instance by calling its [`makeCommandBuffer()`](/documentation/Metal/MTLCommandQueue/makeCommandBuffer()) method. Typically, you create one or more command queues when your app launches and then keep them throughout your app’s lifetime.

To add commands to an [`MTLCommandBuffer`](/documentation/Metal/MTLCommandBuffer) instance, create an encoder from one of its factory methods, including:

- An [`MTLRenderCommandEncoder`](/documentation/Metal/MTLRenderCommandEncoder) instance by calling [`makeRenderCommandEncoder(descriptor:)`](/documentation/Metal/MTLCommandBuffer/makeRenderCommandEncoder(descriptor:))
- An [`MTLComputeCommandEncoder`](/documentation/Metal/MTLComputeCommandEncoder) instance by calling [`makeComputeCommandEncoder(dispatchType:)`](/documentation/Metal/MTLCommandBuffer/makeComputeCommandEncoder(dispatchType:))
- An [`MTLBlitCommandEncoder`](/documentation/Metal/MTLBlitCommandEncoder) instance by calling [`makeBlitCommandEncoder()`](/documentation/Metal/MTLCommandBuffer/makeBlitCommandEncoder()) or [`makeBlitCommandEncoder(descriptor:)`](/documentation/Metal/MTLCommandBuffer/makeBlitCommandEncoder(descriptor:))
- An [`MTLParallelRenderCommandEncoder`](/documentation/Metal/MTLParallelRenderCommandEncoder) instance by calling [`makeParallelRenderCommandEncoder(descriptor:)`](/documentation/Metal/MTLCommandBuffer/makeParallelRenderCommandEncoder(descriptor:))

> Note:
> All encoders inherit additional methods from the ``doc://com.apple.metal/documentation/Metal/MTLCommandEncoder``.

You can use only a single encoder at a time to add commands to a command buffer. To start using a different command encoder, first signal that you’re done with the current encoder by calling its [`endEncoding()`](/documentation/Metal/MTLCommandEncoder/endEncoding()) method. Then create another command encoder from the command buffer and continue adding commands to the buffer with the new encoder.

Repeat the process until you finish encoding commands to the command buffer and are ready to run the buffer’s contents on the GPU. Then submit the command buffer to the command queue that you used to create it by calling the command buffer’s [`commit()`](/documentation/Metal/MTLCommandBuffer/commit()) method. After an app commits a command buffer, you check its [`status`](/documentation/Metal/MTLCommandBuffer/status) property or block a thread by calling its [`waitUntilScheduled()`](/documentation/Metal/MTLCommandBuffer/waitUntilScheduled()) or [`waitUntilCompleted()`](/documentation/Metal/MTLCommandBuffer/waitUntilCompleted()) methods.

You also have the option to reserve a place for the command buffer in its command queue by calling the command buffer’s [`enqueue()`](/documentation/Metal/MTLCommandBuffer/enqueue()) method. You can call this method exactly once at any time before you commit the buffer to the queue. If you don’t enqueue a command buffer, it implicitly enqueues itself when you commit it. Each command queue ensures the order that you enqueue its command buffers is the same order the queue schedules them to run on the GPU.

> Tip:
> Establish an order of execution for multiple command buffers you encode in parallel by first calling their ``doc://com.apple.metal/documentation/Metal/MTLCommandBuffer/enqueue()`` methods in that order.

For example, a multithreaded app might set the GPU’s execution order for a sequence of related subtasks by:

1. Creating a command buffer for each subtask
2. Enqueuing the command buffers in the proper order on a single thread
3. Encoding commands to each buffer on a separate thread and then committing it

## Topics

### Creating command encoders

Create a command encoder from a command buffer that encodes a series of GPU commands to it.

[Command encoder factory methods](/documentation/Metal/command-encoder-factory-methods)

A command encoder defines the actions of a single pass, such as GPU commands that draw, compute, or quickly copy resource data.

### Attaching residency sets

[`useResidencySet(_:)`](/documentation/Metal/MTLCommandBuffer/useResidencySet(_:))

Applies a residency set to a command buffer.

[`useResidencySets(_:)`](/documentation/Metal/MTLCommandBuffer/useResidencySets(_:))

Applies multiple residency sets to a command buffer.

[`useResidencySets:count:`](/documentation/Metal/MTLCommandBuffer/useResidencySets:count:)

Applies multiple residency sets to a command buffer.

### Synchronizing passes with events

Instruct the GPU to wait for an event between two passes until a different command queue’s command buffer signals the event.

[`encodeWaitForEvent(_:value:)`](/documentation/Metal/MTLCommandBuffer/encodeWaitForEvent(_:value:))

Encodes a command into the command buffer that pauses the GPU from running the buffer’s subsequent passes until the event equals or exceeds a value.

[`encodeSignalEvent(_:value:)`](/documentation/Metal/MTLCommandBuffer/encodeSignalEvent(_:value:))

Encodes a command that updates an event’s value, which can clear the GPU to run passes from other command buffers waiting for the event.

### Presenting a drawable

Instruct the command buffer to call a drawable’s presentation method for you at the best time with convenience methods.

[`present(_:)`](/documentation/Metal/MTLCommandBuffer/present(_:))

Presents a drawable as early as possible.

[`present(_:atTime:)`](/documentation/Metal/MTLCommandBuffer/present(_:atTime:))

Presents a drawable at a specific time.

[`present(_:afterMinimumDuration:)`](/documentation/Metal/MTLCommandBuffer/present(_:afterMinimumDuration:))

Presents a drawable after the system presents the previous drawable for an amount of time.

### Registering state change handlers

Notify your app before and after a command buffer runs on the GPU.

[`addScheduledHandler(_:)`](/documentation/Metal/MTLCommandBuffer/addScheduledHandler(_:))

Registers a completion handler the GPU device calls immediately after it schedules the command buffer to run on the GPU.

[`addCompletedHandler(_:)`](/documentation/Metal/MTLCommandBuffer/addCompletedHandler(_:))

Registers a completion handler the GPU device calls immediately after the GPU finishes running the commands in the command buffer.

[`MTLCommandBufferHandler`](/documentation/Metal/MTLCommandBufferHandler)

A completion handler signature a GPU device calls when it finishes scheduling a command buffer, or when the GPU finishes running it.

### Submitting a command buffer

Send a command buffer to run on the GPU, or reserve a place in the queue to arrange its relative order with other command buffers.

[`enqueue()`](/documentation/Metal/MTLCommandBuffer/enqueue())

Reserves the next available place for the command buffer in its command queue.

[`commit()`](/documentation/Metal/MTLCommandBuffer/commit())

Submits the command buffer to run on the GPU.

### Waiting for state changes

Pause your app’s execution on the CPU until the command buffer changes its state.

[`waitUntilScheduled()`](/documentation/Metal/MTLCommandBuffer/waitUntilScheduled())

Blocks the current thread until the command queue schedules the buffer.

[`waitUntilCompleted()`](/documentation/Metal/MTLCommandBuffer/waitUntilCompleted())

Blocks the current thread until the GPU finishes executing the command buffer and all of its completion handlers.

### Troubleshooting a command buffer

[`status`](/documentation/Metal/MTLCommandBuffer/status)

The command buffer’s current state.

[`MTLCommandBufferStatus`](/documentation/Metal/MTLCommandBufferStatus)

The discrete states for a command buffer that represent its life cycle stages.

[Command buffer debugging](/documentation/Metal/command-buffer-debugging)

Properties and methods for programmatically debugging runtime issues with a command buffer.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)