Compute Engine offers predefined machine types that you can use when
you create a VM instance. A predefined machine type has a preset number of vCPUs
and amount of memory and has a set price. If predefined VMs don't
meet your needs, you can create a VM instance with custom virtualized hardware
settings. Specifically, you can create a VM instance with a custom number of
vCPUs and amount of memory, effectively using a custom machine type. Custom
machine types are available for the following:

- [General-purpose machine family](https://docs.cloud.google.com/compute/docs/general-purpose-machines) for the N and E machine series only. You can create a custom VM on the N4, N4D, N4A, N2, N2D, E2, or N1 machine series.
- [Accelerator-optimized machine
  family](https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines) for the G2 machine series only.

Custom VMs are ideal in the following scenarios:

- Workloads that aren't a good fit for the predefined VM types.
- Workloads that require more processing power or more memory but don't need all the upgrades that the next-level machine type provides.
- Workloads that have per-CPU software license costs, where you can customize the number of vCPUs to avoid license costs for unused processing power or to match available software license counts.

## Before you begin

- Read the [machine families](https://docs.cloud.google.com/compute/docs/machine-resource) documentation.
- If you haven't already, set up [authentication](https://docs.cloud.google.com/compute/docs/authentication). Authentication verifies your identity for access to Google Cloud services and APIs. To run code or samples from a local development environment, you can authenticate to Compute Engine by selecting one of the following options:

  Select the tab for how you plan to use the samples on this page:

  ### Console


  When you use the Google Cloud console to access Google Cloud services and
  APIs, you don't need to set up authentication.

  ### gcloud

  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

     After installation,
     [initialize](https://docs.cloud.google.com/sdk/docs/initializing) the Google Cloud CLI by running the following command:

     ```bash
     gcloud init
     ```


     If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

     > [!NOTE]
     > **Note:** If you installed the gcloud CLI previously, make sure you have the latest version by running `gcloud components update`.

  2. [Set a default region and zone](https://docs.cloud.google.com/compute/docs/gcloud-compute#set_default_zone_and_region_in_your_local_client).

  ### Terraform


  To use the Terraform samples on this page in a local development environment, install and
  initialize the gcloud CLI, and then set up Application Default Credentials with
  your user credentials.
  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

  3.

     If you're using a local shell, then create local authentication credentials for your user
     account:

     ```bash
     gcloud auth application-default login
     ```

     You don't need to do this if you're using Cloud Shell.


     If an authentication error is returned, and you are using an external identity provider
     (IdP), confirm that you have
     [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Set up authentication for a local development environment](https://docs.cloud.google.com/compute/docs/authentication#local-development).

  ### Go


  To use the Go samples on this page in a local development environment, install and
  initialize the gcloud CLI, and then set up Application Default Credentials with
  your user credentials.
  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

  3.

     If you're using a local shell, then create local authentication credentials for your user
     account:

     ```bash
     gcloud auth application-default login
     ```

     You don't need to do this if you're using Cloud Shell.


     If an authentication error is returned, and you are using an external identity provider
     (IdP), confirm that you have
     [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Set up authentication for a local development environment](https://docs.cloud.google.com/compute/docs/authentication#local-development).

  ### Java


  To use the Java samples on this page in a local development environment, install and
  initialize the gcloud CLI, and then set up Application Default Credentials with
  your user credentials.
  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

  3.

     If you're using a local shell, then create local authentication credentials for your user
     account:

     ```bash
     gcloud auth application-default login
     ```

     You don't need to do this if you're using Cloud Shell.


     If an authentication error is returned, and you are using an external identity provider
     (IdP), confirm that you have
     [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Set up authentication for a local development environment](https://docs.cloud.google.com/compute/docs/authentication#local-development).

  ### Node.js


  To use the Node.js samples on this page in a local development environment, install and
  initialize the gcloud CLI, and then set up Application Default Credentials with
  your user credentials.
  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

  3.

     If you're using a local shell, then create local authentication credentials for your user
     account:

     ```bash
     gcloud auth application-default login
     ```

     You don't need to do this if you're using Cloud Shell.


     If an authentication error is returned, and you are using an external identity provider
     (IdP), confirm that you have
     [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Set up authentication for a local development environment](https://docs.cloud.google.com/compute/docs/authentication#local-development).

  ### Python


  To use the Python samples on this page in a local development environment, install and
  initialize the gcloud CLI, and then set up Application Default Credentials with
  your user credentials.
  1.
     [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first
     [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

  3.

     If you're using a local shell, then create local authentication credentials for your user
     account:

     ```bash
     gcloud auth application-default login
     ```

     You don't need to do this if you're using Cloud Shell.


     If an authentication error is returned, and you are using an external identity provider
     (IdP), confirm that you have
     [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Set up authentication for a local development environment](https://docs.cloud.google.com/compute/docs/authentication#local-development).

  ### REST


  To use the REST API samples on this page in a local development environment, you use the
  credentials you provide to the gcloud CLI.
  1. [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.
  2. If you're using an external identity provider (IdP), you must first [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


  For more information, see
  [Authenticate for using REST](https://docs.cloud.google.com/docs/authentication/rest)
  in the Google Cloud authentication documentation.

### Required roles


To get the permissions that
you need to create a VM with a custom machine type,

ask your administrator to grant you the
[Compute Instance Admin (v1)](https://docs.cloud.google.com/iam/docs/roles-permissions/compute#compute.instanceAdmin.v1) (`roles/compute.instanceAdmin.v1`) IAM role on the project.


For more information about granting roles, see [Manage access to projects, folders, and organizations](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access).


This predefined role contains

the permissions required to create a VM with a custom machine type. To see the exact permissions that are
required, expand the **Required permissions** section:


#### Required permissions

The following permissions are required to create a VM with a custom machine type:

- To add extended memory to an existing VM: `compute.instances.setMachineType` on the VM
- To create a VM with a custom machine type:
  - `compute.instances.create` on the project
  - To use a custom image to create the VM: `compute.images.useReadOnly` on the image
  - To use a snapshot to create the VM: `compute.snapshots.useReadOnly` on the snapshot
  - To use an instance template to create the VM: `compute.instanceTemplates.useReadOnly` on the instance template
  - To assign a [legacy network](https://docs.cloud.google.com/vpc/docs/legacy) to the VM: `compute.networks.use` on the project
  - To specify a static IP address for the VM: `compute.addresses.use` on the project
  - To assign an external IP address to the VM when using a legacy network: `compute.networks.useExternalIp` on the project
  - To specify a subnet for the VM: `compute.subnetworks.use` on the project or on the chosen subnet
  - To assign an external IP address to the VM when using a VPC network: `compute.subnetworks.useExternalIp` on the project or on the chosen subnet
  - To set VM instance metadata for the VM: `compute.instances.setMetadata` on the project
  - To set tags for the VM: `compute.instances.setTags` on the VM
  - To set labels for the VM: `compute.instances.setLabels` on the VM
  - To set a service account for the VM to use: `compute.instances.setServiceAccount` on the VM
  - To create a new disk for the VM: `compute.disks.create` on the project
  - To attach an existing disk in read-only or read-write mode: `compute.disks.use` on the disk
  - To attach an existing disk in read-only mode: `compute.disks.useReadOnly` on the disk


You might also be able to get
these permissions
with [custom roles](https://docs.cloud.google.com/iam/docs/creating-custom-roles) or
other [predefined roles](https://docs.cloud.google.com/iam/docs/roles-overview#predefined).

## Limitations

- If your VM has Local SSD disks, you can't change the vCPU and memory configuration.
- Extended memory is available on N4, N4A, N4D, N2, N2D, and N1 custom machine
  types. For the limits on extended memory, see
  [Add extended memory to a machine type](https://docs.cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#extendedmemory).

  Predefined machine types, as well as G2 and E2 custom machine types, don't
  support extended memory.
- Extended memory doesn't qualify for
  [resource-based committed use discounts](https://docs.cloud.google.com/compute/docs/instances/committed-use-discounts-overview#resource_based).

- Each machine type has specific ranges and values for vCPUs and memory, as
  shown in the following table:

| Machine series | Min vCPUs | Max vCPUs | Allowed vCPUs | Min memory per vCPU (GB) | Max memory per vCPU (GB) | Step size (MB) | Extended memory |
|---|---|---|---|---|---|---|---|
| N4 | 2 | 80 | Any multiple of 2 | 2 | 8 | 256 | Yes |
| N4D | 2 | 96 | 2, 4, 8, 16, 32, 48, 64, 80, 96 | 0.5 | 8 | 256 | Yes |
| N4A | 1 | 64 | Any | 2 | 8 | 256 | Yes |
| N2 | 2 | 80 | Multiples of 2 (up to 32) or 4 (32 to 80) | 0.5 | 8 | 256 | Yes |
| N2D | 2 | 96 | 2, 4, 8, 16, 32, 48, 64, 80, 96 | 0.5 | 8 | 256 | Yes |
| N1 | 1 | 96 | 1 or any multiple of 2 | 0.9 (1 for 1 or 2 vCPUs) | 6.5 | 256 | Yes |
| E2 | 2 | 32 | Any multiple of 2 | 0.5 | 8 | 256 | No |
| E2 shared-core | 0.25 | 1 | 0.25, 0.5, 1 | 1 total | 8 (2 total for micro, 4 total for small, 8 total for medium) | 256 | No |

> [!NOTE]
> **Note:** G2 (NVIDIA L4) lets you customize vCPUs (4, 8, 12, 16, or 32) when Number of GPUs is 1, whereas for 2, 4, or 8 L4 GPUs the vCPU count is fixed (24, 48, or 96) and only memory is customizable. For the vCPU and custom memory ranges for G2 VMs, see [G2 machine types](https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines#g2-standard-vms).

## Express memory in GB or MB

For historical reasons, Google Cloud tools and documentation refer to machine
type memory as decimal megabytes (MB) and gigabytes (GB). However, these units
represent binary [gibibytes (GiB)](https://wikipedia.org/wiki/Gibibyte) and
mebibytes (MiB), where 1 GB is 2^30^ bytes, or
1,024 MB.

When you configure memory for a custom machine type, the unit requirements and
conversions depend on the tool that you use:

- In the Google Cloud console, you specify memory in GB. For example, if your system needs 1,024 MB of memory, select 1 GB in the Google Cloud console.
- In the Compute Engine API, you must provide memory in MB as an integer multiple of 256 MB (or 1,024 MB for G2 VMs). For example, if you try to provision 5 GB of memory by specifying 5,000 MB in an API request, the API returns an error because 5,000 isn't a multiple of 256 (5 GB is 5,120 MB).
- In the Google Cloud CLI, you can provide the total memory for a VM in GB or MB:
  - The `--custom-memory` flag defaults to GB if you omit the unit. To specify memory in MB, you must include the `MB` unit suffix. For example, if you want 2,048 MB (2 GB) of memory and specify the `--custom-memory=2048` flag without a unit, the gcloud CLI requests 2,048 GB of memory instead of 2,048 MB.
  - Unitless values passed to `--custom-memory` must be integers. To express 0.25 GB (256 MB) increments such as 5.75 GB, either convert the value to an integer in MB (`--custom-memory=5888MB`) or include the `GB` unit suffix (`--custom-memory=5.75GB`).
  - With the `--machine-type` flag, you must specify memory in MB as an integer without a unit suffix---for example, `--machine-type=n2-custom-2-5120`.

## Custom machine type pricing

Compute Engine charges for custom VMs based on the number of vCPUs and
memory hours that the VM uses. This pricing model differs from how
Compute Engine charges for predefined machine types. The on-demand
prices for custom machine types include a 5% premium over the on-demand prices
for predefined machine types.

- When you use a custom machine type, any memory up to and including the default
  amount per vCPU is charged at the machine family custom machine type pricing.
  E2 custom machine and E2 shared-core custom machine types share the same
  pricing scheme.

- If you use your
  [commitments](https://docs.cloud.google.com/compute/docs/instances/signing-up-committed-use-discounts)
  to run custom machine types, then Compute Engine charges a 5%
  premium over the commitment prices. Compute Engine charges this
  premium for the portion and duration of your commitment that you run these
  custom machine type VMs.

To view pricing information by machine series, see
[VM instance pricing](https://docs.cloud.google.com/compute/vm-instance-pricing).

Custom VMs are subject to the same 1-minute minimum charge as any other
instance, but sustained use discounts for custom
machine types are calculated differently. For more information, see
[sustained use discounts](https://docs.cloud.google.com/compute/docs/sustained-use-discounts)
for custom VMs.

### Extended memory pricing

Compute Engine charges extra for memory above the range maximum for
the number of vCPUs configured as extended memory, based on the machine family
extended custom memory pricing. The price for extended memory is higher than
the price for memory below the range maximum.

> [!NOTE]
> **Note:** When you use resource-based committed use discounts, it's often more cost-effective to use a VM shape with excess vCPUs (potentially disabled by using visible cores) than to use extended memory.

Extended memory prices differ depending on the region. Instances running with
extended memory are subject to the same 1-minute minimum charge as any other
instance. Extended memory doesn't qualify for resource-based committed use
discounts, but it does qualify for
[compute flexible committed use discounts](https://docs.cloud.google.com/compute/docs/instances/committed-use-discounts-overview#spend_based)
and [sustained use discounts](https://docs.cloud.google.com/compute/docs/sustained-use-discounts).

## Add extended memory to a machine type

Each custom machine type machine series has a default RAM maximum per vCPU. For
some workloads, this default maximum might not be enough memory per vCPU. For a
premium, you can get more memory per vCPU beyond the default maximum up to the
machine series limit, which is called *extended memory*. The following
table lists the vCPU and extended memory limits for each supported machine
series:

| Machine series | vCPU limit | Memory limit |
|---|---|---|
| N4 | 80 | 640 GB |
| N4D | 96 | 768 GB |
| N4A | 64 | 512 GB |
| N2 | 80 | 864 GB |
| N2D | 96 | 768 GB |
| N1 | 96 | 624 GB |

For higher RAM-to-vCPU ratios, see also the
[memory-optimized machine types](https://docs.cloud.google.com/compute/docs/memory-optimized-machines).

### Determine whether you need extended memory

Certain workloads need more than the default amount of memory per vCPU to
deliver optimum results. Workloads that are based on in-memory high-performance
analytics databases, including relational and NoSQL databases such as Microsoft
SQL Server, MongoDB, and Memcached or Redis, are in this category. The
vCPU-based licensing of operating systems and software stacks also makes
selecting an optimal VM memory configuration more challenging with predefined
machine types. By using extended memory, you can add as much memory as your VMs
need for the best price-performance ratio.

## Create a VM with a custom machine type

Before you create a custom VM instance, read the [custom specifications](https://docs.cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types) for creating this machine type.

<br />

### Console

1. In the Google Cloud console, go to the **Create an instance** page.

   [Go to Create an instance](https://console.cloud.google.com/compute/instancesAdd)
2. In the **Machine configuration** pane, do the following:

   1. Select the **Region** and **Zone** where you want to host the instance.
   2. Select the machine configuration for your instance:
      - To create a general-purpose custom VM, select **General purpose** , and then in the **Series** section, select **N4** , **N4A** , **N4D** , **N2** , **N2D** , **E2** , or **N1**.
      - To create a custom VM with attached GPUs, select **GPUs** , and then do the following:
        1. In the **GPU type** list, select a GPU for the machine series that you want to use:
           - For G2 VMs, select **NVIDIA L4**.
           - For N1 VMs, select **NVIDIA T4** , **NVIDIA V100** , or **NVIDIA Tesla P4**.
        2. In the **Number of GPUs** list, select the number of GPUs.
   3. In the **Machine type** section, select **Custom**.
   4. To specify the number of vCPUs and the amount of memory for the instance, drag the **Cores** and **Memory** sliders or enter the values in the fields. The console displays an estimated cost for the instance as you change the number of vCPUs and amount of memory.
3. Optional: Specify other configuration options. For more information, see
   [Configuration options during instance creation](https://docs.cloud.google.com/compute/docs/instances/instance-creation-overview#new-instance-configuration-options).

4. To create and start the instance, click **Create**.

### gcloud

Create a custom machine type by using the
[`gcloud compute instances create`
command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/create) with the
`--machine-type` flag:

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB

Replace the following:

- `INSTANCE_NAME`: the name of the instance.
- `ZONE`: the zone where you want to create the instance.
- `MACHINE_SERIES`: the lowercase machine series, such as `n4`, `n4d`, `n4a`, `n2`, `n2d`, `e2`, or `g2`. For N1, omit `MACHINE_SERIES-` and start with `custom-`.
- `NUMBER_OF_VCPUS`: the number of vCPUs.
- `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB (or 1,024 MB for G2 VMs).

To create a G2 VM with 4 vCPUs and 19 GB of memory in zone
`us-central1-a`, run the following command:

    gcloud compute instances create example-instance \
        --zone=us-central1-a \
        --machine-type=g2-custom-4-19456 \
        --maintenance-policy=TERMINATE

For G2 VMs, memory must be a multiple of 1,024 MB and within the
[supported memory
range](https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines#g2-standard-vms). For
more information about creating G2 VMs, see [Create a G2 or G4
instance](https://docs.cloud.google.com/compute/docs/gpus/create-gpu-vm-g-series#create-vm).

The following example creates an N2 custom machine type with 48 vCPUs and
310 GB (317,440 MB) of memory in zone `us-central1-a`:

    gcloud compute instances create example-instance \
        --zone=us-central1-a \
        --machine-type=n2-custom-48-317440

For supported machine series, such as N4 or N2, you can configure extended
memory, which lets you specify a higher amount of memory than the maximum
default ratio of memory to vCPUs. To configure extended memory, increase the
value of `AMOUNT_OF_MEMORY_MB` and append `-ext` to
the machine type name---for example, `--machine-type=n2-custom-48-720896-ext`.

Alternatively, you can specify a custom machine type by using the
`--custom-cpu`, `--custom-memory`, and `--custom-vm-type` flags (and
include the `--custom-extensions` flag if you're configuring extended
memory):

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --custom-cpu=NUMBER_OF_VCPUS \
        --custom-memory=AMOUNT_OF_MEMORY \
        --custom-vm-type=MACHINE_SERIES

Replace the following:

- `INSTANCE_NAME`: the name of the instance.
- `ZONE`: the zone where you want to create the instance.
- `NUMBER_OF_VCPUS`: the number of vCPUs.
- `AMOUNT_OF_MEMORY`: the total amount of memory with a unit suffix (`MB` or `GB`), or in GB if you omit the unit.
- `MACHINE_SERIES`: the lowercase machine series, such as `n4`, `n4d`, `n4a`, `n2`, `n2d`, `e2`, or `n1`.

The following example creates an N2 custom machine type with 48 vCPUs and
310 GB of memory by using the `--custom-cpu`, `--custom-memory`, and
`--custom-vm-type` flags:

    gcloud compute instances create example-instance \
        --zone=us-central1-a \
        --custom-cpu=48 \
        --custom-memory=317440MB \
        --custom-vm-type=n2

When you use the `--custom-memory` flag, specify the total amount of
memory in GB or in MB. Unitless values must be integers. To specify
increments of 0.25 GB (256 MB) for memory, either convert the total memory
to an integer in MB (`--custom-memory=5888MB`) or include the `GB` unit
suffix (`--custom-memory=5.75GB`).

For E2 shared-core custom machine types, use the
[`gcloud compute instances create`
command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/create) and include the
shared-core machine size (`micro`, `small`, or `medium`):

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --machine-type=e2-custom-SHARED_CORE_SIZE-AMOUNT_OF_MEMORY_MB

Replace the following:

- `INSTANCE_NAME`: the name of the instance.
- `ZONE`: the zone where you want to create the instance.
- `SHARED_CORE_SIZE`: the E2 shared-core size (`micro`, `small`, or `medium`).
- `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB within the allowed range for the shared-core size.

The following example creates an E2 shared-core `small` custom machine type
with 0.5 vCPU and 2.25 GB (2,304 MB) of memory:

    gcloud compute instances create example-instance \
        --zone=us-central1-a \
        --machine-type=e2-custom-small-2304

### Terraform

To generate the Terraform code, you can use the **Equivalent code** component in the Google Cloud console.

1. In the Google Cloud console, go to the **VM instances** page.

   [Go to VM Instances](https://console.cloud.google.com/compute/instances)
2. Click **Create instance**.
3. Specify the parameters you want.
4. At the top or bottom of the page, click **Equivalent code** , and then click the **Terraform** tab to view the Terraform code.

### Go


Before trying this sample, follow the Go setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Go API
reference documentation](https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    import (
    	"context"
    	"fmt"
    	"io"

    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "cloud.google.com/go/compute/apiv1/computepb"
    	"google.golang.org/protobuf/proto"
    )

    func customMachineTypeURI(zone, cpuSeries string, coreCount, memory int) (string, error) {
    	const (
    		n1       = "custom"
    		n2       = "n2-custom"
    		n2d      = "n2d-custom"
    		e2       = "e2-custom"
    		e2Micro  = "e2-custom-micro"
    		e2Small  = "e2-custom-small"
    		e2Medium = "e2-custom-medium"
    	)

    	type typeLimit struct {
    		allowedCores     []int
    		minMemPerCore    int
    		maxMemPerCore    int
    		allowExtraMemory bool
    		extraMemoryLimit int
    	}

    	makeRange := func(start, end, step int) []int {
    		if step <= 0 || end < start {
    			return []int{}
    		}
    		s := make([]int, 0, 1+(end-start)/step)
    		for start <= end {
    			s = append(s, start)
    			start += step
    		}
    		return s
    	}

    	containsString := func(s []string, str string) bool {
    		for _, v := range s {
    			if v == str {
    				return true
    			}
    		}

    		return false
    	}

    	containsInt := func(nums []int, n int) bool {
    		for _, v := range nums {
    			if v == n {
    				return true
    			}
    		}

    		return false
    	}

    	var (
    		cpuSeriesE2Limit = typeLimit{
    			allowedCores:  makeRange(2, 33, 2),
    			minMemPerCore: 512,
    			maxMemPerCore: 8192,
    		}
    		cpuSeriesE2MicroLimit  = typeLimit{minMemPerCore: 1024, maxMemPerCore: 2048}
    		cpuSeriesE2SmallLimit  = typeLimit{minMemPerCore: 2048, maxMemPerCore: 4096}
    		cpuSeriesE2MeidumLimit = typeLimit{minMemPerCore: 4096, maxMemPerCore: 8192}
    		cpuSeriesN2Limit       = typeLimit{
    			allowedCores:  append(makeRange(2, 33, 2), makeRange(36, 129, 4)...),
    			minMemPerCore: 512, maxMemPerCore: 8192,
    			allowExtraMemory: true,
    			extraMemoryLimit: 624 << 10,
    		}
    		cpuSeriesN2DLimit = typeLimit{
    			allowedCores:  []int{2, 4, 8, 16, 32, 48, 64, 80, 96},
    			minMemPerCore: 512, maxMemPerCore: 8192,
    			allowExtraMemory: true,
    			extraMemoryLimit: 768 << 10,
    		}
    		cpuSeriesN1Limit = typeLimit{
    			allowedCores:     append([]int{1}, makeRange(2, 97, 2)...),
    			minMemPerCore:    922,
    			maxMemPerCore:    6656,
    			allowExtraMemory: true,
    			extraMemoryLimit: 624 << 10,
    		}
    	)

    	typeLimitsMap := map[string]typeLimit{
    		n1:       cpuSeriesN1Limit,
    		n2:       cpuSeriesN2Limit,
    		n2d:      cpuSeriesN2DLimit,
    		e2:       cpuSeriesE2Limit,
    		e2Micro:  cpuSeriesE2MicroLimit,
    		e2Small:  cpuSeriesE2SmallLimit,
    		e2Medium: cpuSeriesE2MeidumLimit,
    	}

    	if !containsString([]string{e2, n1, n2, n2d}, cpuSeries) {
    		return "", fmt.Errorf("incorrect cpu type: %v", cpuSeries)
    	}

    	tl := typeLimitsMap[cpuSeries]

    	// Check whether the requested parameters are allowed.
    	// Find more information about limitations of custom machine types at:
    	// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

    	// Check the number of cores
    	if len(tl.allowedCores) > 0 && !containsInt(tl.allowedCores, coreCount) {
    		return "", fmt.Errorf(
    			"invalid number of cores requested. Allowed number of cores for %v is: %v",
    			cpuSeries,
    			tl.allowedCores,
    		)
    	}

    	// Memory must be a multiple of 256 MB
    	if memory%256 != 0 {
    		return "", fmt.Errorf("requested memory must be a multiple of 256 MB")
    	}

    	// Check if the requested memory isn't too little
    	if memory < coreCount*tl.minMemPerCore {
    		return "", fmt.Errorf(
    			"requested memory is too low. Minimal memory for %v is %v MB per core",
    			cpuSeries,
    			tl.minMemPerCore,
    		)
    	}

    	// Check if the requested memory isn't too much
    	if memory > coreCount*tl.maxMemPerCore && !tl.allowExtraMemory {
    		return "", fmt.Errorf(
    			"requested memory is too large.. Maximum memory allowed for %v is %v MB per core",
    			cpuSeries,
    			tl.maxMemPerCore,
    		)
    	}
    	if memory > tl.extraMemoryLimit && tl.allowExtraMemory {
    		return "", fmt.Errorf(
    			"requested memory is too large.. Maximum memory allowed for %v is %v MB",
    			cpuSeries,
    			tl.extraMemoryLimit,
    		)
    	}

    	// Return the custom machine type in form of a string acceptable by Compute Engine API.
    	if containsString([]string{e2Small, e2Micro, e2Medium}, cpuSeries) {
    		return fmt.Sprintf("zones/%v/machineTypes/%v-%v", zone, cpuSeries, memory), nil
    	}

    	if memory > coreCount*tl.maxMemPerCore {
    		return fmt.Sprintf(
    			"zones/%v/machineTypes/%v-%v-%v-ext",
    			zone,
    			cpuSeries,
    			coreCount,
    			memory,
    		), nil
    	}

    	return fmt.Sprintf("zones/%v/machineTypes/%v-%v-%v", zone, cpuSeries, coreCount, memory), nil
    }

    // createInstanceWithCustomMachineTypeWithHelper creates a new VM instance with a custom machine type.
    func createInstanceWithCustomMachineTypeWithHelper(
    	w io.Writer,
    	projectID, zone, instanceName, cpuSeries string,
    	coreCount, memory int,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// cpuSeries := "e2-custom-micro" // the type of CPU you want to use"
    	// coreCount := 2 // number of CPU cores you want to use.
    	// memory := 256 // the amount of memory for the VM instance, in megabytes.

    	machineType, err := customMachineTypeURI(zone, cpuSeries, coreCount, memory)
    	if err != nil {
    		return fmt.Errorf("unable to create custom machine type string: %w", err)
    	}

    	ctx := context.Background()
    	instancesClient, err := compute.https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1.html#cloud_google_com_go_compute_apiv1_InstancesClient_NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()

    	req := &computepb.InsertInstanceRequest{
    		Project: projectID,
    		Zone:    zone,
    		InstanceResource: &computepb.Instance{
    			Name: proto.String(instanceName),
    			Disks: []*computepb.AttachedDisk{
    				{
    					InitializeParams: &computepb.AttachedDiskInitializeParams{
    						DiskSizeGb: proto.Int64(10),
    						SourceImage: proto.String(
    							"projects/debian-cloud/global/images/family/debian-12",
    						),
    					},
    					AutoDelete: proto.Bool(true),
    					Boot:       proto.Bool(true),
    				},
    			},
    			MachineType: proto.String(machineType),
    			NetworkInterfaces: []*computepb.NetworkInterface{
    				{
    					Name: proto.String("global/networks/default"),
    				},
    			},
    		},
    	}

    	op, err := instancesClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create instance: %w", err)
    	}

    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}

    	fmt.Fprintf(w, "Instance created\n")

    	return nil
    }

### Java


Before trying this sample, follow the Java setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Java API
reference documentation](https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/overview).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).


    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDiskInitializeParams.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.NetworkInterface.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html;
    import com.google.common.collect.ImmutableMap;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Map;
    import java.util.Objects;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    import java.util.stream.IntStream;

    public class CreateWithHelper {

      // This class defines the configurable parameters for a custom VM.
      static final class TypeLimits {

        int[] allowedCores;
        int minMemPerCore;
        int maxMemPerCore;
        int extraMemoryLimit;
        boolean allowExtraMemory;

        TypeLimits(int[] allowedCores, int minMemPerCore, int maxMemPerCore, boolean allowExtraMemory,
            int extraMemoryLimit) {
          this.allowedCores = allowedCores;
          this.minMemPerCore = minMemPerCore;
          this.maxMemPerCore = maxMemPerCore;
          this.allowExtraMemory = allowExtraMemory;
          this.extraMemoryLimit = extraMemoryLimit;
        }
      }

      public enum CpuSeries {
        N1("custom"),
        N2("n2-custom"),
        N2D("n2d-custom"),
        E2("e2-custom"),
        E2_MICRO("e2-custom-micro"),
        E2_SMALL("e2-custom-small"),
        E2_MEDIUM("e2-custom-medium");

        private static final Map<String, CpuSeries> ENUM_MAP;

        static {
          ENUM_MAP = init();
        }

        // Build an immutable map of String name to enum pairs.
        public static Map<String, CpuSeries> init() {
          Map<String, CpuSeries> map = new ConcurrentHashMap<>();
          for (CpuSeries instance : CpuSeries.values()) {
            map.put(instance.getCpuSeries(), instance);
          }
          return Collections.unmodifiableMap(map);
        }

        private final String cpuSeries;

        CpuSeries(String cpuSeries) {
          this.cpuSeries = cpuSeries;
        }

        public static CpuSeries get(String name) {
          return ENUM_MAP.get(name);
        }

        public String getCpuSeries() {
          return this.cpuSeries;
        }
      }

      // This enum correlates a machine type with its limits.
      // The limits for various CPU types are described in:
      // https://cloud.google.com/compute/docs/general-purpose-machines
      enum Limits {
        CPUSeries_E2(new TypeLimits(getNumsInRangeWithStep(2, 33, 2), 512, 8192, false, 0)),
        CPUSeries_E2MICRO(new TypeLimits(new int[]{}, 1024, 2048, false, 0)),
        CPUSeries_E2SMALL(new TypeLimits(new int[]{}, 2048, 4096, false, 0)),
        CPUSeries_E2MEDIUM(new TypeLimits(new int[]{}, 4096, 8192, false, 0)),
        CPUSeries_N2(
            new TypeLimits(concat(getNumsInRangeWithStep(2, 33, 2), getNumsInRangeWithStep(36, 129, 4)),
                512, 8192, true, gbToMb(624))),
        CPUSeries_N2D(
            new TypeLimits(new int[]{2, 4, 8, 16, 32, 48, 64, 80, 96}, 512, 8192, true, gbToMb(768))),
        CPUSeries_N1(
            new TypeLimits(concat(new int[]{1}, getNumsInRangeWithStep(2, 97, 2)), 922, 6656, true,
                gbToMb(624)));

        private final TypeLimits typeLimits;

        Limits(TypeLimits typeLimits) {
          this.typeLimits = typeLimits;
        }

        public TypeLimits getTypeLimits() {
          return typeLimits;
        }
      }

      static ImmutableMap<String, Limits> typeLimitsMap = ImmutableMap.<String, Limits>builder()
          .put("N1", Limits.CPUSeries_N1)
          .put("N2", Limits.CPUSeries_N2)
          .put("N2D", Limits.CPUSeries_N2D)
          .put("E2", Limits.CPUSeries_E2)
          .put("E2_MICRO", Limits.CPUSeries_E2MICRO)
          .put("E2_SMALL", Limits.CPUSeries_E2SMALL)
          .put("E2_MEDIUM", Limits.CPUSeries_E2SMALL)
          .build();

      // Returns the array of integers within the given range, incremented by the specified step.
      // start (inclusive): starting number of the range
      // stop (inclusive): ending number of the range
      // step : increment value
      static int[] getNumsInRangeWithStep(int start, int stop, int step) {
        return IntStream.range(start, stop).filter(x -> (x - start) % step == 0).toArray();
      }

      static int gbToMb(int value) {
        return value << 10;
      }

      static int[] concat(int[] a, int[] b) {
        int[] result = new int[a.length + b.length];
        System.arraycopy(a, 0, result, 0, a.length);
        System.arraycopy(b, 0, result, a.length, b.length);
        return result;
      }

      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "your-google-cloud-project-id";
        // Name of the zone to create the instance in. For example: "us-west3-b".
        String zone = "google-cloud-zone";
        // Name of the new virtual machine (VM) instance.
        String instanceName = "instance-name";
        String cpuSeries = "N1";
        // Number of CPU cores you want to use.
        int coreCount = 2;
        // The amount of memory for the VM instance, in megabytes.
        int memory = 256;

        createInstanceWithCustomMachineTypeWithHelper(
            projectId, zone, instanceName, cpuSeries, coreCount, memory);
      }

      // Create a VM instance with a custom machine type.
      public static void createInstanceWithCustomMachineTypeWithHelper(
          String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // Construct the URI string identifying the machine type.
        String machineTypeUri = customMachineTypeUri(zone, cpuSeries, coreCount, memory);

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html instancesClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html.create()) {

          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html attachedDisk = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html.newBuilder()
              .https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.Builder.html#com_google_cloud_compute_v1_AttachedDisk_Builder_setInitializeParams_com_google_cloud_compute_v1_AttachedDiskInitializeParams_(
                  // Describe the size and source image of the boot disk to attach to the instance.
                  // The list of public images available in Compute Engine can be found here:
                  // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
                  https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDiskInitializeParams.html.newBuilder()
                      .setSourceImage(
                          String.format("projects/%s/global/images/family/%s", "debian-cloud",
                              "debian-13"))
                      .setDiskSizeGb(10)
                      .build()
              )
              // Remember to set auto_delete to True if you want the disk to be deleted when you delete
              // your VM instance.
              .setAutoDelete(true)
              .setBoot(true)
              .build();

          // Create the Instance object with the relevant information.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html instance = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html.newBuilder()
              .setName(instanceName)
              .addDisks(attachedDisk)
              .setMachineType(machineTypeUri)
              .addNetworkInterfaces(
                  https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.NetworkInterface.html.newBuilder().setName("global/networks/default").build())
              .build();

          // Create the insert instance request object.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html insertInstanceRequest = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstanceResource(instance)
              .build();

          // Invoke the API with the request object and wait for the operation to complete.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html response = instancesClient.insertAsync(insertInstanceRequest)
              .get(3, TimeUnit.MINUTES);

          // Check for errors.
          if (response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_hasError__()) {
            throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html("Instance creation failed!!" + response);
          }
          System.out.printf("Instance created : %s", instanceName);
          System.out.println("Operation Status: " + response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_getStatus__());
        }
      }

      public static String customMachineTypeUri(String zone, String cpuSeries, int coreCount,
          int memory) {

        if (!Arrays.asList(CpuSeries.E2.cpuSeries, CpuSeries.N1.cpuSeries, CpuSeries.N2.cpuSeries,
            CpuSeries.N2D.cpuSeries).contains(cpuSeries)) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html(String.format("Incorrect cpu type: %s", cpuSeries));
        }

        TypeLimits typeLimit = Objects.requireNonNull(
            typeLimitsMap.get(CpuSeries.get(cpuSeries).name())).typeLimits;

        // Perform the following checks to verify if the requested parameters are allowed.
        // Find more information about limitations of custom machine types at:
        // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

        // 1. Check the number of cores and if the coreCount is present in allowedCores.
        if (typeLimit.allowedCores.length > 0 && Arrays.stream(typeLimit.allowedCores)
            .noneMatch(x -> x == coreCount)) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html(String.format(
              "Invalid number of cores requested. "
                  + "Number of cores requested for CPU %s should be one of: %s",
              cpuSeries,
              Arrays.toString(typeLimit.allowedCores)));
        }

        // 2. Memory must be a multiple of 256 MB
        if (memory % 256 != 0) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html("Requested memory must be a multiple of 256 MB");
        }

        // 3. Check if the requested memory isn't too little
        if (memory < coreCount * typeLimit.minMemPerCore) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html(
              String.format("Requested memory is too low. Minimum memory for %s is %s MB per core",
                  cpuSeries, typeLimit.minMemPerCore));
        }

        // 4. Check if the requested memory isn't too much
        if (memory > coreCount * typeLimit.maxMemPerCore && !typeLimit.allowExtraMemory) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html(String.format(
              "Requested memory is too large.. Maximum memory allowed for %s is %s MB per core",
              cpuSeries, typeLimit.extraMemoryLimit));
        }

        // 5. Check if the requested memory isn't too large
        if (memory > typeLimit.extraMemoryLimit && typeLimit.allowExtraMemory) {
          throw new https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Error.html(
              String.format("Requested memory is too large.. Maximum memory allowed for %s is %s MB",
                  cpuSeries, typeLimit.extraMemoryLimit));
        }

        // Check if the CPU Series is E2 and return the custom machine type in the form of a string
        // acceptable by Compute Engine API.
        if (Arrays.asList(CpuSeries.E2_SMALL.cpuSeries, CpuSeries.E2_MICRO.cpuSeries,
            CpuSeries.E2_MEDIUM.cpuSeries).contains(cpuSeries)) {
          return String.format("zones/%s/machineTypes/%s-%s", zone, cpuSeries, memory);
        }

        // Check if extended memory was requested and return the extended custom machine type
        // in the form of a string acceptable by Compute Engine API.
        if (memory > coreCount * typeLimit.maxMemPerCore) {
          return String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries, coreCount,
              memory);
        }

        // Return the custom machine type in the form of a standard string
        // acceptable by Compute Engine API.
        return String.format("zones/%s/machineTypes/%s-%s-%s", zone, cpuSeries, coreCount, memory);
      }
    }

### Node.js


Before trying this sample, follow the Node.js setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Node.js API
reference documentation](https://docs.cloud.google.com/nodejs/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const instanceName = 'YOUR_INSTANCE_NAME';
    // const cpuSeries = 'N1';
    // const coreCount = 2
    // const memory = 256

    const compute = require('https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html');

    function range(from, to, step) {
      return [...Array(Math.floor((to - from) / step) + 1)].map(
        (_, i) => from + i * step
      );
    }

    class CustomMachineType {
      constructor(zone, cpuSeries, coreCount, memory) {
        this.zone = zone;
        this.cpuSeries = cpuSeries;
        this.coreCount = coreCount;
        this.memory = memory;

        this.N1 = 'custom';
        this.N2 = 'n2-custom';
        this.N2D = 'n2d-custom';
        this.E2 = 'e2-custom';
        this.E2Micro = 'e2-custom-micro';
        this.E2Small = 'e2-custom-small';
        this.E2Medium = 'e2-custom-medium';

        this.CpuSeriesE2Limit = {
          allowedCores: range(2, 33, 2),
          minMemPerCore: 512,
          maxMemPerCore: 8192,
          allowExtraMemory: false,
          extraMemoryLimit: 0,
        };

        this.CpuSeriesE2MicroLimit = {
          allowedCores: [],
          minMemPerCore: 1024,
          maxMemPerCore: 2048,
          allowExtraMemory: false,
          extraMemoryLimit: 0,
        };

        this.CpuSeriesE2SmallLimit = {
          allowedCores: [],
          minMemPerCore: 2048,
          maxMemPerCore: 4096,
          allowExtraMemory: false,
          extraMemoryLimit: 0,
        };

        this.CpuSeriesE2MediumLimit = {
          allowedCores: [],
          minMemPerCore: 4096,
          maxMemPerCore: 8192,
          allowExtraMemory: false,
          extraMemoryLimit: 0,
        };

        this.CpuSeriesN2Limit = {
          allowedCores: [...range(2, 33, 2), ...range(36, 129, 4)],
          minMemPerCore: 512,
          maxMemPerCore: 8192,
          allowExtraMemory: true,
          extraMemoryLimit: 624 << 10,
        };

        this.CpuSeriesN2DLimit = {
          allowedCores: [2, 4, 8, 16, 32, 48, 64, 80, 96],
          minMemPerCore: 512,
          maxMemPerCore: 8192,
          allowExtraMemory: true,
          extraMemoryLimit: 768 << 10,
        };

        this.CpuSeriesN1Limit = {
          allowedCores: [1, range(2, 97, 2)],
          minMemPerCore: 922,
          maxMemPerCore: 6656,
          allowExtraMemory: true,
          extraMemoryLimit: 624 << 10,
        };

        this.TYPE_LIMITS = {
          [this.N1]: this.CpuSeriesN1Limit,
          [this.N2]: this.CpuSeriesN2Limit,
          [this.N2D]: this.CpuSeriesN2DLimit,
          [this.E2]: this.CpuSeriesE2Limit,
          [this.E2Micro]: this.CpuSeriesE2MicroLimit,
          [this.E2Small]: this.CpuSeriesE2SmallLimit,
          [this.E2Medium]: this.CpuSeriesE2MediumLimit,
        };

        if (![this.E2, this.N1, this.N2, this.N2D].includes(cpuSeries)) {
          throw new Error(`Incorrect CPU type: ${this.cpuSeries}`);
        }

        this.typeLimit = this.TYPE_LIMITS[this.cpuSeries];

        // Check whether the requested parameters are allowed.
        // Find more information about limitations of custom machine types at:
        // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

        // Check the number of cores
        if (
          this.typeLimit.allowedCores.length > 0 &&
          !this.typeLimit.allowedCores.includes(coreCount)
        ) {
          throw new Error(
            `Invalid number of cores requested. Allowed number of cores for ${this.cpuSeries} is: ${this.typeLimit.allowedCores}`
          );
        }

        // Memory must be a multiple of 256 MB
        if (this.memory % 256 !== 0) {
          throw new Error('Requested memory must be a multiple of 256 MB');
        }

        // Check if the requested memory isn't too little
        if (this.memory < this.coreCount * this.typeLimit.minMemPerCore) {
          throw new Error(
            `Requested memory is too low. Minimal memory for ${this.cpuSeries} is ${this.typeLimit.minMemPerCore} MB per core`
          );
        }

        // Check if the requested memory isn't too much
        if (
          this.memory > this.coreCount * this.typeLimit.maxMemPerCore &&
          !this.typeLimit.allowExtraMemory
        ) {
          throw new Error(
            `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.maxMemPerCore} MB per core`
          );
        }

        if (
          this.memory > this.typeLimit.extraMemoryLimit &&
          this.typeLimit.allowExtraMemory
        ) {
          throw new Error(
            `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.extraMemoryLimit} MB`
          );
        }
      }

      // Returns the custom machine type in form of a string acceptable by Compute Engine API.
      getMachineTypeURI() {
        if (
          [this.E2Small, this.E2Micro, this.E2Medium].includes(this.cpuSeries)
        ) {
          return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.memory}`;
        }

        if (this.memory > this.coreCount * this.typeLimit.maxMemPerCore) {
          return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}-ext`;
        }

        return `zones/${zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}`;
      }
    }

    async function createInstanceWithCustomMachineTypeWithHelper() {
      const instancesClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      const machineType = new CustomMachineType(
        zone,
        cpuSeries,
        coreCount,
        memory
      ).getMachineTypeURI();

      const [response] = await instancesClient.insert({
        instanceResource: {
          name: instanceName,
          disks: [
            {
              initializeParams: {
                diskSizeGb: '64',
                sourceImage:
                  'projects/debian-cloud/global/images/family/debian-11/',
              },
              autoDelete: true,
              boot: true,
            },
          ],
          machineType,
          networkInterfaces: [
            {
              name: 'global/networks/default',
            },
          ],
        },
        project: projectId,
        zone,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      // Wait for the create operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }

      console.log('Instance created.');
    }

    createInstanceWithCustomMachineTypeWithHelper();

### Python


Before trying this sample, follow the Python setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Python API
reference documentation](https://docs.cloud.google.com/python/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    from __future__ import annotations

    from collections import namedtuple
    from enum import Enum
    from enum import unique
    import re
    import sys
    from typing import Any
    import warnings

    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1


    def gb_to_mb(value: int) -> int:
        return value << 10


    class CustomMachineType:
        """
        Allows to create custom machine types to be used with the VM instances.
        """

        @unique
        class CPUSeries(Enum):
            N1 = "custom"
            N2 = "n2-custom"
            N2D = "n2d-custom"
            E2 = "e2-custom"
            E2_MICRO = "e2-custom-micro"
            E2_SMALL = "e2-custom-small"
            E2_MEDIUM = "e2-custom-medium"

        TypeLimits = namedtuple(
            "TypeLimits",
            [
                "allowed_cores",
                "min_mem_per_core",
                "max_mem_per_core",
                "allow_extra_memory",
                "extra_memory_limit",
            ],
        )

        # The limits for various CPU types are described on:
        # https://cloud.google.com/compute/docs/general-purpose-machines
        LIMITS = {
            CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
            CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
            CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
            CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
            CPUSeries.N2: TypeLimits(
                frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
                512,
                8192,
                True,
                gb_to_mb(624),
            ),
            CPUSeries.N2D: TypeLimits(
                frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
            ),
            CPUSeries.N1: TypeLimits(
                frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
            ),
        }

        def __init__(
            self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
        ):
            self.zone = zone
            self.cpu_series = cpu_series
            self.limits = self.LIMITS[self.cpu_series]
            # Shared machine types (e2-small, e2-medium and e2-micro) always have
            # 2 vCPUs: https://cloud.google.com/compute/docs/general-purpose-machines#e2_limitations
            self.core_count = 2 if self.is_shared() else core_count
            self.memory_mb = memory_mb
            self._checked = False
            self._check_parameters()
            self.extra_memory_used = self._check_extra_memory()

        def is_shared(self):
            return self.cpu_series in (
                CustomMachineType.CPUSeries.E2_SMALL,
                CustomMachineType.CPUSeries.E2_MICRO,
                CustomMachineType.CPUSeries.E2_MEDIUM,
            )

        def _check_extra_memory(self) -> bool:
            if self._checked:
                return self.memory_mb > self.core_count * self.limits.max_mem_per_core
            else:
                raise RuntimeError(
                    "You need to call _check_parameters() before calling _check_extra_memory()"
                )

        def _check_parameters(self):
            """
            Check whether the requested parameters are allowed. Find more information about limitations of custom machine
            types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
            """
            # Check the number of cores
            if (
                self.limits.allowed_cores
                and self.core_count not in self.limits.allowed_cores
            ):
                raise RuntimeError(
                    f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
                )

            # Memory must be a multiple of 256 MB
            if self.memory_mb % 256 != 0:
                raise RuntimeError("Requested memory must be a multiple of 256 MB.")

            # Check if the requested memory isn't too little
            if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
                raise RuntimeError(
                    f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
                )

            # Check if the requested memory isn't too much
            if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
                if self.limits.allow_extra_memory:
                    if self.memory_mb > self.limits.extra_memory_limit:
                        raise RuntimeError(
                            f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
                        )
                else:
                    raise RuntimeError(
                        f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
                    )

            self._checked = True

        def __str__(self) -> str:
            """
            Return the custom machine type in form of a string acceptable by Compute Engine API.
            """
            if self.cpu_series in {
                self.CPUSeries.E2_SMALL,
                self.CPUSeries.E2_MICRO,
                self.CPUSeries.E2_MEDIUM,
            }:
                return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"

            if self.extra_memory_used:
                return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"

            return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"

        def short_type_str(self) -> str:
            """
            Return machine type in a format without the zone. For example, n2-custom-0-10240.
            This format is used to create instance templates.
            """
            return str(self).rsplit("/", maxsplit=1)[1]

        @classmethod
        def from_str(cls, machine_type: str):
            """
            Construct a new object from a string. The string needs to be a valid custom machine type like:
             - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
             - zones/us-central1-b/machineTypes/e2-custom-4-8192
             - e2-custom-4-8192 (in this case, the zone parameter will not be set)
            """
            zone = None
            if machine_type.startswith("http"):
                machine_type = machine_type[machine_type.find("zones/") :]

            if machine_type.startswith("zones/"):
                _, zone, _, machine_type = machine_type.split("/")

            extra_mem = machine_type.endswith("-ext")

            if machine_type.startswith("custom"):
                cpu = cls.CPUSeries.N1
                _, cores, memory = machine_type.rsplit("-", maxsplit=2)
            else:
                if extra_mem:
                    cpu_series, _, cores, memory, _ = machine_type.split("-")
                else:
                    cpu_series, _, cores, memory = machine_type.split("-")
                if cpu_series == "n2":
                    cpu = cls.CPUSeries.N2
                elif cpu_series == "n2d":
                    cpu = cls.CPUSeries.N2D
                elif cpu_series == "e2":
                    cpu = cls.CPUSeries.E2
                    if cores == "micro":
                        cpu = cls.CPUSeries.E2_MICRO
                        cores = 2
                    elif cores == "small":
                        cpu = cls.CPUSeries.E2_SMALL
                        cores = 2
                    elif cores == "medium":
                        cpu = cls.CPUSeries.E2_MEDIUM
                        cores = 2
                else:
                    raise RuntimeError("Unknown CPU series.")

            cores = int(cores)
            memory = int(memory)

            return cls(zone, cpu, memory, cores)


    def get_image_from_family(project: str, family: str) -> compute_v1.Image:
        """
        Retrieve the newest image that is part of a given family in a project.

        Args:
            project: project ID or project number of the Cloud project you want to get image from.
            family: name of the image family you want to get image from.

        Returns:
            An Image object.
        """
        image_client = compute_v1.ImagesClient()
        # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
        newest_image = image_client.get_from_family(project=project, family=family)
        return newest_image


    def disk_from_image(
        disk_type: str,
        disk_size_gb: int,
        boot: bool,
        source_image: str,
        auto_delete: bool = True,
    ) -> compute_v1.AttachedDisk:
        """
        Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
        source for the new disk.

        Args:
             disk_type: the type of disk you want to create. This value uses the following format:
                "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
                For example: "zones/us-west3-b/diskTypes/pd-ssd"
            disk_size_gb: size of the new disk in gigabytes
            boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
            source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
                of the publicly available images or an image from one of your projects.
                This value uses the following format: "projects/{project_name}/global/images/{image_name}"
            auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

        Returns:
            AttachedDisk object configured to be created using the specified image.
        """
        boot_disk = compute_v1.AttachedDisk()
        initialize_params = compute_v1.AttachedDiskInitializeParams()
        initialize_params.source_image = source_image
        initialize_params.disk_size_gb = disk_size_gb
        initialize_params.disk_type = disk_type
        boot_disk.initialize_params = initialize_params
        # Remember to set auto_delete to True if you want the disk to be deleted when you delete
        # your VM instance.
        boot_disk.auto_delete = auto_delete
        boot_disk.boot = boot
        return boot_disk


    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.

        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.

        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.

        Returns:
            Whatever the operation.result() returns.

        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.

            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)

        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)

        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

        return result


    def create_instance(
        project_id: str,
        zone: str,
        instance_name: str,
        disks: list[compute_v1.AttachedDisk],
        machine_type: str = "n1-standard-1",
        network_link: str = "global/networks/default",
        subnetwork_link: str = None,
        internal_ip: str = None,
        external_access: bool = False,
        external_ipv4: str = None,
        accelerators: list[compute_v1.AcceleratorConfig] = None,
        preemptible: bool = False,
        spot: bool = False,
        instance_termination_action: str = "STOP",
        custom_hostname: str = None,
        delete_protection: bool = False,
    ) -> compute_v1.Instance:
        """
        Send an instance creation request to the Compute Engine API and wait for it to complete.

        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            disks: a list of compute_v1.AttachedDisk objects describing the disks
                you want to attach to your new instance.
            machine_type: machine type of the VM being created. This value uses the
                following format: "zones/{zone}/machineTypes/{type_name}".
                For example: "zones/europe-west3-c/machineTypes/f1-micro"
            network_link: name of the network you want the new instance to use.
                For example: "global/networks/default" represents the network
                named "default", which is created automatically for each project.
            subnetwork_link: name of the subnetwork you want the new instance to use.
                This value uses the following format:
                "regions/{region}/subnetworks/{subnetwork_name}"
            internal_ip: internal IP address you want to assign to the new instance.
                By default, a free address from the pool of available internal IP addresses of
                used subnet will be used.
            external_access: boolean flag indicating if the instance should have an external IPv4
                address assigned.
            external_ipv4: external IPv4 address to be assigned to this instance. If you specify
                an external IP address, it must live in the same region as the zone of the instance.
                This setting requires `external_access` to be set to True to work.
            accelerators: a list of AcceleratorConfig objects describing the accelerators that will
                be attached to the new instance.
            preemptible: boolean value indicating if the new instance should be preemptible
                or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
            spot: boolean value indicating if the new instance should be a Spot VM or not.
            instance_termination_action: What action should be taken once a Spot VM is terminated.
                Possible values: "STOP", "DELETE"
            custom_hostname: Custom hostname of the new VM instance.
                Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
            delete_protection: boolean value indicating if the new virtual machine should be
                protected against deletion or not.
        Returns:
            Instance object.
        """
        instance_client = compute_v1.InstancesClient()

        # Use the network interface provided in the network_link argument.
        network_interface = compute_v1.NetworkInterface()
        network_interface.network = network_link
        if subnetwork_link:
            network_interface.subnetwork = subnetwork_link

        if internal_ip:
            network_interface.network_i_p = internal_ip

        if external_access:
            access = compute_v1.AccessConfig()
            access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
            access.name = "External NAT"
            access.network_tier = access.NetworkTier.PREMIUM.name
            if external_ipv4:
                access.nat_i_p = external_ipv4
            network_interface.access_configs = [access]

        # Collect information into the Instance object.
        instance = compute_v1.Instance()
        instance.network_interfaces = [network_interface]
        instance.name = instance_name
        instance.disks = disks
        if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
            instance.machine_type = machine_type
        else:
            instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

        instance.scheduling = compute_v1.Scheduling()
        if accelerators:
            instance.guest_accelerators = accelerators
            instance.scheduling.on_host_maintenance = (
                compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
            )

        if preemptible:
            # Set the preemptible setting
            warnings.warn(
                "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
            )
            instance.scheduling = compute_v1.Scheduling()
            instance.scheduling.preemptible = True

        if spot:
            # Set the Spot VM setting
            instance.scheduling.provisioning_model = (
                compute_v1.Scheduling.ProvisioningModel.SPOT.name
            )
            instance.scheduling.instance_termination_action = instance_termination_action

        if custom_hostname is not None:
            # Set the custom hostname for the instance
            instance.hostname = custom_hostname

        if delete_protection:
            # Set the delete protection bit
            instance.deletion_protection = True

        # Prepare the request to insert an instance.
        request = compute_v1.InsertInstanceRequest()
        request.zone = zone
        request.project = project_id
        request.instance_resource = instance

        # Wait for the create operation to complete.
        print(f"Creating the {instance_name} instance in {zone}...")

        operation = instance_client.insert(request=request)

        wait_for_extended_operation(operation, "instance creation")

        print(f"Instance {instance_name} created.")
        return instance_client.get(project=project_id, zone=zone, instance=instance_name)


    def create_custom_instance(
        project_id: str,
        zone: str,
        instance_name: str,
        cpu_series: CustomMachineType.CPUSeries,
        core_count: int,
        memory: int,
    ) -> compute_v1.Instance:
        """
        Create a new VM instance with a custom machine type.

        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            cpu_series: the type of CPU you want to use. Select one value from the CustomMachineType.CPUSeries enum.
                For example: CustomMachineType.CPUSeries.N2
            core_count: number of CPU cores you want to use.
            memory: the amount of memory for the VM instance, in megabytes.

        Return:
            Instance object.
        """
        assert cpu_series in (
            CustomMachineType.CPUSeries.E2,
            CustomMachineType.CPUSeries.N1,
            CustomMachineType.CPUSeries.N2,
            CustomMachineType.CPUSeries.N2D,
        )
        custom_type = CustomMachineType(zone, cpu_series, memory, core_count)

        newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
        disk_type = f"zones/{zone}/diskTypes/pd-standard"
        disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]

        return create_instance(project_id, zone, instance_name, disks, str(custom_type))

### REST

To create an instance with a custom machine type, call the
[`instances.insert` method](https://docs.cloud.google.com/compute/docs/reference/latest/instances/insert)
and specify the custom
[`machineType` values](https://docs.cloud.google.com/compute/docs/reference/latest/instances#machineType)
with memory in MB:

- For the N1 machine series, omit the series prefix and start with `custom-`.
- For E2 shared-core machine types, replace the vCPU count with `micro`, `small`, or `medium`.
- To enable extended memory, append `-ext` to the machine type string.

The following example creates an N2 custom machine type with 16 vCPUs and
105 GB (107,520 MB) of memory:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances

    {
      "name": "example-instance",
      "machineType": "zones/ZONE/machineTypes/n2-custom-16-107520",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "diskSizeGb": "10",
            "sourceImage": "projects/debian-cloud/global/images/family/debian-13"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ]
    }

Replace the following:

- `PROJECT_ID`: the ID of the project where you want to create the instance.
- `ZONE`: the zone where you want to create the instance.

You can similarly create [Spot VMs](https://docs.cloud.google.com/compute/docs/instances/spot)
and [managed instance groups (MIGs)](https://docs.cloud.google.com/compute/docs/instance-groups) with custom
machine types.

### Add extended memory during instance creation

To create a VM instance with extended memory, do the following:

<br />

### Console

1. In the Google Cloud console, go to the **Create an instance** page.

   [Go to Create an instance](https://console.cloud.google.com/compute/instancesAdd)
2. In the **Machine configuration** pane, do the following:

   1. Select the **Region** and **Zone** where you want to host the VM.
   2. Select the machine configuration for your instance:
      - To create a general-purpose custom VM, select **General purpose** , and then in the **Series** section, select **N4** , **N4D** , **N4A** , **N2** , **N2D** , or **N1**.
      - To create an N1 custom VM with attached GPUs, select **GPUs** , and then do the following:
        1. In the **GPU type** list, select **NVIDIA T4** , **NVIDIA V100** , or **NVIDIA Tesla P4**.
        2. In the **Number of GPUs** list, select the number of GPUs.
   3. In the **Machine type** section, select **Custom**.
   4. To specify the number of vCPUs, drag the **Cores** slider or enter the value in the field.
   5. To add extended memory, select **Extend Memory** . To specify the amount of memory for the machine type, drag the **Memory** slider or enter the value in the field. The console displays an estimated cost for the VM as you edit the number of vCPUs and amount of memory.
3. Optional: Specify other configuration options. For more information, see
   [Configuration options during instance creation](https://docs.cloud.google.com/compute/docs/instances/instance-creation-overview#new-instance-configuration-options).

4. To create and start the VM, click **Create**.

### gcloud

Create a custom machine type with extended memory by using the
[`gcloud compute instances create`
command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/create) with the
`--machine-type` flag and the `-ext` suffix:

    gcloud compute instances create INSTANCE_NAME \
        --zone=ZONE \
        --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext

Replace the following:

- `INSTANCE_NAME`: the name of the instance.
- `ZONE`: the zone where you want to create the instance.
- `MACHINE_SERIES`: the lowercase machine series that supports extended memory, such as `n4`, `n4d`, `n4a`, `n2`, or `n2d`. For N1, omit `MACHINE_SERIES-` and start with `custom-`.
- `NUMBER_OF_VCPUS`: the number of vCPUs.
- `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB.

The following example creates an N2 custom machine type with 2 vCPUs and
20 GB (20,480 MB) of extended memory in zone `us-central1-a`:

    gcloud compute instances create example-instance \
        --zone=us-central1-a \
        --machine-type=n2-custom-2-20480-ext

### Go


Before trying this sample, follow the Go setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Go API
reference documentation](https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    import (
    	"context"
    	"fmt"
    	"io"

    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "cloud.google.com/go/compute/apiv1/computepb"
    	"google.golang.org/protobuf/proto"
    )

    // createInstanceWithExtraMemWithoutHelper сreates new VM instances with extra memory
    // without using a CustomMachineType struct.
    func createInstanceWithExtraMemWithoutHelper(
    	w io.Writer,
    	projectID, zone, instanceName, cpuSeries string,
    	coreCount, memory int,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// cpuSeries := "N1"
    	// coreCount := 2 // number of CPU cores you want to use.
    	// memory := 256 // the amount of memory for the VM instance, in megabytes.

    	// The coreCount and memory values are not validated anywhere and can be rejected by the API.

    	ctx := context.Background()
    	instancesClient, err := ccompute.https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1.html#cloud_google_com_go_compute_apiv1_InstancesClient_NewInstancesRESTClientctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()

    	mt := fmt.Sprintf("zones/%s/machineTypes/%v-%v-%v-ext", zone, cpuSeries, coreCount, memory)
    	inst := &computepb.Instance{
    		Name: proto.String(instanceName),
    		Disks: []*computepb.AttachedDisk{
    			{
    				InitializeParams: &computepb.AttachedDiskInitializeParams{
    					DiskSizeGb: proto.Int64(10),
    					SourceImage: proto.String(
    						"projects/debian-cloud/global/images/family/debian-12",
    					),
    				},
    				AutoDelete: proto.Bool(true),
    				Boot:       proto.Bool(true),
    			},
    		},
    		MachineType: proto.String(mt),
    		NetworkInterfaces: []*computepb.NetworkInterface{
    			{
    				Name: proto.String("global/networks/default"),
    			},
    		},
    	}

    	req := &computepb.InsertInstanceRequest{
    		Project:          projectID,
    		Zone:             zone,
    		InstanceResource: inst,
    	}

    	op, err := instancesClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create instance: %w", err)
    	}

    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}

    	fmt.Fprintf(w, "Instance created\n")

    	return nil
    }

### Java


Before trying this sample, follow the Java setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Java API
reference documentation](https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/overview).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).


    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDiskInitializeParams.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.NetworkInterface.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;

    public class ExtraMemoryWithoutHelper {

      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "your-google-cloud-project-id";
        // Name of the zone to create the instance in. For example: "us-west3-b".
        String zone = "google-cloud-zone";
        // Name of the new virtual machine (VM) instance.
        String instanceName = "instance-name";
        String cpuSeries = "N1";
        // Number of CPU cores you want to use.
        int coreCount = 2;
        // The amount of memory for the VM instance, in megabytes.
        int memory = 256;

        createInstanceWithExtraMemoryWithoutHelper(projectId, zone, instanceName, cpuSeries, coreCount,
            memory);
      }

      // Create VM instances with extra memory without using a CustomMachineType class and
      // return the created Instance.
      public static void createInstanceWithExtraMemoryWithoutHelper(
          String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html instancesClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html.create()) {

          // The coreCount and memory values are not validated anywhere and can be rejected by the API.
          String machineType = String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries,
              coreCount, memory);

          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html attachedDisk = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.html.newBuilder()
              .https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDisk.Builder.html#com_google_cloud_compute_v1_AttachedDisk_Builder_setInitializeParams_com_google_cloud_compute_v1_AttachedDiskInitializeParams_(
                  // Describe the size and source image of the boot disk to attach to the instance.
                  // The list of public images available in Compute Engine can be found here:
                  // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
                  https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.AttachedDiskInitializeParams.html.newBuilder()
                      .setSourceImage(
                          String.format("projects/%s/global/images/family/%s", "debian-cloud",
                              "debian-13"))
                      .setDiskSizeGb(10)
                      .build()
              )
              // Remember to set auto_delete to True if you want the disk to be deleted when you delete
              // your VM instance.
              .setAutoDelete(true)
              .setBoot(true)
              .build();

          // Create the Instance object with the relevant information.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html instance = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html.newBuilder()
              .setName(instanceName)
              .addDisks(attachedDisk)
              .setMachineType(machineType)
              .addNetworkInterfaces(
                  https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.NetworkInterface.html.newBuilder().setName("global/networks/default").build())
              .build();

          // Create the insert instance request object.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html insertInstanceRequest = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InsertInstanceRequest.html.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstanceResource(instance)
              .build();

          // Invoke the API with the request object and wait for the operation to complete.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html response = instancesClient.insertAsync(insertInstanceRequest)
              .get(3, TimeUnit.MINUTES);

          // Check for errors.
          if (response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_hasError__()) {
            System.out.println("Instance creation failed!!" + response);
            return;
          }
          System.out.printf("Instance created : %s", instanceName);
          System.out.println("Operation Status: " + response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_getStatus__());
        }
      }
    }

### Node.js


Before trying this sample, follow the Node.js setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Node.js API
reference documentation](https://docs.cloud.google.com/nodejs/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const instanceName = 'YOUR_INSTANCE_NAME';
    // const cpuSeries = 'N1';
    // const coreCount = 2
    // const memory = 256

    // The coreCount and memory values are not validated anywhere and can be rejected by the API.

    const compute = require('https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html');

    async function createInstanceWithExtraMemWithoutHelper() {
      const instancesClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      const machineType = `zones/${zone}/machineTypes/${cpuSeries}-${coreCount}-${memory}-ext`;

      const [response] = await instancesClient.insert({
        instanceResource: {
          name: instanceName,
          disks: [
            {
              initializeParams: {
                diskSizeGb: '64',
                sourceImage:
                  'projects/debian-cloud/global/images/family/debian-11/',
              },
              autoDelete: true,
              boot: true,
            },
          ],
          machineType,
          networkInterfaces: [
            {
              name: 'global/networks/default',
            },
          ],
        },
        project: projectId,
        zone,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      // Wait for the create operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }

      console.log('Instance created.');
    }

    createInstanceWithExtraMemWithoutHelper();

### Python


Before trying this sample, follow the Python setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Python API
reference documentation](https://docs.cloud.google.com/python/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    from __future__ import annotations

    import re
    import sys
    from typing import Any
    import warnings

    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1


    def get_image_from_family(project: str, family: str) -> compute_v1.Image:
        """
        Retrieve the newest image that is part of a given family in a project.

        Args:
            project: project ID or project number of the Cloud project you want to get image from.
            family: name of the image family you want to get image from.

        Returns:
            An Image object.
        """
        image_client = compute_v1.ImagesClient()
        # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
        newest_image = image_client.get_from_family(project=project, family=family)
        return newest_image


    def disk_from_image(
        disk_type: str,
        disk_size_gb: int,
        boot: bool,
        source_image: str,
        auto_delete: bool = True,
    ) -> compute_v1.AttachedDisk:
        """
        Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
        source for the new disk.

        Args:
             disk_type: the type of disk you want to create. This value uses the following format:
                "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
                For example: "zones/us-west3-b/diskTypes/pd-ssd"
            disk_size_gb: size of the new disk in gigabytes
            boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
            source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
                of the publicly available images or an image from one of your projects.
                This value uses the following format: "projects/{project_name}/global/images/{image_name}"
            auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

        Returns:
            AttachedDisk object configured to be created using the specified image.
        """
        boot_disk = compute_v1.AttachedDisk()
        initialize_params = compute_v1.AttachedDiskInitializeParams()
        initialize_params.source_image = source_image
        initialize_params.disk_size_gb = disk_size_gb
        initialize_params.disk_type = disk_type
        boot_disk.initialize_params = initialize_params
        # Remember to set auto_delete to True if you want the disk to be deleted when you delete
        # your VM instance.
        boot_disk.auto_delete = auto_delete
        boot_disk.boot = boot
        return boot_disk


    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.

        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.

        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.

        Returns:
            Whatever the operation.result() returns.

        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.

            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)

        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)

        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

        return result


    def create_instance(
        project_id: str,
        zone: str,
        instance_name: str,
        disks: list[compute_v1.AttachedDisk],
        machine_type: str = "n1-standard-1",
        network_link: str = "global/networks/default",
        subnetwork_link: str = None,
        internal_ip: str = None,
        external_access: bool = False,
        external_ipv4: str = None,
        accelerators: list[compute_v1.AcceleratorConfig] = None,
        preemptible: bool = False,
        spot: bool = False,
        instance_termination_action: str = "STOP",
        custom_hostname: str = None,
        delete_protection: bool = False,
    ) -> compute_v1.Instance:
        """
        Send an instance creation request to the Compute Engine API and wait for it to complete.

        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            disks: a list of compute_v1.AttachedDisk objects describing the disks
                you want to attach to your new instance.
            machine_type: machine type of the VM being created. This value uses the
                following format: "zones/{zone}/machineTypes/{type_name}".
                For example: "zones/europe-west3-c/machineTypes/f1-micro"
            network_link: name of the network you want the new instance to use.
                For example: "global/networks/default" represents the network
                named "default", which is created automatically for each project.
            subnetwork_link: name of the subnetwork you want the new instance to use.
                This value uses the following format:
                "regions/{region}/subnetworks/{subnetwork_name}"
            internal_ip: internal IP address you want to assign to the new instance.
                By default, a free address from the pool of available internal IP addresses of
                used subnet will be used.
            external_access: boolean flag indicating if the instance should have an external IPv4
                address assigned.
            external_ipv4: external IPv4 address to be assigned to this instance. If you specify
                an external IP address, it must live in the same region as the zone of the instance.
                This setting requires `external_access` to be set to True to work.
            accelerators: a list of AcceleratorConfig objects describing the accelerators that will
                be attached to the new instance.
            preemptible: boolean value indicating if the new instance should be preemptible
                or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
            spot: boolean value indicating if the new instance should be a Spot VM or not.
            instance_termination_action: What action should be taken once a Spot VM is terminated.
                Possible values: "STOP", "DELETE"
            custom_hostname: Custom hostname of the new VM instance.
                Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
            delete_protection: boolean value indicating if the new virtual machine should be
                protected against deletion or not.
        Returns:
            Instance object.
        """
        instance_client = compute_v1.InstancesClient()

        # Use the network interface provided in the network_link argument.
        network_interface = compute_v1.NetworkInterface()
        network_interface.network = network_link
        if subnetwork_link:
            network_interface.subnetwork = subnetwork_link

        if internal_ip:
            network_interface.network_i_p = internal_ip

        if external_access:
            access = compute_v1.AccessConfig()
            access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
            access.name = "External NAT"
            access.network_tier = access.NetworkTier.PREMIUM.name
            if external_ipv4:
                access.nat_i_p = external_ipv4
            network_interface.access_configs = [access]

        # Collect information into the Instance object.
        instance = compute_v1.Instance()
        instance.network_interfaces = [network_interface]
        instance.name = instance_name
        instance.disks = disks
        if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
            instance.machine_type = machine_type
        else:
            instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

        instance.scheduling = compute_v1.Scheduling()
        if accelerators:
            instance.guest_accelerators = accelerators
            instance.scheduling.on_host_maintenance = (
                compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
            )

        if preemptible:
            # Set the preemptible setting
            warnings.warn(
                "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
            )
            instance.scheduling = compute_v1.Scheduling()
            instance.scheduling.preemptible = True

        if spot:
            # Set the Spot VM setting
            instance.scheduling.provisioning_model = (
                compute_v1.Scheduling.ProvisioningModel.SPOT.name
            )
            instance.scheduling.instance_termination_action = instance_termination_action

        if custom_hostname is not None:
            # Set the custom hostname for the instance
            instance.hostname = custom_hostname

        if delete_protection:
            # Set the delete protection bit
            instance.deletion_protection = True

        # Prepare the request to insert an instance.
        request = compute_v1.InsertInstanceRequest()
        request.zone = zone
        request.project = project_id
        request.instance_resource = instance

        # Wait for the create operation to complete.
        print(f"Creating the {instance_name} instance in {zone}...")

        operation = instance_client.insert(request=request)

        wait_for_extended_operation(operation, "instance creation")

        print(f"Instance {instance_name} created.")
        return instance_client.get(project=project_id, zone=zone, instance=instance_name)


    def create_custom_instances_extra_mem(
        project_id: str, zone: str, instance_name: str, core_count: int, memory: int
    ) -> list[compute_v1.Instance]:
        """
        Create 3 new VM instances with extra memory without using a CustomMachineType helper class.

        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            core_count: number of CPU cores you want to use.
            memory: the amount of memory for the VM instance, in megabytes.

        Returns:
            List of Instance objects.
        """
        newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
        disk_type = f"zones/{zone}/diskTypes/pd-standard"
        disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
        # The core_count and memory values are not validated anywhere and can be rejected by the API.
        instances = [
            create_instance(
                project_id,
                zone,
                f"{instance_name}_n1_extra_mem",
                disks,
                f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
            ),
            create_instance(
                project_id,
                zone,
                f"{instance_name}_n2_extra_mem",
                disks,
                f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
            ),
            create_instance(
                project_id,
                zone,
                f"{instance_name}_n2d_extra_mem",
                disks,
                f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
            ),
        ]
        return instances

### REST

To create an instance with extended memory, call the
[`instances.insert` method](https://docs.cloud.google.com/compute/docs/reference/latest/instances/insert)
and append `-ext` to the `machineType` field to extend the memory up to the
limit for that machine series:

    zones/ZONE/machineTypes/MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext

Replace the following:

- `ZONE`: the zone where you want to create the instance.
- `MACHINE_SERIES`: the lowercase machine series, such as `n4`, `n4d`, `n4a`, `n2`, or `n2d`. For N1, omit `MACHINE_SERIES-` and start with `custom-`.
- `NUMBER_OF_VCPUS`: the number of vCPUs.
- `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB.

For example, the following specifies an N2 machine type with
2 vCPUs and 20 GB (20,480 MB) of extended memory:

    zones/ZONE/machineTypes/n2-custom-2-20480-ext

### Add extended memory to an existing VM instance

To add more memory to an existing instance that uses a custom machine type, you must first [stop the instance](https://docs.cloud.google.com/compute/docs/instances/stop-start-instance). After the instance stops, complete the following steps to add more memory to the VM:

<br />

### Console

1. In the Google Cloud console, go to the **VM instances** page.

   [Go to VM instances](https://console.cloud.google.com/compute/instances)
2. Click the name of the stopped VM that you want to modify.

3. At the top of the page, click **Edit**.

4. In the **Machine configuration** section, verify that **Custom** is
   selected under **Machine type**.

5. To add extended memory, select **Extend Memory** , and then specify the
   amount of **Memory** that you need.

6. Click **Save**.

7. To restart the VM, at the top of the page, click **Start / Resume**.

### gcloud

1. Stop the VM by running the
   [`gcloud compute instances stop`
   command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/stop):

       gcloud compute instances stop INSTANCE_NAME \
           --zone=ZONE

2. Update the custom machine type with extended memory by running the
   [`gcloud compute instances set-machine-type`
   command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/set-machine-type) with
   the `--custom-cpu`, `--custom-memory`, `--custom-vm-type`, and
   `--custom-extensions` flags:

       gcloud compute instances set-machine-type INSTANCE_NAME \
           --zone=ZONE \
           --custom-cpu=NUMBER_OF_VCPUS \
           --custom-memory=AMOUNT_OF_MEMORY \
           --custom-vm-type=MACHINE_SERIES \
           --custom-extensions

   Alternatively, you can pass the full custom machine type string with the
   `-ext` suffix to the `--machine-type` flag:

       gcloud compute instances set-machine-type INSTANCE_NAME \
           --zone=ZONE \
           --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext

   Replace the following:
   - `INSTANCE_NAME`: the name of the VM.
   - `ZONE`: the zone where the VM is located.
   - `NUMBER_OF_VCPUS`: the number of vCPUs.
   - `AMOUNT_OF_MEMORY`: the total amount of memory with a unit suffix (`MB` or `GB`), or in GB if you omit the unit.
   - `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB.
   - `MACHINE_SERIES`: the lowercase machine series that supports extended memory, such as `n4`, `n4d`, `n4a`, `n2`, `n2d`, or `n1`. For N1 with the `--machine-type` flag, omit `MACHINE_SERIES-` and start with `custom-`.
3. Restart the VM by running the
   [`gcloud compute instances start`
   command](https://docs.cloud.google.com/sdk/gcloud/reference/compute/instances/start):

       gcloud compute instances start INSTANCE_NAME \
           --zone=ZONE

### Go


Before trying this sample, follow the Go setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Go API
reference documentation](https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    import (
    	"context"
    	"fmt"
    	"io"
    	"strings"

    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "cloud.google.com/go/compute/apiv1/computepb"
    	"google.golang.org/protobuf/proto"
    )

    // modifyInstanceWithExtendedMemory sends an instance creation request
    // to the Compute Engine API and waits for it to complete.
    func modifyInstanceWithExtendedMemory(
    	w io.Writer,
    	projectID, zone, instanceName string,
    	newMemory int,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// newMemory := 256 // the amount of memory for the VM instance, in megabytes.

    	ctx := context.Background()
    	instancesClient, err := compute.https://docs.cloud.google.com/go/docs/reference/cloud.google.com/go/compute/latest/apiv1.html#cloud_google_com_go_compute_apiv1_InstancesClient_NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()

    	reqInstance := &computepb.GetInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    	}

    	instance, err := instancesClient.Get(ctx, reqInstance)
    	if err != nil {
    		return fmt.Errorf("unable to get instance: %w", err)
    	}

    	containsString := func(s []string, str string) bool {
    		for _, v := range s {
    			if v == str {
    				return true
    			}
    		}

    		return false
    	}

    	if !(strings.Contains(instance.GetMachineType(), "machineTypes/n1-") ||
    		strings.Contains(instance.GetMachineType(), "machineTypes/n2-") ||
    		strings.Contains(instance.GetMachineType(), "machineTypes/n2d-")) {
    		return fmt.Errorf("extra memory is available only for N1, N2 and N2D CPUs")
    	}

    	// Make sure that the machine is turned off
    	if !containsString([]string{"TERMINATED", "STOPPED"}, instance.GetStatus()) {
    		reqStop := &computepb.StopInstanceRequest{
    			Project:  projectID,
    			Zone:     zone,
    			Instance: instanceName,
    		}

    		op, err := instancesClient.Stop(ctx, reqStop)
    		if err != nil {
    			return fmt.Errorf("unable to stop instance: %w", err)
    		}

    		if err = op.Wait(ctx); err != nil {
    			return fmt.Errorf("unable to wait for the operation: %w", err)
    		}
    	}

    	// Modify the machine definition, remember that extended memory
    	// is available only for N1, N2 and N2D CPUs
    	machineType := instance.GetMachineType()
    	start := machineType[:strings.LastIndex(machineType, "-")]

    	updateReq := &computepb.SetMachineTypeInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    		InstancesSetMachineTypeRequestResource: &computepb.InstancesSetMachineTypeRequest{
    			MachineType: proto.String(fmt.Sprintf("%s-%v-ext", start, newMemory)),
    		},
    	}
    	op, err := instancesClient.SetMachineType(ctx, updateReq)
    	if err != nil {
    		return fmt.Errorf("unable to update instance: %w", err)
    	}

    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}

    	fmt.Fprintf(w, "Instance updated\n")

    	return nil

    }

### Java


Before trying this sample, follow the Java setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Java API
reference documentation](https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/overview).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).


    import com.google.api.gax.longrunning.https://docs.cloud.google.com/java/docs/reference/gax/latest/com.google.api.gax.longrunning.OperationFuture.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.GetInstanceRequest.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Status.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesSetMachineTypeRequest.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.SetMachineTypeInstanceRequest.html;
    import com.google.cloud.compute.v1.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.StopInstanceRequest.html;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;

    public class UpdateMemory {

      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "your-google-cloud-project-id";
        // Name of the zone to create the instance in. For example: "us-west3-b".
        String zone = "google-cloud-zone";
        // Name of the new virtual machine (VM) instance.
        String instanceName = "instance-name";
        // The amount of memory for the VM instance, in megabytes.
        int newMemory = 256;

        modifyInstanceWithExtendedMemory(projectId, zone, instanceName, newMemory);
      }

      // Modify an existing VM to use extended memory and return the modified Instance.
      public static void modifyInstanceWithExtendedMemory(
          String project, String zone, String instanceName, int newMemory)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html instancesClient = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html.create()) {

          // Create the get instance request object.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.GetInstanceRequest.html getInstanceRequest = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.GetInstanceRequest.html.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName)
              .build();

          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html instance = instancesClient.get(getInstanceRequest);

          // Check the machine type.
          if (!(instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getMachineType__().contains("machineTypes/n1-")
              || instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getMachineType__().contains("machineTypes/n2-")
              || instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getMachineType__().contains("machineTypes/n2d-"))) {
            System.out.println("extra memory is available only for N1, N2 and N2D CPUs");
            return;
          }

          // Make sure that the machine is turned off.
          if (!(instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getStatus__().equals(https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Status.html.TERMINATED.toString())
              || instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getStatus__().equals(https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Status.html.STOPPED.toString()))) {

            https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.StopInstanceRequest.html stopInstanceRequest = https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.StopInstanceRequest.html.newBuilder()
                .setProject(project)
                .setZone(zone)
                .setInstance(instanceName)
                .build();

            OperationFuture<Operation, Operation> operation = instancesClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html#com_google_cloud_compute_v1_InstancesClient_stopAsync_com_google_cloud_compute_v1_StopInstanceRequest_(
                stopInstanceRequest);
            https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html response = operation.get(3, TimeUnit.MINUTES);
            if (response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_hasError__()) {
              System.out.printf("Unable to stop instance %s", response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_getError__());
              return;
            }
          }

          // Modify the machine definition. Note that extended memory
          // is available only for N1, N2 and N2D CPUs.
          String machineType = instance.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Instance.html#com_google_cloud_compute_v1_Instance_getMachineType__();
          String start = machineType.substring(0, machineType.lastIndexOf("-"));

          // Create the machine type instance request object.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.SetMachineTypeInstanceRequest.html setMachineTypeInstanceRequest =
              https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.SetMachineTypeInstanceRequest.html.newBuilder()
                  .setProject(project)
                  .setZone(zone)
                  .setInstance(instanceName)
                  .https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.SetMachineTypeInstanceRequest.Builder.html#com_google_cloud_compute_v1_SetMachineTypeInstanceRequest_Builder_setInstancesSetMachineTypeRequestResource_com_google_cloud_compute_v1_InstancesSetMachineTypeRequest_(https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesSetMachineTypeRequest.html.newBuilder()
                      .setMachineType(String.format("%s-%d-ext", start, newMemory))
                      .build())
                  .build();

          // Invoke the API with the request object and wait for the operation to complete.
          https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html response = instancesClient.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.InstancesClient.html#com_google_cloud_compute_v1_InstancesClient_setMachineTypeAsync_com_google_cloud_compute_v1_SetMachineTypeInstanceRequest_(setMachineTypeInstanceRequest)
              .get(3, TimeUnit.MINUTES);

          // Check for errors.
          if (response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_hasError__()) {
            System.out.printf("Unable to update instance %s", response.https://docs.cloud.google.com/java/docs/reference/google-cloud-compute/latest/com.google.cloud.compute.v1.Operation.html#com_google_cloud_compute_v1_Operation_getError__());
            return;
          }
          System.out.println("Instance updated!");
        }
      }
    }

### Node.js


Before trying this sample, follow the Node.js setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Node.js API
reference documentation](https://docs.cloud.google.com/nodejs/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const instanceName = 'YOUR_INSTANCE_NAME';
    // const newMemory = 256;

    const compute = require('https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html');

    async function modifyInstanceWithExtendedMemory() {
      const instancesClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      const [instance] = await instancesClient.get({
        project: projectId,
        zone,
        instance: instanceName,
      });

      if (
        !['machineTypes/n1-', 'machineTypes/n2-', 'machineTypes/n2d-'].some(
          type => instance.machineType.includes(type)
        )
      ) {
        throw new Error('extra memory is available only for N1, N2 and N2D CPUs');
      }

      // Make sure that the machine is turned off
      if (!['TERMINATED', 'STOPPED'].some(status => instance.status === status)) {
        const [response] = await instancesClient.stop({
          project: projectId,
          zone,
          instance: instanceName,
        });

        let operation = response.latestResponse;
        const operationsClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

        // Wait for the stop operation to complete.
        while (operation.status !== 'DONE') {
          [operation] = await operationsClient.wait({
            operation: operation.name,
            project: projectId,
            zone: operation.zone.split('/').pop(),
          });
        }
      }

      // Modify the machine definition, remember that extended memory
      // is available only for N1, N2 and N2D CPUs

      const start = instance.machineType.substring(
        0,
        instance.machineType.lastIndexOf('-')
      );

      const [response] = await instancesClient.setMachineType({
        project: projectId,
        zone,
        instance: instanceName,
        instancesSetMachineTypeRequestResource: {
          machineType: `${start}-${newMemory}-ext`,
        },
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.https://docs.cloud.google.com/nodejs/docs/reference/compute/latest/overview.html();

      // Wait for the update operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }

      console.log('Instance updated.');
    }

    modifyInstanceWithExtendedMemory();

### Python


Before trying this sample, follow the Python setup instructions in the
[Compute Engine quickstart using
client libraries](https://docs.cloud.google.com/compute/docs/api/using-libraries).


For more information, see the
[Compute Engine Python API
reference documentation](https://docs.cloud.google.com/python/docs/reference/compute/latest).


To authenticate to Compute Engine, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/compute/docs/authentication#client-libs).

    from __future__ import annotations

    import sys
    import time
    from typing import Any

    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import https://docs.cloud.google.com/python/docs/reference/compute/latest


    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.

        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.

        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.

        Returns:
            Whatever the operation.result() returns.

        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.

            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)

        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)

        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

        return result


    def add_extended_memory_to_instance(
        project_id: str, zone: str, instance_name: str, new_memory: int
    ):
        """
        Modify an existing VM to use extended memory.

        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            new_memory: the amount of memory for the VM instance, in megabytes.

        Returns:
            Instance object.
        """
        instance_client = https://docs.cloud.google.com/python/docs/reference/compute/latest.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html()
        instance = instance_client.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html#google_cloud_compute_v1_services_instances_InstancesClient_get(
            project=project_id, zone=zone, instance=instance_name
        )

        if not (
            "n1-" in instance.machine_type
            or "n2-" in instance.machine_type
            or "n2d-" in instance.machine_type
        ):
            raise RuntimeError("Extra memory is available only for N1, N2 and N2D CPUs.")

        # Make sure that the machine is turned off
        if instance.status not in (
            instance.Status.TERMINATED.name,
            instance.Status.STOPPED.name,
        ):
            operation = instance_client.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html#google_cloud_compute_v1_services_instances_InstancesClient_stop(
                project=project_id, zone=zone, instance=instance_name
            )
            wait_for_extended_operation(operation, "instance stopping")
            start = time.time()
            while instance.status not in (
                instance.Status.TERMINATED.name,
                instance.Status.STOPPED.name,
            ):
                # Waiting for the instance to be turned off.
                instance = instance_client.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html#google_cloud_compute_v1_services_instances_InstancesClient_get(
                    project=project_id, zone=zone, instance=instance_name
                )
                time.sleep(2)
                if time.time() - start >= 300:  # 5 minutes
                    raise TimeoutError()

        # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
        start, end = instance.machine_type.rsplit("-", maxsplit=1)
        instance.machine_type = start + f"-{new_memory}-ext"
        # TODO: If you prefer to use the CustomMachineType helper class, uncomment this code and comment the 2 lines above
        # Using CustomMachineType helper
        # cmt = CustomMachineType.from_str(instance.machine_type)
        # cmt.memory_mb = new_memory
        # cmt.extra_memory_used = True
        # instance.machine_type = str(cmt)
        operation = instance_client.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html#google_cloud_compute_v1_services_instances_InstancesClient_update(
            project=project_id,
            zone=zone,
            instance=instance_name,
            instance_resource=instance,
        )
        wait_for_extended_operation(operation, "instance update")

        return instance_client.https://docs.cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.services.instances.InstancesClient.html#google_cloud_compute_v1_services_instances_InstancesClient_get(project=project_id, zone=zone, instance=instance_name)

### REST

1. Stop the VM by calling the [`instances.stop` method](https://docs.cloud.google.com/compute/docs/reference/latest/instances/stop).
2. Update the machine type resources by calling the
   [`instances.setMachineType`
   method](https://docs.cloud.google.com/compute/docs/reference/latest/instances/setMachineType) and
   specifying the `-ext` suffix in the `machineType` field:

       POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/setMachineType

       {
         "machineType": "zones/ZONE/machineTypes/MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext"
       }

   Replace the following:
   - `PROJECT_ID`: the ID of the project that contains the VM.
   - `ZONE`: the zone where the VM is located.
   - `INSTANCE_NAME`: the name of the VM.
   - `MACHINE_SERIES`: the lowercase machine series, such as `n4`, `n4d`, `n4a`, `n2`, or `n2d`. For N1, omit `MACHINE_SERIES-` and start with `custom-`.
   - `NUMBER_OF_VCPUS`: the number of vCPUs.
   - `AMOUNT_OF_MEMORY_MB`: the total amount of memory in MB. This value must be an integer multiple of 256 MB.
3. Restart the VM by calling the
   [`instances.start`
   method](https://docs.cloud.google.com/compute/docs/reference/latest/instances/start).

## What's next

- Learn more about [machine families](https://docs.cloud.google.com/compute/docs/machine-resource).
- After creating a VM, complete a [tutorial](https://docs.cloud.google.com/compute/docs#training-and-tutorials) to start using a VM instance.
- Learn how to [connect to your VM instance](https://docs.cloud.google.com/compute/docs/instances/connecting-to-instance).