Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions apps/docs/content/guides/platform/compute-and-disk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ Be aware that increasing IOPS or throughput incurs additional charges.

When selecting your disk, it's essential to focus on the performance needs of your workload. Here's a comparison of our available disk types:

| | General Purpose SSD (gp3) | High Performance SSD (io2) |
| ----------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| **Use Case** | General workloads, development environments, small to medium databases | High-performance needs, large-scale databases, mission-critical applications |
| **Max Disk Size** | 16 TB | 60 TB |
| **Max IOPS** | 16,000 IOPS (at 32 GB disk size) | 80,000 IOPS (at 80 GB disk size) |
| **Throughput** | 125 MiB/s (default) to 1,000 MiB/s (maximum) | Automatically scales with IOPS |
| **Best For** | Great value for most use cases | Low latency and very high IOPS requirements |
| | General Purpose SSD (gp3) | High Performance SSD (io2) |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **Use Case** | General workloads, development environments, small to medium databases | High-performance needs, large-scale databases, mission-critical applications |
| **Max Disk Size** | 16 TB | 60 TB |
| **Max IOPS** | 16,000 IOPS (at 32 GB disk size) | 80,000 IOPS (at 80 GB disk size) |
| **Throughput** | 125 MiB/s (default) to 1,000 MiB/s (maximum) | Automatically scales with IOPS |
| **Best For** | Great value for most use cases | Low latency and very high IOPS requirements |
| **Pricing** | Disk: 8 GB included, then $0.125 per GB<br/>IOPS: 3,000 included, then $0.024 per IOPS<br/>Throughput: 125 Mbps included, then $0.95 per Mbps | Disk: $0.195 per GB<br/>IOPS: $0.119 per IOPS<br/>Throughput: Scales with IOPS at no additional cost |

For general, day-to-day operations, gp3 should be more than enough. If you need high throughput and IOPS for critical systems, io2 will provide the performance required.

