Home / Function/ CreateDiskStorageSchema() — supabase Function Reference

CreateDiskStorageSchema() — supabase Function Reference

Architecture documentation for the CreateDiskStorageSchema() function in DiskManagement.schema.ts from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  36093eba_fdee_f0d6_0930_e23cece03c50["CreateDiskStorageSchema()"]
  3f4f7d35_5d3a_08a8_61c4_a4247033eecf["DiskManagementForm()"]
  3f4f7d35_5d3a_08a8_61c4_a4247033eecf -->|calls| 36093eba_fdee_f0d6_0930_e23cece03c50
  b0d5ba92_ed17_8ca3_6b79_fef306286c41["formatNumber()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| b0d5ba92_ed17_8ca3_6b79_fef306286c41
  286185f2_a0d5_3bed_586f_a6483e3bd18b["calculateMaxIopsAllowedForDiskSizeWithio2()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| 286185f2_a0d5_3bed_586f_a6483e3bd18b
  1a66cb37_05e5_394e_2484_4199b74f69f6["calculateDiskSizeRequiredForIopsWithIo2()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| 1a66cb37_05e5_394e_2484_4199b74f69f6
  cac598b1_693b_5720_2c5f_1d7f69273afa["calculateMaxIopsAllowedForDiskSizeWithGp3()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| cac598b1_693b_5720_2c5f_1d7f69273afa
  bcf3f3d3_327f_5b50_b77a_871e76fd2766["calculateDiskSizeRequiredForIopsWithGp3()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| bcf3f3d3_327f_5b50_b77a_871e76fd2766
  b1a22ce9_2609_ba8f_e6e9_b726bb60d6ce["calculateMaxThroughput()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| b1a22ce9_2609_ba8f_e6e9_b726bb60d6ce
  81a71f38_083d_a4ab_ddc1_dab10727bc6a["calculateIopsRequiredForThroughput()"]
  36093eba_fdee_f0d6_0930_e23cece03c50 -->|calls| 81a71f38_083d_a4ab_ddc1_dab10727bc6a
  style 36093eba_fdee_f0d6_0930_e23cece03c50 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/DiskManagement/DiskManagement.schema.ts lines 46–235

export const CreateDiskStorageSchema = ({
  defaultTotalSize,
  cloudProvider,
}: {
  defaultTotalSize: number
  cloudProvider: CloudProvider
}) => {
  const isFlyProject = cloudProvider === 'FLY'
  const isAwsNimbusProject = cloudProvider === 'AWS_NIMBUS'
  const isAwsK8sProject = cloudProvider === 'AWS_K8S'

  const validateDiskConfiguration = !isFlyProject && !isAwsNimbusProject && !isAwsK8sProject

  const schema = baseSchema.superRefine((data, ctx) => {
    const { storageType, totalSize, provisionedIOPS, throughput, maxSizeGb, computeSize } = data
    const computeMaxIops = (() => {
      const parsedCompute = computeInstanceAddonVariantIdSchema.safeParse(computeSize)
      if (!parsedCompute.success) return Number.POSITIVE_INFINITY
      return COMPUTE_MAX_IOPS[parsedCompute.data] ?? Number.POSITIVE_INFINITY
    })()

    if (validateDiskConfiguration && totalSize < 8) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: 'Allocated disk size must be at least 8 GB.',
        path: ['totalSize'],
      })
    }

    if (validateDiskConfiguration && totalSize < defaultTotalSize) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: `Disk size cannot be reduced in size. Reduce your database size and then head to the Infrastructure settings and go through a Postgres version upgrade to right-size your disk.`,
        path: ['totalSize'],
      })
    }

    // Validate maxSizeGb cannot be lower than totalSize
    if (validateDiskConfiguration && !!maxSizeGb && maxSizeGb < totalSize) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: `Max disk size cannot be lower than the current disk size. Must be at least ${formatNumber(totalSize)} GB.`,
        path: ['maxSizeGb'],
      })
    }

    if (validateDiskConfiguration && storageType === 'io2') {
      // Validation rules for io2

      const maxIopsForIo2 = Math.min(DISK_LIMITS[DiskType.IO2].maxIops, computeMaxIops)
      if (provisionedIOPS > maxIopsForIo2) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `IOPS cannot exceed ${formatNumber(maxIopsForIo2)} for io2 Disk type and the selected compute size.`,
          path: ['provisionedIOPS'],
        })
      }

      const maxIOPSforDiskSizeWithio2 = calculateMaxIopsAllowedForDiskSizeWithio2(totalSize)

      if (provisionedIOPS < DISK_LIMITS[DiskType.IO2].minIops) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `Provisioned IOPS must be at least ${formatNumber(DISK_LIMITS[DiskType.IO2].minIops)}`,
          path: ['provisionedIOPS'],
        })
      } else if (provisionedIOPS > maxIOPSforDiskSizeWithio2) {
        if (totalSize >= 8) {
          const diskSizeRequiredForIopsWithIo2 =
            calculateDiskSizeRequiredForIopsWithIo2(provisionedIOPS)

          if (diskSizeRequiredForIopsWithIo2 > totalSize) {
            ctx.addIssue({
              code: z.ZodIssueCode.custom,
              message: `Larger Disk size of at least ${formatNumber(diskSizeRequiredForIopsWithIo2)} GB required. Current max is ${formatNumber(maxIOPSforDiskSizeWithio2)} IOPS.`,
              path: ['provisionedIOPS'],
            })
          }
        } else {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Invalid IOPS value due to small disk size`,
            path: ['provisionedIOPS'],
          })
        }
      }

      if (throughput !== undefined) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: 'Throughput is not configurable for io2.',
          path: ['throughput'],
        })
      }

      if (totalSize > DISK_LIMITS[DiskType.IO2].maxStorage) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `Allocated disksize must not exceed ${formatNumber(DISK_LIMITS[DiskType.IO2].maxStorage)} GB `,
          path: ['totalSize'],
        })
      }
    }

    if (validateDiskConfiguration && storageType === 'gp3') {
      const maxIopsAllowedForDiskSizeWithGp3 = calculateMaxIopsAllowedForDiskSizeWithGp3(totalSize)
      const maxIopsForGp3 = Math.min(DISK_LIMITS[DiskType.GP3].maxIops, computeMaxIops)
      const computeMaxThroughput = (() => {
        const parsedCompute = computeInstanceAddonVariantIdSchema.safeParse(computeSize)
        if (!parsedCompute.success) return DISK_LIMITS[DiskType.GP3].maxThroughput
        return COMPUTE_MAX_THROUGHPUT[parsedCompute.data] ?? DISK_LIMITS[DiskType.GP3].maxThroughput
      })()

      if (provisionedIOPS > maxIopsForGp3) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `IOPS cannot exceed ${formatNumber(maxIopsForGp3)} for GP3 Disk and the selected compute size.`,
          path: ['provisionedIOPS'],
        })
      }

      if (provisionedIOPS < DISK_LIMITS[DiskType.GP3].minIops) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `IOPS must be at least ${formatNumber(DISK_LIMITS[DiskType.GP3].minIops)}`,
          path: ['provisionedIOPS'],
        })
      } else if (provisionedIOPS > maxIopsAllowedForDiskSizeWithGp3) {
        if (totalSize >= 8) {
          const diskSizeRequiredForIopsWithGp3 =
            calculateDiskSizeRequiredForIopsWithGp3(provisionedIOPS)

          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Larger Disk size of at least ${formatNumber(diskSizeRequiredForIopsWithGp3)} GB required. Current max is ${formatNumber(maxIopsAllowedForDiskSizeWithGp3)} IOPS.`,
            path: ['provisionedIOPS'],
          })
        } else {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Invalid IOPS value due to invalid disk size`,
            path: ['provisionedIOPS'],
          })
        }
      }

      if (throughput !== undefined) {
        // gp3 throughput scales with provisioned IOPS (capped by gp3 max)
        const iopsThroughputLimit = calculateMaxThroughput(provisionedIOPS)
        if (throughput > DISK_LIMITS[DiskType.GP3].maxThroughput) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Throughput cannot exceed ${formatNumber(DISK_LIMITS[DiskType.GP3].maxThroughput)} MB/s for GP3 disk type.`,
            path: ['throughput'],
          })
        } else if (throughput > computeMaxThroughput) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Throughput cannot exceed ${formatNumber(computeMaxThroughput)} MB/s for the selected compute size.`,
            path: ['throughput'],
          })
        } else if (throughput > iopsThroughputLimit) {
          const iopsRequiredForThroughput = calculateIopsRequiredForThroughput(throughput)
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Need at least ${formatNumber(iopsRequiredForThroughput)} IOPS to support ${formatNumber(throughput)} MB/s.`,
            path: ['throughput'],
          })
        }
        if (throughput < DISK_LIMITS[DiskType.GP3].minThroughput) {
          ctx.addIssue({
            code: z.ZodIssueCode.custom,
            message: `Throughput must be at least ${formatNumber(DISK_LIMITS[DiskType.GP3].minThroughput)} MB/s`,
            path: ['throughput'],
          })
        }
      }

      if (totalSize > DISK_LIMITS[DiskType.GP3].maxStorage) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: `Allocated disksize must not exceed ${formatNumber(DISK_LIMITS[DiskType.GP3].maxStorage)} GB`,
          path: ['totalSize'],
        })
      }
    }
  })

  return schema
}

Subdomains

Frequently Asked Questions

What does CreateDiskStorageSchema() do?
CreateDiskStorageSchema() is a function in the supabase codebase.
What does CreateDiskStorageSchema() call?
CreateDiskStorageSchema() calls 7 function(s): calculateDiskSizeRequiredForIopsWithGp3, calculateDiskSizeRequiredForIopsWithIo2, calculateIopsRequiredForThroughput, calculateMaxIopsAllowedForDiskSizeWithGp3, calculateMaxIopsAllowedForDiskSizeWithio2, calculateMaxThroughput, formatNumber.
What calls CreateDiskStorageSchema()?
CreateDiskStorageSchema() is called by 1 function(s): DiskManagementForm.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free