PoolingModesModal.tsx110 lines · main
1import { useParams } from 'common'
2import { AlertTriangleIcon } from 'lucide-react'
3import {
4 Alert,
5 AlertDescription,
6 AlertTitle,
7 Button,
8 Dialog,
9 DialogClose,
10 DialogContent,
11 DialogDescription,
12 DialogFooter,
13 DialogHeader,
14 DialogSection,
15 DialogSectionSeparator,
16 DialogTitle,
17} from 'ui'
18
19import { Markdown } from '@/components/interfaces/Markdown'
20import { DocsButton } from '@/components/ui/DocsButton'
21import { useSupavisorConfigurationQuery } from '@/data/database/supavisor-configuration-query'
22import { DOCS_URL } from '@/lib/constants'
23import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector'
24import { useDatabaseSettingsStateSnapshot } from '@/state/database-settings'
25
26export const PoolingModesModal = () => {
27 const { ref: projectRef } = useParams()
28 const snap = useDatabaseSettingsStateSnapshot()
29 const state = useDatabaseSelectorStateSnapshot()
30
31 const { data } = useSupavisorConfigurationQuery({ projectRef: projectRef })
32 const primaryConfig = data?.find((x) => x.identifier === state.selectedDatabaseId)
33
34 const navigateToPoolerSettings = () => {
35 const el = document.getElementById('connection-pooler')
36 if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' })
37 }
38
39 return (
40 <Dialog open={snap.showPoolingModeHelper} onOpenChange={snap.setShowPoolingModeHelper}>
41 <DialogContent hideClose className="sm:max-w-4xl">
42 <DialogHeader>
43 <DialogTitle>
44 <div className="w-full flex items-center justify-between">
45 <p className="max-w-2xl">Which pooling mode should I use?</p>
46 <DocsButton
47 href={`${DOCS_URL}/guides/database/connecting-to-postgres#how-connection-pooling-works`}
48 />
49 </div>
50 </DialogTitle>
51 <DialogDescription className="max-w-2xl">
52 A connection pooler is a system (external to Postgres) which manages Postgres
53 connections by allocating connections whenever clients make requests.
54 </DialogDescription>
55 </DialogHeader>
56 <DialogSectionSeparator />
57 <DialogSection>
58 <Markdown
59 className="max-w-full [&>h3]:text-sm"
60 content={`
61Each pooling mode handles connections differently.
62
63### Transaction mode
64This mode is recommended if you are connecting from *serverless environments*. A connection is assigned to the client for the duration of a transaction. Two consecutive transactions from the same client could be executed over two different connections. Some session-based Postgres features such as prepared statements are *not available* with this option.
65
66### Session mode
67This mode is similar to connecting to your database directly. There is full support for prepared statements in this mode. When a new client connects, a connection is assigned to the client until it disconnects. You *might run into pooler connection limits* since the connection is held till the client disconnects.
68
69### Using session and transaction modes at the same time
70 ${
71 primaryConfig?.pool_mode === 'transaction'
72 ? 'You can use the session mode connection string (port 5432) and transaction mode connection string (port 6543) in your application.'
73 : 'To get the best of both worlds, as a starting point, we recommend using session mode just when you need support for prepared statements and transaction mode in other cases.'
74 }
75`}
76 />
77 </DialogSection>
78 {primaryConfig?.pool_mode === 'session' && (
79 <div className="px-6">
80 <Alert variant="warning">
81 <AlertTriangleIcon strokeWidth={2} />
82 <AlertTitle>Pooling mode is currently configured to use session mode</AlertTitle>
83 <AlertDescription>
84 To use transaction mode concurrently with session mode, change the pooling mode to
85 transaction first in the{' '}
86 <span
87 tabIndex={0}
88 className="text-foreground cursor-pointer underline underline-offset-2"
89 onClick={() => {
90 snap.setShowPoolingModeHelper(false)
91 navigateToPoolerSettings()
92 }}
93 >
94 connection pooling settings
95 </span>
96 . After this, you can use transaction mode on port 6543 and session mode on port
97 5432.
98 </AlertDescription>
99 </Alert>
100 </div>
101 )}
102 <DialogFooter>
103 <DialogClose onClick={() => snap.setShowPoolingModeHelper(false)}>
104 <Button type="default">Close</Button>
105 </DialogClose>
106 </DialogFooter>
107 </DialogContent>
108 </Dialog>
109 )
110}