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

# MTLResidencySet

A collection of resource allocations that can move in and out of resident memory.

```
protocol MTLResidencySet : NSObjectProtocol
```

## Overview

Residency sets are a way you can tell Metal which resource allocations, such as buffers, textures, and heaps, to make *resident*, or GPU-accessible. Adding allocations to a residency set requires less overhead than the equivalent methods of a command encoder. Residency sets also give you more control when Metal makes their allocations resident, and for how long they remain resident. However, residency sets don’t track hazards, so you need to account for hazards with fences and events.

You can change which [`MTLAllocation`](/documentation/Metal/MTLAllocation) instances are in a residency set at any time by:

1. Staging additions and removals with the [`addAllocation(_:)`](/documentation/Metal/MTLResidencySet/addAllocation(_:)) and [`removeAllocation(_:)`](/documentation/Metal/MTLResidencySet/removeAllocation(_:)) methods, respectively, or with their sibling methods
2. Applying staged changes by calling the residency set’s [`commit()`](/documentation/Metal/MTLResidencySet/commit()) method

Metal doesn’t synchronize the state of the residency set between the CPU and the GPU. This means you can add resource allocations to the set while the GPU is actively running a command buffer that’s accessing them.

> Important:
> If there’s a resource in a residency set that the GPU no longer needs access to,
> you can remove that resource from the residency set,
> even while the GPU is actively accessing other resources from the same residency set.

Metal makes the union of all residency sets’ allocations resident. This means each resource allocation, such as a buffer, can have an entry in multiple residency sets at the same time. Removing an allocation from one residency set doesn’t affect its residency if it also has an entry in another residency set. So you can remove an entire residency set from a command queue and only remove the allocations from residency that are unique to that set. All other resource allocations remain in residency because at least one other residency set has an entry for each.

Alternatively, render and compute command encoders have the following methods that make resource allocations resident:

|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder``                              |``doc://com.apple.metal/documentation/Metal/MTLComputeCommandEncoder``                       |
|---------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/useResource(_:usage:stages:)`` |``doc://com.apple.metal/documentation/Metal/MTLComputeCommandEncoder/useResource(_:usage:)`` |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/useResources(_:usage:stages:)``|``doc://com.apple.metal/documentation/Metal/MTLComputeCommandEncoder/useResources(_:usage:)``|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/useHeap(_:stages:)``           |``doc://com.apple.metal/documentation/Metal/MTLComputeCommandEncoder/useHeap(_:)``           |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/useHeaps(_:stages:)``          |``doc://com.apple.metal/documentation/Metal/MTLComputeCommandEncoder/useHeaps(_:)``          |

These command encoder methods:

- Support hazard tracking to applicable resources (see [Resource fundamentals](/documentation/Metal/resource-fundamentals))
- Require CPU overhead for each resource or heap, which scale up with each one you add
- Apply to a single command encoder, which means you need to call the methods again for the same resources for each command encoder

Residency sets, by contrast:

- Don’t support hazard tracking, which means you need to account for hazards with [`MTLFence`](/documentation/Metal/MTLFence) and [`MTLEvent`](/documentation/Metal/MTLEvent) instances
- Require minimal CPU overhead by aggregating allocations at little to no cost for each resource or heap
- Can attach to a command buffer with a single call, which makes residency set’s allocations available to all of that command buffer’s encoders
- Can attach to a command queue with a single call

Metal attaches all of a command queue’s residency sets to a command buffer from that queue when you call the command buffer’s [`commit()`](/documentation/Metal/MTLCommandBuffer/commit()) method.

> Important:
> Residency sets don’t support sparse heaps or sparse textures, and their methods aren’t thread-safe.

See [Simplifying GPU resource management with residency sets](/documentation/Metal/simplifying-gpu-resource-management-with-residency-sets) for information about associating a residency set to command buffers and command queues.

### Create a residency set

Make a residency set by configuring an [`MTLResidencySetDescriptor`](/documentation/Metal/MTLResidencySetDescriptor) instance and passing it to the [`makeResidencySet(descriptor:)`](/documentation/Metal/MTLDevice/makeResidencySet(descriptor:)) method of an [`MTLDevice`](/documentation/Metal/MTLDevice).

```swift
let setDescriptor = MTLResidencySetDescriptor()
setDescriptor.label = "Primary residency set"
setDescriptor.initialCapacity = 42

let residencySet = try device.makeResidencySet(descriptor: setDescriptor)
```

### Add allocations to a residency set

Add individual resource allocations to a residency set by calling [`addAllocation(_:)`](/documentation/Metal/MTLResidencySet/addAllocation(_:)), or add multiple allocations with [`addAllocations(_:)`](/documentation/Metal/MTLResidencySet/addAllocations(_:)).

