Clean up auto region selection experiment (#51121)

## Context

Just cleans up the experiment that was introduced
[here](https://github.com/supabase/supabase/issues/50851) - can clean up
feature flag in ConfigCat thereafter too

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Project Creation**
* Removed the “Best available” region option. Choose a specific region
or smart group when creating a project; the selected region name appears
in the selector.
  * Recommended badges remain visible on recommended regions.
* **Telemetry**
* Project creation events no longer include details about the removed
region option or the initial region recommendation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Joshen Lim authored and GitHub committed 2026-10-05 12:13:11 +08:00
1 parent 39e13d3181
commit 94b8b06eb2
7 files changed
+16 -239

No files matched your search

@@ -11,7 +11,6 @@ import {
getAvailableRegions,
getHighAvailabilityRegionCode,
resolveDefaultDbRegion,
resolveSelectedRegionOptionType,
} from './ProjectCreation.utils'
describe('resolveDefaultDbRegion', () => {
@@ -70,55 +69,6 @@ describe('resolveDefaultDbRegion', () => {
})
})
describe('resolveSelectedRegionOptionType', () => {
const smartGroupRegions = [{ name: 'Americas' }, { name: 'APAC' }]
const specificRegions = [{ name: 'ap-southeast-1' }, { name: 'us-east-1' }]
it('returns general when the "Best available region" shortcut was used', () => {
expect(
resolveSelectedRegionOptionType({
isBestAvailableSelected: true,
dbRegion: 'ap-southeast-1',
smartGroupRegions,
specificRegions,
})
).toBe('general')
})
it('returns general when the region was picked from the smart group list', () => {
expect(
resolveSelectedRegionOptionType({
isBestAvailableSelected: false,
dbRegion: 'Americas',
smartGroupRegions,
specificRegions,
})
).toBe('general')
})
it('returns specific when the region was picked from the specific regions list', () => {
expect(
resolveSelectedRegionOptionType({
isBestAvailableSelected: false,
dbRegion: 'ap-southeast-1',
smartGroupRegions,
specificRegions,
})
).toBe('specific')
})
it('returns undefined when the region matches neither list', () => {
expect(
resolveSelectedRegionOptionType({
isBestAvailableSelected: false,
dbRegion: undefined,
smartGroupRegions,
specificRegions,
})
).toBeUndefined()
})
})
describe('getAvailableRegions', () => {
it.each(['local', 'staging', 'prod'])('returns all AWS regions for AWS on %s', (environment) => {
expect(getAvailableRegions('AWS', environment)).toEqual(AWS_REGIONS)
@@ -68,26 +68,6 @@ export function resolveDefaultDbRegion({
: fixedDefaultRegion
}
type ResolveSelectedRegionOptionTypeArgs = {
isBestAvailableSelected: boolean
dbRegion: string | undefined
smartGroupRegions: Array<{ name: string }>
specificRegions: Array<{ name: string }>
}
export function resolveSelectedRegionOptionType({
isBestAvailableSelected,
dbRegion,
smartGroupRegions,
specificRegions,
}: ResolveSelectedRegionOptionTypeArgs): 'general' | 'specific' | undefined {
// The "Best available region" shortcut always resolves to a smart-group recommendation
if (isBestAvailableSelected) return 'general'
if (smartGroupRegions.some((region) => region.name === dbRegion)) return 'general'
if (specificRegions.some((region) => region.name === dbRegion)) return 'specific'
return undefined
}
/**
* When launching new projects, they only get assigned a compute size once successfully launched,
* this might assume wrong compute size, but only for projects being rapidly launched after one another on non-default compute sizes.
@@ -35,7 +35,6 @@ import {
instanceLabel,
monthlyInstancePrice,
resolveDefaultDbRegion,
resolveSelectedRegionOptionType,
smartRegionToExactRegion,
} from './ProjectCreation.utils'
import { ProjectCreationFooter } from './ProjectCreationFooter'
@@ -143,18 +142,6 @@ export const ProjectCreationForm = ({
useFlag('newProjectInternalOnlyConfiguration') && !isVercelIntegrationFlow
const { getRegionRestriction } = useRegionRestriction()
// [Joshen] Temp experiment - to clean up once completed
const showBestAvailableRegionFeature = useIsFeatureEnabled(
'project_creation:show_best_available_region'
)
const showBestAvailableRegionFlag = useFlag('showBestAvailableRegion')
const showBestAvailableRegionOption =
showBestAvailableRegionFeature && showBestAvailableRegionFlag && isFreePlan
const [isBestAvailableSelected, setIsBestAvailableSelected] = useState(false)
const shouldTrackRegionRecommendation = isFreePlan && showBestAvailableRegionFeature
const initialRecommendedRegionRef = useRef<string | undefined>(undefined)
// Read the raw flag for telemetry — coerce-undefined-to-false would record false for
// users whose flags haven't loaded yet. The raw value preserves undefined (omitted from
// PostHog) so we only record an actual value (boolean true/false, or a variant string
@@ -309,16 +296,6 @@ export const ProjectCreationForm = ({
? availableRegionsData?.recommendations.smartGroup.name
: ''
if (
initialRecommendedRegionRef.current === undefined &&
flagsLoaded &&
shouldTrackRegionRecommendation
) {
initialRecommendedRegionRef.current = showBestAvailableRegionOption
? 'best_available'
: recommendedSmartRegion || undefined
}
const fixedDefaultRegion = PROVIDERS[selectedCloudProvider].default_region.displayName
const regionError = smartRegionEnabled ? availableRegionsError : defaultRegionError
const defaultRegion = resolveDefaultDbRegion({
@@ -371,15 +348,6 @@ export const ProjectCreationForm = ({
} = useProjectCreateMutation({
onSuccess: (res) => {
setProjectCreationError(undefined)
const { smartGroup = [], specific = [] } = availableRegionsData?.all ?? {}
const submittedDbRegion = form.getValues('dbRegion')
const selectedRegionOption = isBestAvailableSelected ? 'best_available' : submittedDbRegion
const selectedRegionOptionType = resolveSelectedRegionOptionType({
isBestAvailableSelected,
dbRegion: submittedDbRegion,
smartGroupRegions: smartGroup,
specificRegions: specific,
})
track(
'project_creation_simple_version_submitted',
{
@@ -392,11 +360,6 @@ export const ProjectCreationForm = ({
...(dataApiRevokeOnCreateDefaultFlag !== undefined && {
dataApiRevokeOnCreateDefaultEnabled: dataApiRevokeOnCreateDefaultFlag,
}),
...(shouldTrackRegionRecommendation && {
selectedRegionOption,
selectedRegionOptionType,
initialRecommendedRegion: initialRecommendedRegionRef.current,
}),
},
{
project: res.ref,
@@ -818,9 +781,6 @@ export const ProjectCreationForm = ({
form={form}
hasSelectedOrganization={hasSelectedOrganization}
instanceSize={instanceSize as DesiredInstanceSize}
showBestAvailableRegionOption={showBestAvailableRegionOption}
isBestAvailableSelected={isBestAvailableSelected}
onBestAvailableSelectedChange={setIsBestAvailableSelected}
/>
{isVercelIntegrationFlow && !!externalId && <DataSeeding form={form} />}
@@ -1,5 +1,5 @@
import { useFeatureFlags, useFlag, useParams } from 'common'
import { Loader2, ThumbsUp } from 'lucide-react'
import { Loader2 } from 'lucide-react'
import { useEffect, useRef } from 'react'
import { UseFormReturn } from 'react-hook-form'
import type { CloudProvider } from 'shared-data'
@@ -51,9 +51,6 @@ interface RegionSelectorProps {
hasSelectedOrganization: boolean
instanceSize?: DesiredInstanceSize
layout?: 'vertical' | 'horizontal'
showBestAvailableRegionOption: boolean
isBestAvailableSelected: boolean
onBestAvailableSelectedChange: (value: boolean) => void
}
// [Joshen] Let's use a library to maintain the flag SVGs in the future
@@ -70,20 +67,11 @@ const getDisplayNameForSmartRegion = (name: string): string => {
const isLocal = process.env.NEXT_PUBLIC_ENVIRONMENT === 'local'
const BestAvailableRegionIcon = () => (
<div className="w-5 border border-brand-500 h-4.5 rounded-[3px] bg-brand-300 flex items-center justify-center">
<ThumbsUp size={10} className="text-brand" />
</div>
)
export const RegionSelector = ({
form,
hasSelectedOrganization,
instanceSize,
layout = 'horizontal',
showBestAvailableRegionOption,
isBestAvailableSelected,
onBestAvailableSelectedChange,
}: RegionSelectorProps) => {
const { slug } = useParams()
const cloudProvider = form.getValues('cloudProvider') as CloudProvider
@@ -127,32 +115,6 @@ export const RegionSelector = ({
const recommendedSmartRegions = new Set(
[availableRegionsData?.recommendations.smartGroup.code].filter(Boolean)
)
const recommendedSmartRegion = smartRegions.find(
(x) => x.code === recommendedSmartRegions.values().next().value
)
const isBestAvailableOptionShown = showBestAvailableRegionOption && !!recommendedSmartRegion
const isBestAvailableActive = isBestAvailableSelected && isBestAvailableOptionShown
// Defaults free orgs to the "Best available region" shortcut once the recommendation loads,
// unless the user has already interacted with the region field themselves.
const hasUserSelectedRegionRef = useRef(false)
useEffect(() => {
if (hasUserSelectedRegionRef.current) return
if (isBestAvailableOptionShown) {
onBestAvailableSelectedChange(true)
}
}, [isBestAvailableOptionShown, onBestAvailableSelectedChange])
// Keeps dbRegion following the recommendation while "Best available" is active, so a
// recommendation change (e.g. after a refetch) doesn't leave the form submitting a stale
// region behind a label that still reads "Auto".
useEffect(() => {
if (!isBestAvailableSelected || !recommendedSmartRegion) return
if (dbRegion !== recommendedSmartRegion.name) {
form.setValue('dbRegion', recommendedSmartRegion.name)
}
}, [isBestAvailableSelected, recommendedSmartRegion, dbRegion, form])
const recommendedSpecificRegions = new Set(
availableRegionsData?.recommendations.specific.map((region) => region.code)
@@ -234,11 +196,7 @@ export const RegionSelector = ({
selectedRestriction !== undefined
? getRegionRestrictionCopy(selectedRestriction)
: undefined
const triggerLabel = isLoading
? 'Loading available regions...'
: isBestAvailableActive
? 'Auto'
: selectedRegionLabel
const triggerLabel = isLoading ? 'Loading available regions...' : selectedRegionLabel
const affectingIncidents = incidents.filter((incident) => {
const affectedRegions = incident.cache?.affected_regions ?? []
@@ -280,18 +238,10 @@ export const RegionSelector = ({
>
<FormControl>
<Select
value={isBestAvailableActive ? 'best_available' : dbRegion}
value={dbRegion}
onValueChange={(value) => {
if (value === '') return
hasUserSelectedRegionRef.current = true
if (value === 'best_available') {
if (!recommendedSmartRegion) return
onBestAvailableSelectedChange(true)
field.onChange(recommendedSmartRegion.name)
} else {
onBestAvailableSelectedChange(false)
field.onChange(value)
}
field.onChange(value)
}}
disabled={isLoading}
>
@@ -310,12 +260,8 @@ export const RegionSelector = ({
{dbRegion !== undefined && (
<div className="flex items-center gap-x-3">
{isLoading && <Loader2 size={14} className="animate-spin" />}
{isBestAvailableActive ? (
<BestAvailableRegionIcon />
) : (
selectedRegion?.code && (
<RegionFlag className="w-5" region={selectedRegion.code} />
)
{selectedRegion?.code && (
<RegionFlag className="w-5" region={selectedRegion.code} />
)}
<span className="text-foreground">{triggerLabel}</span>
</div>
@@ -323,28 +269,6 @@ export const RegionSelector = ({
</SelectValue>
</SelectTrigger>
<SelectContent>
{isBestAvailableOptionShown && (
<>
<SelectGroup>
<SelectLabel>Recommendation</SelectLabel>
<SelectItem
value="best_available"
className="w-full [&>:nth-child(2)]:w-full"
>
<div className="flex flex-row items-center justify-between w-full">
<div className="flex items-center gap-x-3">
<BestAvailableRegionIcon />
<span className="text-foreground">Auto</span>
</div>
<Badge variant="success" className="mr-1">
Recommended
</Badge>
</div>
</SelectItem>
</SelectGroup>
<SelectSeparator />
</>
)}
{smartRegionEnabled && !highAvailability && (
<>
<SelectGroup>
@@ -365,12 +289,11 @@ export const RegionSelector = ({
</div>
<div>
{!isBestAvailableOptionShown &&
recommendedSmartRegions.has(value.code) && (
<Badge variant="success" className="mr-1">
Recommended
</Badge>
)}
{recommendedSmartRegions.has(value.code) && (
<Badge variant="success" className="mr-1">
Recommended
</Badge>
)}
</div>
</div>
</SelectItem>
@@ -410,12 +333,11 @@ export const RegionSelector = ({
</div>
</div>
{!isBestAvailableOptionShown &&
recommendedSpecificRegions.has(value.code) && (
<Badge variant="success" className="mr-1">
Recommended
</Badge>
)}
{recommendedSpecificRegions.has(value.code) && (
<Badge variant="success" className="mr-1">
Recommended
</Badge>
)}
{restrictionCopy !== undefined && (
<Tooltip>
@@ -103,7 +103,6 @@
"project_creation:show_advanced_config": true,
"project_creation:show_high_availability": true,
"project_creation:show_best_available_region": true,
"project_homepage:show_instance_size": true,
"project_homepage:show_examples": true,
@@ -358,10 +358,6 @@
"type": "boolean",
"description": "Show the high availability toggle in the project creation flow"
},
"project_creation:show_best_available_region": {
"type": "boolean",
"description": "Show the best available region option in the project creation region selector"
},
"project_homepage:show_instance_size": {
"type": "boolean",
-30
View File
@@ -449,36 +449,6 @@ export interface ProjectCreationSimpleVersionSubmittedEvent {
* omitted = PostHog flags had not loaded at the time of project creation
*/
dataApiRevokeOnCreateDefaultEnabled?: boolean | string
/**
* Which region option was submitted. Only present for the region-recommendation experiment's
* eligible cohort (free plan + `project_creation:show_best_available_region` feature enabled —
* see `shouldTrackRegionRecommendation` in ProjectCreationForm.tsx). This is cohort-level
* eligibility, not "the option was shown" — it's present for both the PostHog flag's control
* and test arms so the two can be compared; omitted entirely outside the cohort (e.g. paid
* plans, or providers like AWS_NIMBUS where the feature is disabled).
* 'best_available' = the "Best available region" shortcut was used
* otherwise = the name of the region that was directly selected (e.g. 'Americas', 'ap-southeast-1')
*/
selectedRegionOption?: string
/**
* Which region list `selectedRegionOption` came from. Only present alongside `selectedRegionOption`.
* 'general' = picked from the "General regions" (smart group) list, or the "Best available
* region" shortcut was used (it always resolves to a general/smart region)
* 'specific' = picked from the "Specific regions" list
*/
selectedRegionOptionType?: 'general' | 'specific'
/**
* The region that was recommended/defaulted to on initial render, before any user
* interaction. Present under the same cohort gate as `selectedRegionOption`. Frozen the
* first time it's known, so a later refetch (e.g. switching cloud provider or instance size)
* doesn't overwrite what was actually shown to the user initially.
* 'best_available' = the user was in the PostHog flag's test arm, so the form defaulted to
* the "Best available region" shortcut
* otherwise = the name of the smart-group region recommended by the `available-regions`
* endpoint (e.g. 'Americas'), for users in the flag's control arm
* undefined = no recommendation had loaded yet at submission time
*/
initialRecommendedRegion?: string
}
groups: TelemetryGroups
}