Expand Down
14 changes: 14 additions & 0 deletions apps/docs/content/guides/platform/database-size.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,22 @@ Once you have reclaimed space, you can run the following to disable [read-only](
set default_transaction_read_only = 'off';
```

### Disk Size Distribution

You can check the distribution of your disk size on your [project's compute and disk page](/dashboard/_/settings/compute-and-disk).

![Disk Size Distribution](/docs/img/guides/platform/database-size/disk-size-distribution.png)

Your disk size usage falls in three categories:

- **Database** - Disk usage by the database. This includes the actual data, indexes, materialized views, ...
- **WAL** - Disk usage by the write-ahead log. The usage depends on your WAL settings and the amount of data being written to the database.
- **System** - Disk usage reserved by the system to ensure the database can operate smoothly. Users cannot modify this and it should only take very little space.

### Reducing disk size

Disks don't automatically downsize during normal operation. Once you have [reduced your database size](/docs/guides/platform/database-size#database-size), they _will_ automatically "right-size" during a [project upgrade](/docs/guides/platform/upgrading). The final disk size after the upgrade is 1.2x the size of the database with a minimum of 8 GB. For example, if your database size is 100GB, and you have a 200GB disk, the size after a project upgrade will be 120 GB.

In case you have a large WAL directory, you may [modify WAL settings](/docs/guides/database/custom-postgres-config) such as `max_wal_size`. Use at your own risk as changing these settings can have side effects. To query your current WAL size, use `SELECT SUM(size) FROM pg_ls_waldir()`.

In the event that your project is already on the latest version of Postgres and cannot be upgraded, a new version of Postgres will be released approximately every week which you can then upgrade to once it becomes available.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
import { CodeBlockLang } from 'ui'

export type DatabaseConnectionType =
| 'uri'
| 'psql'
| 'golang'
| 'jdbc'
| 'dotnet'
| 'nodejs'
| 'php'
| 'python'
| 'sqlalchemy'

export const DATABASE_CONNECTION_TYPES: {
id: DatabaseConnectionType
label: string
contentType: 'input' | 'code'
lang: CodeBlockLang
fileTitle: string | undefined
}[] = [
{ id: 'uri', label: 'URI', contentType: 'input', lang: 'bash', fileTitle: undefined },
{ id: 'psql', label: 'PSQL', contentType: 'code', lang: 'bash', fileTitle: undefined },
{ id: 'golang', label: 'Golang', contentType: 'code', lang: 'go', fileTitle: '.env' },
{ id: 'jdbc', label: 'JDBC', contentType: 'input', lang: 'bash', fileTitle: undefined },
{
id: 'dotnet',
label: '.NET',
contentType: 'code',
lang: 'csharp',
fileTitle: 'appsettings.json',
},
{ id: 'nodejs', label: 'Node.js', contentType: 'code', lang: 'js', fileTitle: '.env' },
{ id: 'php', label: 'PHP', contentType: 'code', lang: 'php', fileTitle: '.env' },
{ id: 'python', label: 'Python', contentType: 'code', lang: 'python', fileTitle: '.env' },
{ id: 'sqlalchemy', label: 'SQLAlchemy', contentType: 'code', lang: 'python', fileTitle: '.env' },
]

export const CONNECTION_PARAMETERS = {
host: {
key: 'host',
description: 'The hostname of your database',
},
port: {
key: 'port',
description: 'Port number for the connection',
},
database: {
key: 'database',
description: 'Default database name',
},
user: {
key: 'user',
description: 'Database user',
},
pool_mode: {
key: 'pool_mode',
description: 'Connection pooling behavior',
},
} as const

export type ConnectionType = {
key: string
icon: string
Expand Down Expand Up @@ -283,6 +343,7 @@ export const ORMS: ConnectionType[] = [
]

export const CONNECTION_TYPES = [
{ key: 'direct', label: 'Connection String', obj: [] },
{ key: 'frameworks', label: 'App Frameworks', obj: FRAMEWORKS },
{ key: 'mobiles', label: 'Mobile Frameworks', obj: MOBILES },
{ key: 'orms', label: 'ORMs', obj: ORMS },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import { useParams } from 'common'
import { ExternalLink, Plug } from 'lucide-react'
import { useState } from 'react'

import { DatabaseConnectionString } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseConnectionString'
import { PoolingModesModal } from 'components/interfaces/Settings/Database/PoolingModesModal'
import { DatabaseConnectionString } from 'components/interfaces/Connect/DatabaseConnectionString'
import { DatabaseConnectionString as OldDatabaseConnectionString } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseConnectionString'

import Panel from 'components/ui/Panel'
import { getAPIKeys, useProjectSettingsV2Query } from 'data/config/project-settings-v2-query'
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useFlag } from 'hooks/ui/useFlag'
import { useAppStateSnapshot } from 'state/app-state'
import {
Button,
DIALOG_PADDING_X,
DIALOG_PADDING_X_SMALL,
DIALOG_PADDING_Y,
Dialog,
DialogContent,
Expand All @@ -31,7 +33,9 @@ import ConnectDropdown from './ConnectDropdown'
import ConnectTabContent from './ConnectTabContent'

const Connect = () => {
const state = useAppStateSnapshot()
const { ref: projectRef } = useParams()
const connectDialogUpdate = useFlag('connectDialogUpdate')

const [connectionObject, setConnectionObject] = useState<ConnectionType[]>(FRAMEWORKS)
const [selectedParent, setSelectedParent] = useState(connectionObject[0].key) // aka nextjs
Expand Down Expand Up @@ -145,14 +149,18 @@ const Connect = () => {

return (
<>
<Dialog>
<Dialog open={state.showConnectDialog} onOpenChange={state.setShowConnectDialog}>
<DialogTrigger asChild>
<Button type="primary" icon={<Plug className="rotate-90" />}>
<Button
type={connectDialogUpdate ? 'default' : 'primary'}
className={cn(connectDialogUpdate && 'rounded-full')}
icon={<Plug className="rotate-90" />}
>
<span>Connect</span>
</Button>
</DialogTrigger>
<DialogContent className={cn('sm:max-w-5xl p-0')} centered={false}>
<DialogHeader className="pb-3">
<DialogHeader className={DIALOG_PADDING_X}>
<DialogTitle>Connect to your project</DialogTitle>
<DialogDescription>
Get the connection strings and environment variables for your app
Expand All @@ -163,10 +171,7 @@ const Connect = () => {
defaultValue="direct"
onValueChange={(value) => handleConnectionType(value)}
>
<TabsList_Shadcn_ className={cn('flex gap-4', DIALOG_PADDING_X_SMALL)}>
<TabsTrigger_Shadcn_ key="direct" value="direct" className="px-0">
Connection String
</TabsTrigger_Shadcn_>
<TabsList_Shadcn_ className={cn('flex gap-x-4', DIALOG_PADDING_X)}>
{CONNECTION_TYPES.map((type) => (
<TabsTrigger_Shadcn_ key={type.key} value={type.key} className="px-0">
{type.label}
Expand All @@ -183,14 +188,34 @@ const Connect = () => {
.find((parent) => parent.key === selectedParent)
?.children.find((child) => child.key === selectedChild)?.children.length || 0) > 0

if (type.key === 'direct') {
return (
<TabsContent_Shadcn_
key="direct"
value="direct"
className={cn('!mt-0', 'p-0', 'flex flex-col gap-6')}
>
<div className={DIALOG_PADDING_Y}>
{connectDialogUpdate ? (
<DatabaseConnectionString />
) : (
<div className="px-7">
<OldDatabaseConnectionString appearance="minimal" />
</div>
)}
</div>
</TabsContent_Shadcn_>
)
}

return (
<TabsContent_Shadcn_
key={`content-${type.key}`}
value={type.key}
className={cn(DIALOG_PADDING_X, DIALOG_PADDING_Y, '!mt-0')}
>
<div className="flex justify-between">
<div className="flex items-center gap-5">
<div className="flex items-center gap-3">
<ConnectDropdown
state={selectedParent}
updateState={handleParentChange}
Expand Down Expand Up @@ -254,17 +279,9 @@ const Connect = () => {
</TabsContent_Shadcn_>
)
})}
<TabsContent_Shadcn_
key="direct"
value="direct"
className={cn(DIALOG_PADDING_X_SMALL, DIALOG_PADDING_Y, '!mt-0')}
>
<DatabaseConnectionString appearance="minimal" />
</TabsContent_Shadcn_>
</Tabs_Shadcn_>
</DialogContent>
</Dialog>
<PoolingModesModal />
</>
)
}
Expand Down
98 changes: 98 additions & 0 deletions apps/studio/components/interfaces/Connect/ConnectDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Box, Check, ChevronDown } from 'lucide-react'
import { useState } from 'react'

import {
Button,
CommandEmpty_Shadcn_,
CommandGroup_Shadcn_,
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
cn,
} from 'ui'
import { ConnectionIcon } from './ConnectionIcon'

interface ConnectDropdownProps {
state: string
updateState: (state: string) => void
label: string
items: any[]
}

const ConnectDropdown = ({
state,
updateState,
label,

items,
}: ConnectDropdownProps) => {
const [open, setOpen] = useState(false)

function onSelectLib(key: string) {
updateState(key)
setOpen(false)
}

const selectedItem = items.find((item) => item.key === state)

return (
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={false}>
<div className="flex ">
<span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
{label}
</span>
<PopoverTrigger_Shadcn_ asChild>
<Button
size="small"
type="default"
className="gap-0 rounded-l-none"
iconRight={<ChevronDown strokeWidth={1.5} />}
>
<div className="flex items-center gap-2">
{selectedItem?.icon ? (
<ConnectionIcon connection={selectedItem.icon} />
) : (
<Box size={12} />
)}
{selectedItem?.label}
</div>
</Button>
</PopoverTrigger_Shadcn_>
</div>
<PopoverContent_Shadcn_ className="p-0 max-w-48" side="bottom" align="start">
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Search..." />
<CommandList_Shadcn_>
<CommandEmpty_Shadcn_>No results found.</CommandEmpty_Shadcn_>
<CommandGroup_Shadcn_>
{items.map((item) => (
<CommandItem_Shadcn_
key={item.key}
value={item.key}
onSelect={() => {
onSelectLib(item.key)
setOpen(false)
}}
className="flex gap-2 items-center"
>
{item.icon ? <ConnectionIcon connection={item.icon} /> : <Box size={12} />}
{item.label}
<Check
size={15}
className={cn('ml-auto ', item.key === state ? 'opacity-100' : 'opacity-0')}
/>
</CommandItem_Shadcn_>
))}
</CommandGroup_Shadcn_>
</CommandList_Shadcn_>
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
)
}

export default ConnectDropdown
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dynamic from 'next/dynamic'
import { forwardRef, HTMLAttributes } from 'react'
import { forwardRef, HTMLAttributes, useMemo } from 'react'

import { useParams } from 'common'
import { getConnectionStrings } from 'components/interfaces/Settings/Database/DatabaseSettings/DatabaseSettings.utils'
Expand Down Expand Up @@ -49,16 +49,15 @@ const ConnectTabContentNew = forwardRef<HTMLDivElement, ConnectContentTabProps>(
const connectionStringPoolerTransaction = connectionStringsPooler.uri
const connectionStringPoolerSession = connectionStringsPooler.uri.replace('6543', '5432')

const ContentFile = dynamic<ConnectContentTabProps>(
() => import(`./content/${filePath}/content`),
{
const ContentFile = useMemo(() => {
return dynamic<ConnectContentTabProps>(() => import(`./content/${filePath}/content`), {
loading: () => (
<div className="p-4 min-h-[331px]">
<GenericSkeletonLoader />
</div>
),
}
)
})
}, [filePath])

return (
<div ref={ref} {...props} className={cn('border rounded-lg', props.className)}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Tabs_Shadcn_ } from 'ui'
import { FileJson2 } from 'lucide-react'
import { TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui'
import { TabsContent_Shadcn_ } from 'ui'
import React, { ReactNode } from 'react'
import { isValidElement, ReactNode } from 'react'

import { Tabs_Shadcn_, TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui'

interface ConnectTabTriggerProps {
value: string
Expand All @@ -22,7 +21,7 @@ interface ConnectTabContentProps {
const ConnectTabs = ({ children }: ConnectFileTabProps) => {
const firstChild = children[0]

const defaultValue = React.isValidElement(firstChild)
const defaultValue = isValidElement(firstChild)
? (firstChild.props as any)?.children[0]?.props?.value || ''
: null

Expand Down Expand Up @@ -57,4 +56,4 @@ export const ConnectTabContent = ({ value, children }: ConnectTabContentProps) =
)
}

export { ConnectTabTrigger, ConnectTabTriggers, ConnectTabs }
export { ConnectTabs, ConnectTabTrigger, ConnectTabTriggers }
Loading
Loading