[{"data":1,"prerenderedAt":739},["ShallowReactive",2],{"navigation_docs":3,"section-navigation-docs":130,"-docs-postgres":164,"-docs-postgres-surround":646,"doc-previews":651},[4,8,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126],{"title":5,"path":6,"stem":7},"Quickstart","\u002Fdocs\u002Fquickstart","docs\u002F01.quickstart",{"title":9,"path":10,"stem":11,"children":12},"Guides","\u002Fdocs\u002Fguides","docs\u002F02.guides\u002Findex",[13,14,18,22,26,30,34,38,42,46],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17},"Next.js","\u002Fdocs\u002Fguides\u002Fnextjs","docs\u002F02.guides\u002F1.nextjs",{"title":19,"path":20,"stem":21},"Nuxt","\u002Fdocs\u002Fguides\u002Fnuxt","docs\u002F02.guides\u002F2.nuxt",{"title":23,"path":24,"stem":25},"SvelteKit","\u002Fdocs\u002Fguides\u002Fsveltekit","docs\u002F02.guides\u002F3.sveltekit",{"title":27,"path":28,"stem":29},"Astro","\u002Fdocs\u002Fguides\u002Fastro","docs\u002F02.guides\u002F4.astro",{"title":31,"path":32,"stem":33},"Express","\u002Fdocs\u002Fguides\u002Fexpress","docs\u002F02.guides\u002F5.express",{"title":35,"path":36,"stem":37},"FastAPI","\u002Fdocs\u002Fguides\u002Ffastapi","docs\u002F02.guides\u002F6.fastapi",{"title":39,"path":40,"stem":41},"Django","\u002Fdocs\u002Fguides\u002Fdjango","docs\u002F02.guides\u002F7.django",{"title":43,"path":44,"stem":45},"Laravel","\u002Fdocs\u002Fguides\u002Flaravel","docs\u002F02.guides\u002F8.laravel",{"title":47,"path":48,"stem":49},"Go","\u002Fdocs\u002Fguides\u002Fgo","docs\u002F02.guides\u002F9.go",{"title":51,"path":52,"stem":53},"Services","\u002Fdocs\u002Fservices","docs\u002F03.services",{"title":55,"path":56,"stem":57},"Deployments","\u002Fdocs\u002Fdeployments","docs\u002F04.deployments",{"title":59,"path":60,"stem":61},"Builds","\u002Fdocs\u002Fbuilds","docs\u002F05.builds",{"title":63,"path":64,"stem":65},"Variables","\u002Fdocs\u002Fvariables","docs\u002F06.variables",{"title":67,"path":68,"stem":69},"Domains","\u002Fdocs\u002Fdomains","docs\u002F07.domains",{"title":71,"path":72,"stem":73},"PostgreSQL","\u002Fdocs\u002Fpostgres","docs\u002F08.postgres",{"title":75,"path":76,"stem":77},"Object storage","\u002Fdocs\u002Fobject-storage","docs\u002F09.object-storage",{"title":79,"path":80,"stem":81},"Volumes","\u002Fdocs\u002Fvolumes","docs\u002F10.volumes",{"title":83,"path":84,"stem":85},"Key-value store","\u002Fdocs\u002Fredis","docs\u002F11.redis",{"title":87,"path":88,"stem":89},"Workspaces","\u002Fdocs\u002Fworkspaces","docs\u002F12.workspaces",{"title":91,"path":92,"stem":93},"Projects","\u002Fdocs\u002Fprojects","docs\u002F13.projects",{"title":95,"path":96,"stem":97},"Environments","\u002Fdocs\u002Fenvironments","docs\u002F14.environments",{"title":99,"path":100,"stem":101},"Eject","\u002Fdocs\u002Feject","docs\u002F15.eject",{"title":103,"path":104,"stem":105},"API","\u002Fdocs\u002Fapi","docs\u002F16.api",{"title":107,"path":108,"stem":109},"CLI","\u002Fdocs\u002Fcli","docs\u002F17.cli",{"title":111,"path":112,"stem":113},"Claude Plugin & MCP","\u002Fdocs\u002Fclaude-plugin","docs\u002F18.claude-plugin",{"title":115,"path":116,"stem":117},"Metrics","\u002Fdocs\u002Fmetrics","docs\u002F19.metrics",{"title":119,"path":120,"stem":121},"Logs","\u002Fdocs\u002Flogs","docs\u002F20.logs",{"title":123,"path":124,"stem":125},"Billing","\u002Fdocs\u002Fbilling","docs\u002F21.billing",{"title":127,"path":128,"stem":129},"Self-hosting","\u002Fdocs\u002Fself-hosting","docs\u002F22.self-hosting",[131,132,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163],{"title":5,"path":6,"stem":7},{"title":9,"path":10,"stem":11,"children":133},[134,135,136,137,138,139,140,141,142,143],{"title":9,"path":10,"stem":11},{"title":15,"path":16,"stem":17},{"title":19,"path":20,"stem":21},{"title":23,"path":24,"stem":25},{"title":27,"path":28,"stem":29},{"title":31,"path":32,"stem":33},{"title":35,"path":36,"stem":37},{"title":39,"path":40,"stem":41},{"title":43,"path":44,"stem":45},{"title":47,"path":48,"stem":49},{"title":51,"path":52,"stem":53},{"title":55,"path":56,"stem":57},{"title":59,"path":60,"stem":61},{"title":63,"path":64,"stem":65},{"title":67,"path":68,"stem":69},{"title":71,"path":72,"stem":73},{"title":75,"path":76,"stem":77},{"title":79,"path":80,"stem":81},{"title":83,"path":84,"stem":85},{"title":87,"path":88,"stem":89},{"title":91,"path":92,"stem":93},{"title":95,"path":96,"stem":97},{"title":99,"path":100,"stem":101},{"title":103,"path":104,"stem":105},{"title":107,"path":108,"stem":109},{"title":111,"path":112,"stem":113},{"title":115,"path":116,"stem":117},{"title":119,"path":120,"stem":121},{"title":123,"path":124,"stem":125},{"title":127,"path":128,"stem":129},{"id":165,"title":71,"body":166,"description":639,"extension":640,"links":641,"meta":642,"navigation":643,"path":72,"seo":644,"stem":73,"__hash__":645},"docs\u002Fdocs\u002F08.postgres.md",{"type":167,"value":168,"toc":622},"minimark",[169,173,176,181,192,200,211,215,223,242,245,328,334,338,348,351,358,366,371,388,398,404,411,415,422,425,428,432,435,441,448,454,463,469,474,480,484,487,490,495,499,502,505,514,517,521,524,583,587,601,605],[170,171,172],"p",{},"Lucity gives you fully managed PostgreSQL. Provision a database in a couple of clicks, connect a service to it without handling credentials, and leave the running of it to the platform.",[170,174,175],{},"Every database comes with high availability and automatic failover, continuous backups with point-in-time recovery across the last 30 days, and encrypted connections. Rather than splitting those across plans, every Lucity database gets all of them. What you configure is the CPU, memory and storage it needs, so the database fits your workload rather than a tier.",[177,178,180],"h2",{"id":179},"provisioning","Provisioning",[170,182,183,184,188,189,191],{},"On the project canvas, click ",[185,186,187],"strong",{},"Create"," and choose ",[185,190,71],{},". Give it a name between 2 and 16 characters and confirm.",[170,193,194,195,199],{},"A database belongs to one ",[196,197,198],"a",{"href":96},"environment",", so development and production each get their own. Provisioning takes a minute or two, after which the node on the canvas turns healthy and the credentials are available.",[170,201,202,203,207,208,210],{},"You get PostgreSQL 17, with a database called ",[204,205,206],"code",{},"app"," owned by a user called ",[204,209,206],{},". That user owns everything it creates, so migrations, extensions and schema changes all work without asking anyone for permission.",[177,212,214],{"id":213},"connect","Connect",[170,216,217,218,222],{},"Your services reach the database over the private network inside their environment. By default nothing else can, though you can ",[196,219,221],{"href":220},"#public-access","expose it to the internet"," if you need to.",[170,224,225,226,230,231,233,234,237,238,241],{},"The way to connect a service is a ",[196,227,229],{"href":228},"\u002Fdocs\u002Fvariables#dynamic-variables","dynamic variable",": open the service's ",[185,232,63],{}," tab, add a key such as ",[204,235,236],{},"DATABASE_URL",", click the link icon, and pick ",[204,239,240],{},"fqdn-uri"," from the database. The connection string is never copied anywhere, so there is nothing to keep in sync.",[170,243,244],{},"A database exposes six values:",[246,247,248,261],"table",{},[249,250,251],"thead",{},[252,253,254,258],"tr",{},[255,256,257],"th",{},"Variable",[255,259,260],{},"What it is",[262,263,264,274,284,296,307,318],"tbody",{},[252,265,266,271],{},[267,268,269],"td",{},[204,270,240],{},[267,272,273],{},"The complete connection string, which is usually the only one you need",[252,275,276,281],{},[267,277,278],{},[204,279,280],{},"host",[267,282,283],{},"The private hostname",[252,285,286,291],{},[267,287,288],{},[204,289,290],{},"port",[267,292,293],{},[204,294,295],{},"5432",[252,297,298,303],{},[267,299,300],{},[204,301,302],{},"dbname",[267,304,305],{},[204,306,206],{},[252,308,309,314],{},[267,310,311],{},[204,312,313],{},"user",[267,315,316],{},[204,317,206],{},[252,319,320,325],{},[267,321,322],{},[204,323,324],{},"password",[267,326,327],{},"The generated password",[170,329,330,331,333],{},"The ",[185,332,214],{}," tab on the database shows the same values if you need to read them yourself.",[177,335,337],{"id":336},"public-access","Public access",[170,339,340,341,343,344,347],{},"A database is private by default, which is where it should stay. When you need to reach it from an external tool, open the ",[185,342,214],{}," tab and switch ",[185,345,346],{},"Internet access"," on.",[170,349,350],{},"That gives the database a public hostname on port 5432. The user and password stay the same as on the private network, so only the connection string changes. Traffic is encrypted end to end: TLS terminates at the database itself, not at a proxy in front of it.",[170,352,353,354,357],{},"Because of that, your client has to use TLS. Connect with ",[204,355,356],{},"sslmode=require"," or stricter, which the connection string shown in the dashboard already does. With TLS off, the connection will not reach the database at all.",[359,360,361,362,365],"note",{},"Your client also has to be recent enough to send SNI, which means libpq 14 or newer for anything built on it, including ",[204,363,364],{},"psql",". Older clients connect to the right port and get nowhere.",[367,368,370],"h3",{"id":369},"allowed-addresses","Allowed addresses",[170,372,373,374,376,377,379,380,383,384,387],{},"Only the addresses you allow can connect over the public hostname, so a freshly exposed database lets nobody in. When you switch ",[185,375,346],{}," on, you can allow the computer you're using right away, and later add more under ",[185,378,370],{},". Each entry is an IPv4 address like ",[204,381,382],{},"203.0.113.7"," or a range like ",[204,385,386],{},"203.0.113.0\u002F24",", and a short description helps you remember whose it is.",[170,389,390,393,394,397],{},[185,391,392],{},"Allow connections from anywhere"," adds ",[204,395,396],{},"0.0.0.0\u002F0",", which lets every address through. Then only the password protects the database, so prefer listing the addresses you actually connect from. Removing an entry never opens the database up, so once the last one is gone, nobody can connect.",[170,399,400,401,403],{},"Switching ",[185,402,346],{}," off removes the public hostname together with the allowed addresses. It takes effect immediately, so ideally leave the database unexposed and turn this on only for as long as you need it.",[359,405,406,407,410],{},"A connection from an address that isn't allowed fails with ",[204,408,409],{},"SSL SYSCALL error: EOF detected",", the same error an old client without SNI gets. If you see it, check that your current address is on the list.",[177,412,414],{"id":413},"cpu-memory-and-storage","CPU, memory and storage",[170,416,417,418,421],{},"Under the database's ",[185,419,420],{},"Settings"," tab you can give it between 0.25 and 4 vCPU and between 256 MB and 16 GB of memory, defaulting to 0.5 vCPU and 512 MB. Storage starts at 16 GB and goes up to 1 TB.",[170,423,424],{},"Storage can be grown but never shrunk, so start with what you need and raise it as you go. Growing it happens in place, without downtime and without a restore.",[170,426,427],{},"Scaling CPU or memory triggers a rolling restart across the instances, so the database stays available throughout.",[177,429,431],{"id":430},"database-explorer","Database explorer",[170,433,434],{},"Lucity gives you basic tools for working with your data straight from the dashboard.",[170,436,437,440],{},[185,438,439],{},"Tables"," lists every table with its columns, types and an estimated row count, and shows the rows themselves a page at a time. It is the fastest way to check that your migration did what you expected.",[170,442,443],{},[444,445],"img",{"alt":446,"src":447},"The database panel on the Tables tab, showing the rows of a table","\u002Fimg\u002Fdocs\u002Fpostgres\u002Fexplorer-tables.png",[170,449,450],{},[451,452,453],"em",{},"Pick a table and read its rows without leaving the dashboard.",[170,455,456,459,460,462],{},[185,457,458],{},"Query"," runs SQL. It is a real connection, so it will happily write as well as read: be as careful here as you would be in ",[204,461,364],{}," against production. Statements are cut off after 30 seconds and results capped at 1000 rows, so use an external tool or a service in the same environment for long-running queries and migrations.",[170,464,465],{},[444,466],{"alt":467,"src":468},"The database panel on the Query tab, showing the result of a SELECT","\u002Fimg\u002Fdocs\u002Fpostgres\u002Fexplorer-query.png",[170,470,471],{},[451,472,473],{},"A query and its result, run against the database from the dashboard.",[170,475,476,479],{},[204,477,478],{},"pg_stat_statements"," is enabled, so you can query it directly to find out which statements are costing you the most.",[177,481,483],{"id":482},"backups","Backups",[170,485,486],{},"Backups are enabled by default, with a retention of 30 days, and there is nothing to configure.",[170,488,489],{},"A full base backup runs weekly, on Sunday at 02:00 UTC. Between those, every write is archived continuously as it happens, so the database can be restored to any moment in the window rather than only to the times a backup happened to run.",[170,491,330,492,494],{},[185,493,483],{}," tab shows how far back you can currently go, when the last backup completed, and the list of base backups with their status. You can also trigger one by hand there, which is worth doing before a migration you are unsure about.",[177,496,498],{"id":497},"point-in-time-restores","Point-in-time restores",[170,500,501],{},"Because every write is archived as it happens, you can restore to any moment inside the retention window, down to the second. This means you can restore your database to right before the moment something went wrong.",[170,503,504],{},"Restores always happen to a fresh database, which avoids any risk of data loss on the source. The original keeps running and serving traffic throughout.",[170,506,507,508,510,511,513],{},"From the ",[185,509,483],{}," tab, choose a point in time and give the new database a name. When it comes up you have both, so you can compare them, copy across what you need, or point your service at the restored one by changing its ",[204,512,236],{},".",[359,515,516],{},"A restored database is a new database with its own storage and its own bill. Delete it once you have what you needed from it.",[177,518,520],{"id":519},"whats-not-there-yet","What's not there yet",[170,522,523],{},"Some things you might expect from a managed database are not built yet:",[525,526,527,534,540,550,556,570],"ul",{},[528,529,530,533],"li",{},[185,531,532],{},"Choosing or upgrading the PostgreSQL version."," Every database is PostgreSQL 17.",[528,535,536,539],{},[185,537,538],{},"Read replicas."," The standby is there to take over when the primary fails, not to serve reads. Every connection goes to the primary.",[528,541,542,545,546,549],{},[185,543,544],{},"Extensions beyond the image."," You get the standard contrib set and ",[204,547,548],{},"pgvector",". Anything else, PostGIS included, cannot be added.",[528,551,552,555],{},[185,553,554],{},"Connection pooling."," There is no pooler in front of the database, so pool in your application and remember that the pool size counts per replica.",[528,557,558,561,562,565,566,569],{},[185,559,560],{},"Exports from the dashboard."," Run ",[204,563,564],{},"pg_dump"," yourself, either against a ",[196,567,568],{"href":220},"publicly exposed"," database or from a service in the same environment.",[528,571,572,575,576,578,579,582],{},[185,573,574],{},"Database metrics and alerting."," ",[196,577,51],{"href":52}," and ",[196,580,581],{"href":80},"volumes"," have usage graphs; databases do not.",[177,584,586],{"id":585},"under-the-hood","Under the hood",[170,588,589,590,596,597,600],{},"Databases are ",[196,591,595],{"href":592,"rel":593},"https:\u002F\u002Fcloudnative-pg.io",[594],"nofollow","CloudNativePG"," clusters, running two instances on separate machines with replication slots and unsupervised failover between them. That is where the high availability and the continuous archiving come from, and it is a project you can run yourself: an ",[196,598,599],{"href":100},"ejected"," environment keeps its databases as ordinary CloudNativePG resources, with the same backups and the same recovery behavior.",[177,602,604],{"id":603},"next-steps","Next steps",[525,606,607,612,617],{},[528,608,609,611],{},[196,610,63],{"href":228}," for wiring a database into a service",[528,613,614,616],{},[196,615,83],{"href":84}," for caching and queues, which do not belong in PostgreSQL",[528,618,619,621],{},[196,620,95],{"href":96}," for keeping production data away from development",{"title":623,"searchDepth":624,"depth":624,"links":625},"",2,[626,627,628,632,633,634,635,636,637,638],{"id":179,"depth":624,"text":180},{"id":213,"depth":624,"text":214},{"id":336,"depth":624,"text":337,"children":629},[630],{"id":369,"depth":631,"text":370},3,{"id":413,"depth":624,"text":414},{"id":430,"depth":624,"text":431},{"id":482,"depth":624,"text":483},{"id":497,"depth":624,"text":498},{"id":519,"depth":624,"text":520},{"id":585,"depth":624,"text":586},{"id":603,"depth":624,"text":604},"Managed PostgreSQL databases, replicated and backed up, connected to your services without copying credentials.","md",null,{},true,{"title":71,"description":639},"WDlVwmaR_Qyx7BnDWG-T1rByX63RNaC9Gl6Bz1Vx0mQ",[647,649],{"title":67,"path":68,"stem":69,"description":648,"children":-1},"Put a service on the internet. Use a platform hostname for quick tests, or a domain you own.",{"title":75,"path":76,"stem":77,"description":650,"children":-1},"S3-compatible buckets for uploads, exports and anything else your service needs to keep.",[652,655,657,660,663,666,669,672,675,678,681,684,687,689,691,693,695,696,697,698,700,702,704,706,708,710,712,714,716,718,720,722,724,727,731,735],{"path":6,"title":653,"description":654},"Deploy your first service","Deploy an app to Lucity, put it on a public domain, and connect a PostgreSQL database and an object storage bucket in about fifteen minutes.",{"path":656,"title":9,"description":641},"\u002Fdocs\u002Fguides\u002F.navigation",{"path":16,"title":658,"description":659},"Deploy a Next.js app","Deploy a Next.js app on Lucity, with a database, environment variables that behave, and no Dockerfile.",{"path":20,"title":661,"description":662},"Deploy a Nuxt app","Deploy a Nuxt app on Lucity. Nitro output, runtime config, and a database, with no preset to pick.",{"path":24,"title":664,"description":665},"Deploy a SvelteKit app","Deploy a SvelteKit app on Lucity. One adapter change stands between a fresh project and a running service.",{"path":28,"title":667,"description":668},"Deploy an Astro site","Deploy an Astro site on Lucity, static by default and server rendered when you add an adapter.",{"path":32,"title":670,"description":671},"Deploy an Express API","Deploy an Express API on Lucity. Three requirements, none of them platform-specific.",{"path":36,"title":673,"description":674},"Deploy a FastAPI service","Deploy a FastAPI service on Lucity. Detection is picky about layout, and the fix is one setting.",{"path":40,"title":676,"description":677},"Deploy a Django project","Deploy a Django project on Lucity, with migrations that run themselves and static files that do not.",{"path":44,"title":679,"description":680},"Deploy a Laravel application","Deploy a Laravel application on Lucity, with migrations, caches and a queue worker, and no server to configure.",{"path":48,"title":682,"description":683},"Deploy a Go service","Deploy a Go service on Lucity. Compiled in the build, shipped as a binary, nothing else in the image.",{"path":10,"title":685,"description":686},"Deploy your framework","Deploy guides for the frameworks people actually ship: Next.js, Nuxt, SvelteKit, Astro, Express, FastAPI, Django, Laravel, and Go.",{"path":52,"title":51,"description":688},"Services are the deployable units of a project: what they are, how they are configured, and how they scale.",{"path":56,"title":55,"description":690},"How a deployment goes live on Lucity, and the ways to trigger one.",{"path":60,"title":59,"description":692},"How Lucity turns your source code into a container image.",{"path":64,"title":63,"description":694},"Configuration for your services: service variables, shared variables, and dynamic variables.",{"path":68,"title":67,"description":648},{"path":72,"title":71,"description":639},{"path":76,"title":75,"description":650},{"path":80,"title":79,"description":699},"Persistent disks for services that need to keep state on the filesystem.",{"path":84,"title":83,"description":701},"A Redis®-compatible key-value store for caching, sessions and queues.",{"path":88,"title":87,"description":703},"Workspaces represent your organization in Lucity, with their own members, isolation and billing.",{"path":92,"title":91,"description":705},"Projects group services, databases and the environments they run in.",{"path":96,"title":95,"description":707},"Development, staging, production: isolated copies of the same application.",{"path":100,"title":99,"description":709},"Download a project as a Helm chart and run it on a Kubernetes cluster of your own.",{"path":104,"title":103,"description":711},"The GraphQL API behind the dashboard, with an interactive playground.",{"path":108,"title":107,"description":713},"Deploy and manage your services from a terminal or a CI pipeline.",{"path":112,"title":111,"description":715},"Deploy and manage your services from Claude Code, Codex, Cursor or any other MCP client.",{"path":116,"title":115,"description":717},"CPU and memory for every service, and disk usage for every volume.",{"path":120,"title":119,"description":719},"What your services print while they run, and the output of every deployment step.",{"path":124,"title":123,"description":721},"Plans, resource usage, the free trial, and what happens when a payment fails.",{"path":128,"title":127,"description":723},"Run the whole platform on a Kubernetes cluster you own, using the same two Helm charts we run ourselves.",{"path":725,"title":726,"description":641},"\u002Flegal\u002F.navigation","Legal",{"path":728,"title":729,"description":730},"\u002Flegal\u002Fdata-processing-agreement","Data Processing Agreement","How Lucity processes personal data on your behalf.",{"path":732,"title":733,"description":734},"\u002Flegal\u002Fprivacy-policy","Privacy Policy","How Lucity handles your data.",{"path":736,"title":737,"description":738},"\u002Flegal\u002Fterms-of-use","Terms of Use","Terms governing your use of Lucity.",1791216728141]