```swift
let residencySet = try device.makeResidencySet(descriptor: setDescriptor)

residencySet.addAllocation(buffer0)
residencySet.addAllocation(buffer1)
residencySet.addAllocation(texture0)
residencySet.addAllocation(texture1)
residencySet.addAllocation(heap)

let allocations = [buffer2,
                   texture2,
                   argumentBufferHeap,
                   textureHeap]

residencySet.addAllocations(allocations)
```

The residency set can handle redundant entries for the same allocation because it ignores duplicates that already have an entry in the set.

> Important:
> Adding a resource, such as a buffer or texture, that originates from a heap to a residency set makes its entire heap resident.

### Remove allocations from a residency set

Remove individual resource allocations from a residency set by calling [`removeAllocation(_:)`](/documentation/Metal/MTLResidencySet/removeAllocation(_:)), or remove multiple allocations with [`removeAllocations(_:)`](/documentation/Metal/MTLResidencySet/removeAllocations(_:)).

```swift
residencySet.removeAllocation(buffer1)
residencySet.removeAllocations( [argumentBufferHeap, textureHeap] )
```

Like the methods that add resource allocations to the set, these methods aggregate removals with little CPU overhead. So you can call the methods multiple times without adversely affecting runtime performance.

### Commit the changes to a residency set

Apply the updates to a residency set by calling its [`commit()`](/documentation/Metal/MTLResidencySet/commit()) method.

```objective-c
residencySet.commit()
```

A residency set’s addition and removal methods don’t take effect until you call this method.

## Topics

### Adding allocations

Add allocation instances, including buffers, textures, and heaps, to a residency set.

[`addAllocation(_:)`](/documentation/Metal/MTLResidencySet/addAllocation(_:))

Stages a single resource to join the residency set’s list of allocations.

[`addAllocations(_:)`](/documentation/Metal/MTLResidencySet/addAllocations(_:))

Stages multiple resources to join the residency set’s list of allocations.

[`addAllocations:count:`](/documentation/Metal/MTLResidencySet/addAllocations:count:)

Stages multiple resources to join the residency set’s list of allocations.

### Removing allocations

Remove allocation instances, including buffers, textures, and heaps, from a residency set.

[`removeAllAllocations()`](/documentation/Metal/MTLResidencySet/removeAllAllocations())

Stages all the resources in the residency set to leave its list of allocations.

[`removeAllocation(_:)`](/documentation/Metal/MTLResidencySet/removeAllocation(_:))

Stages a single resource to leave the residency set’s list of allocations.

[`removeAllocations(_:)`](/documentation/Metal/MTLResidencySet/removeAllocations(_:))

Stages multiple resources to leave the residency set’s list of allocations.

[`removeAllocations:count:`](/documentation/Metal/MTLResidencySet/removeAllocations:count:)

Stages multiple resources to leave the residency set’s list of allocations.

### Finalizing pending allocation changes

Complete the additions and removals since the last commit.

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

Applies any pending additions to and removals from the residency set.

### Requesting residency for the allocations

Ask Metal to make the residency set’s allocations resident.

[`requestResidency()`](/documentation/Metal/MTLResidencySet/requestResidency())

Tells Metal to do as much preparatory work as it can, with the system’s current conditions, to make the set’s resource allocations resident.

### Releasing the allocations from residency

Notify Metal that you no longer need the residency set’s allocations to be resident so it can reallocate the underlying memory.

[`endResidency()`](/documentation/Metal/MTLResidencySet/endResidency())

Informs Metal that the residency set’s allocations no longer need to be resident, and that it can reuse the memory for other allocations.

### Inspecting a residency set

Identify a residency and check its current allocations and memory footprint.

[`label`](/documentation/Metal/MTLResidencySet/label)

An optional name that can help you identify the residency set.

[`device`](/documentation/Metal/MTLResidencySet/device)

The Metal device that owns the residency set.

[`containsAllocation(_:)`](/documentation/Metal/MTLResidencySet/containsAllocation(_:))

Returns a Boolean value that indicates whether the residency set contains a specific resource allocation.

[`allAllocations`](/documentation/Metal/MTLResidencySet/allAllocations)

The residency set’s current list of resource allocations.

[`allocationCount`](/documentation/Metal/MTLResidencySet/allocationCount)

The number of resource allocations in the residency set.

[`allocatedSize`](/documentation/Metal/MTLResidencySet/allocatedSize)

The amount of resident memory, in bytes, the residency set’s resource allocations consume.



---

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)