<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Light Cloud</title>
    <description>The latest articles on DEV Community by Light Cloud (lightcloud).</description>
    <link>https://dev.to/lightcloud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F14938%2Fe488b677-4276-480d-bddd-4095227d5d5e.png</url>
      <title>DEV Community: Light Cloud</title>
      <link>https://dev.to/lightcloud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lightcloud"/>
    <language>en</language>
    <item>
      <title>Rotate a Database Password With Only Seconds of Downtime</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Mon, 02 Nov 2026 09:18:29 +0000</pubDate>
      <link>https://dev.to/lightcloud/rotate-a-database-password-with-only-seconds-of-downtime-35c7</link>
      <guid>https://dev.to/lightcloud/rotate-a-database-password-with-only-seconds-of-downtime-35c7</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi7sim1djk65g3gu5jpjm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi7sim1djk65g3gu5jpjm.webp" alt="Rotate a Database Password With Only Seconds of Downtime" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To rotate the password of a Light Cloud PostgreSQL database that a live app uses, choose the new password yourself, put it into the app's &lt;code&gt;DATABASE_URL&lt;/code&gt; first, and click &lt;strong&gt;Rotate password&lt;/strong&gt; with &lt;strong&gt;Set my own&lt;/strong&gt; the moment the app's new deployment is live. In my test that caused 7 seconds of errors. Rotating first and updating the app afterwards caused almost two minutes.&lt;/p&gt;

&lt;p&gt;This is part 6 of the database series. It uses the &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt; and a small API that reads from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploy a small API that uses the database.&lt;/li&gt;
&lt;li&gt;Choose a new password and build the new &lt;code&gt;DATABASE_URL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save it on the app, then rotate the password when the deploy is live.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why the order matters
&lt;/h2&gt;

&lt;p&gt;A database has one password. Rotating it changes it at once: the old password stops working for new connections, and apps with the old one fail until they are updated. Updating an app's &lt;code&gt;DATABASE_URL&lt;/code&gt; redeploys it, which took about a minute in my runs.&lt;/p&gt;

&lt;p&gt;I measured both orders with a request to the API's &lt;code&gt;/health&lt;/code&gt; every half second:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Order&lt;/th&gt;
&lt;th&gt;Failed requests&lt;/th&gt;
&lt;th&gt;Errors for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rotate first, then update &lt;code&gt;DATABASE_URL&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;107 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update &lt;code&gt;DATABASE_URL&lt;/code&gt; first, rotate when the deploy is live&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The second order works because the old deployment keeps serving with the old password until the new one takes over. The only gap is between the new deployment going live and your click on &lt;strong&gt;Rotate password&lt;/strong&gt;. The errors were all &lt;code&gt;password authentication failed&lt;/code&gt;, answered by the API with a 503.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An app that uses it. To follow along, deploy the &lt;code&gt;app&lt;/code&gt; folder of the &lt;a href="https://github.com/light-cloud-com/tutorial-database-basics" rel="noopener noreferrer"&gt;repository&lt;/a&gt; from GitHub, as in &lt;a href="https://blog.light-cloud.com/tutorials/deploy-an-express-api" rel="noopener noreferrer"&gt;the Express guide&lt;/a&gt;: set &lt;strong&gt;Root directory&lt;/strong&gt; to &lt;code&gt;app&lt;/code&gt;, name it &lt;code&gt;bookshop-api&lt;/code&gt;, and add &lt;code&gt;DATABASE_URL&lt;/code&gt; with the connection string plus &lt;code&gt;?sslmode=require&amp;amp;uselibpqcompat=true&lt;/code&gt;. Its &lt;code&gt;/health&lt;/code&gt; checks the database.&lt;/li&gt;
&lt;li&gt;A Light Cloud account on the &lt;strong&gt;Lite&lt;/strong&gt; plan or higher.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Choose the new password
&lt;/h2&gt;

&lt;p&gt;Generate a random password of letters and digits. Those need no escaping in a connection string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 16


&lt;span class="c"&gt;# Run this in Git Bash, which comes with Git for Windows.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 16

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It prints 32 random characters; yours will differ. Keep the password somewhere safe, such as your password manager.&lt;/p&gt;

&lt;p&gt;Then write the new connection string: take the current one from the database's &lt;strong&gt;Credentials&lt;/strong&gt; tab and replace only the password, the part between &lt;code&gt;:&lt;/code&gt; and &lt;code&gt;@&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgresql://u_ ******:NEW_PASSWORD@bookshop-db-yourworkspace.db.light-cloud.io:5432/db******?sslmode=require&amp;amp;uselibpqcompat=true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Save it on the app first
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;bookshop-api&lt;/strong&gt; , &lt;strong&gt;Production&lt;/strong&gt; , &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Edit&lt;/strong&gt; next to &lt;strong&gt;Environment Variables&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Replace the value of &lt;code&gt;DATABASE_URL&lt;/code&gt; with the new connection string and click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F429wmib28u23lz3glyuo.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F429wmib28u23lz3glyuo.webp" alt="The Environment Variables editor with DATABASE_URL and its value hidden, and the Save button highlighted" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Saving starts a new deployment. The app keeps running on the old deployment, with the old password, which still works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Get the rotation ready
&lt;/h2&gt;

&lt;p&gt;While the app deploys, open &lt;strong&gt;bookshop-db&lt;/strong&gt; , &lt;strong&gt;Credentials&lt;/strong&gt; in a second browser tab and click &lt;strong&gt;Rotate password&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose &lt;strong&gt;Set my own&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Paste the password from Step 1.&lt;/li&gt;
&lt;li&gt;Do not click &lt;strong&gt;Rotate password&lt;/strong&gt; yet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjwuxb7f0plf8dbrd68uw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjwuxb7f0plf8dbrd68uw.webp" alt="The Rotate password window with Set my own selected, the new password hidden, the character rules, and the Rotate password button highlighted" width="448" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The window warns: &lt;em&gt;Apps using the current credentials will lose access until they are updated.&lt;/em&gt; Your app is already updated, it just is not live yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Rotate when the deploy is live
&lt;/h2&gt;

&lt;p&gt;Go back to the app tab and open &lt;strong&gt;Deployments&lt;/strong&gt;. When the new deployment at the top says &lt;strong&gt;Deployed&lt;/strong&gt; , switch tabs and click &lt;strong&gt;Rotate password&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwys962f7xwhw2g9lhxdn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwys962f7xwhw2g9lhxdn.webp" alt="The Deployment History with the newest deployment Deployed after 56 seconds, highlighted" width="799" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The console confirms: &lt;strong&gt;Password updated - connected apps need the new credentials&lt;/strong&gt;. Check the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://main-bookshop-api-yourworkspace.light-cloud.io/health
{"status":"ok","database":"ok"}


PS&amp;gt; curl.exe https://main-bookshop-api-yourworkspace.light-cloud.io/health
{"status":"ok","database":"ok"}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My deploy took 56 seconds. The new deployment started failing a few seconds before I saw &lt;strong&gt;Deployed&lt;/strong&gt; , and recovered the moment I rotated: 7 seconds of errors in total.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Update everything else
&lt;/h2&gt;

&lt;p&gt;The old password no longer works anywhere. Update every other place that has it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;other apps and environments that use the same database, such as preview environments,&lt;/li&gt;
&lt;li&gt;your laptop's &lt;code&gt;DATABASE_URL&lt;/code&gt; from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;GUI tools like TablePlus or DBeaver,&lt;/li&gt;
&lt;li&gt;scheduled jobs, such as the &lt;code&gt;pg_dump&lt;/code&gt; backup from &lt;a href="https://blog.light-cloud.com/tutorials/export-a-database-backup" rel="noopener noreferrer"&gt;part 4&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one of them uses the database a lot, rotate during a quiet hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  The quick way
&lt;/h2&gt;

&lt;p&gt;If a minute or two of errors is acceptable, for example on a staging database, click &lt;strong&gt;Rotate password&lt;/strong&gt; and keep &lt;strong&gt;Generate a strong password&lt;/strong&gt;. Then copy the new connection string from &lt;strong&gt;Credentials&lt;/strong&gt; and update &lt;code&gt;DATABASE_URL&lt;/code&gt; on every app. The console shows the new password right away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  password authentication failed for user "u_..."
&lt;/h3&gt;

&lt;p&gt;The app still has the old password. Check that you saved the new &lt;code&gt;DATABASE_URL&lt;/code&gt; on the right environment, and that its deployment has finished.&lt;/p&gt;

&lt;h3&gt;
  
  
  The new password was rejected
&lt;/h3&gt;

&lt;p&gt;It must be 12 to 72 characters: letters, digits or &lt;code&gt;!@#$%^&amp;amp;*()_-+=.,?&lt;/code&gt;, with no quotes, spaces or backslashes. Some of those characters also need encoding in a connection string (for example &lt;code&gt;@&lt;/code&gt; as &lt;code&gt;%40&lt;/code&gt;), which is why Step 1 uses letters and digits only.&lt;/p&gt;

&lt;h3&gt;
  
  
  The app broke before I rotated
&lt;/h3&gt;

&lt;p&gt;You rotated too late: the new deployment went live with the new password while the database still had the old one. Click &lt;strong&gt;Rotate password&lt;/strong&gt; now; the app recovers at once.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Import Data into Light Cloud: Upload a .sql Dump or Stream It with psql</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Sun, 01 Nov 2026 10:41:05 +0000</pubDate>
      <link>https://dev.to/lightcloud/import-data-into-light-cloud-upload-a-sql-dump-or-stream-it-with-psql-4ajg</link>
      <guid>https://dev.to/lightcloud/import-data-into-light-cloud-upload-a-sql-dump-or-stream-it-with-psql-4ajg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr06lhiw1w4g08bgvb60t.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr06lhiw1w4g08bgvb60t.webp" alt="Import Data into Light Cloud: Upload a .sql Dump or Stream It with psql" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To import a SQL dump into a PostgreSQL database on Light Cloud, open the database in the console, go to the &lt;strong&gt;Backup&lt;/strong&gt; tab, click &lt;strong&gt;Import dump&lt;/strong&gt; and choose the file. Plain &lt;code&gt;.sql&lt;/code&gt; and gzipped &lt;code&gt;.sql.gz&lt;/code&gt; files both work. For large dumps, run the file with &lt;code&gt;psql&lt;/code&gt; from your computer instead.&lt;/p&gt;

&lt;p&gt;This is part 5 of the database series. It adds a &lt;code&gt;publishers&lt;/code&gt; table to the &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;, first with the console and then with &lt;code&gt;psql&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Import a small SQL file with &lt;strong&gt;Import dump&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Check the new data with a query.&lt;/li&gt;
&lt;li&gt;Import a second file with &lt;code&gt;psql&lt;/code&gt;, the way to go for large dumps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The two files from the &lt;a href="https://github.com/light-cloud-com/tutorial-database-basics" rel="noopener noreferrer"&gt;repository&lt;/a&gt;: &lt;code&gt;imports/publishers.sql&lt;/code&gt; and &lt;code&gt;imports/more-books.sql&lt;/code&gt;. If you cloned it in part 1, run &lt;code&gt;git pull&lt;/code&gt; in its folder. Otherwise, download the files from GitHub.&lt;/li&gt;
&lt;li&gt;For Step 4, &lt;code&gt;psql&lt;/code&gt; from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Look at the file
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;imports/publishers.sql&lt;/code&gt; is what a supplier might send you. It creates a table of three (made-up) publishers, adds a &lt;code&gt;publisher_id&lt;/code&gt; column to &lt;code&gt;books&lt;/code&gt;, and fills it in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;publishers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;publishers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Lighthouse Press'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Edinburgh'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Northwind Books'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Toronto'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Blue Harbour'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Gdansk'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;publishers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always read a dump before you import it: it runs with full access to your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Import it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;a href="https://console.light-cloud.com" rel="noopener noreferrer"&gt;Light Cloud console&lt;/a&gt;, open &lt;strong&gt;bookshop-db&lt;/strong&gt; and its &lt;strong&gt;Backup&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Import dump&lt;/strong&gt; and choose &lt;code&gt;publishers.sql&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Folsu4yzwko0qf6o14u7e.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Folsu4yzwko0qf6o14u7e.webp" alt="The Import card on the Backup tab explaining that the SQL dump runs against this database, with the Import dump button highlighted" width="797" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The import starts as soon as you choose the file; there is no second confirmation. For this small file it finished within a few seconds, with the message &lt;strong&gt;Dump imported&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The import runs into the database as it is. Nothing is deleted first: tables the dump does not mention stay as they are, and a table that already exists is an error unless the dump drops it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Check the result
&lt;/h2&gt;

&lt;p&gt;Open the &lt;strong&gt;Data&lt;/strong&gt; tab. The table list now has &lt;strong&gt;publishers&lt;/strong&gt;. Ask how many books each publisher has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;publishers&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2oscd2hdkr1csr18bjru.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2oscd2hdkr1csr18bjru.webp" alt="The Data tab with the new publishers table highlighted in the table list, and the query result: Lighthouse Press Edinburgh 5, Northwind Books Toronto 3, Blue Harbour Gdansk 2" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All 10 books have a publisher. The query box is explained in &lt;a href="https://blog.light-cloud.com/tutorials/run-sql-queries-in-the-console" rel="noopener noreferrer"&gt;part 3&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Import with psql
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Import dump&lt;/strong&gt; takes files up to 512 MB uncompressed, and the import has about four and a half minutes to finish. For bigger dumps, or to import from a script, run the file with &lt;code&gt;psql&lt;/code&gt; and the &lt;code&gt;DATABASE_URL&lt;/code&gt; from part 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ psql "$DATABASE_URL" --single-transaction -v ON_ERROR_STOP=1 -f imports/more-books.sql
INSERT 0 2


PS&amp;gt; psql "$env:DATABASE_URL" --single-transaction -v ON_ERROR_STOP=1 -f imports/more-books.sql
INSERT 0 2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two more books arrived. The two options make a failed import safe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-v ON_ERROR_STOP=1&lt;/code&gt; stops at the first error, instead of carrying on with the rest of the file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--single-transaction&lt;/code&gt; runs the whole file as one transaction, so an error undoes everything the file already did. Your database is either fully imported or unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Import dump&lt;/strong&gt; also stops at the first error, but keeps what ran before it. With &lt;code&gt;psql&lt;/code&gt;, you choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a dump may contain
&lt;/h2&gt;

&lt;p&gt;The console and &lt;code&gt;psql&lt;/code&gt; run the file with your database user's rights. That user owns your tables but is not a superuser, so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain SQL only.&lt;/strong&gt; A &lt;code&gt;.sql&lt;/code&gt; file, or one gzipped as &lt;code&gt;.sql.gz&lt;/code&gt;. The console rejects &lt;code&gt;pg_dump -Fc&lt;/code&gt; archives, tar and zip files with a message saying so. Restore a &lt;code&gt;-Fc&lt;/code&gt; archive with &lt;code&gt;pg_restore&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No owners or permissions from another server.&lt;/strong&gt; &lt;code&gt;ALTER TABLE ... OWNER TO postgres&lt;/code&gt; fails with &lt;code&gt;must be member of role "postgres"&lt;/code&gt;, and &lt;code&gt;GRANT ... TO some_user&lt;/code&gt; with &lt;code&gt;role "some_user" does not exist&lt;/code&gt;. Create the dump with &lt;code&gt;pg_dump --no-owner --no-privileges&lt;/code&gt;, like the console's own backups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;CREATE DATABASE&lt;/code&gt;.&lt;/strong&gt; It fails with &lt;code&gt;permission denied to create database&lt;/code&gt;. Dump a single database without &lt;code&gt;-C&lt;/code&gt;, and import it into the Light Cloud database you created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A backup downloaded from any Light Cloud database, as in &lt;a href="https://blog.light-cloud.com/tutorials/export-a-database-backup" rel="noopener noreferrer"&gt;part 4&lt;/a&gt;, meets all three rules and imports as it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Import failed: ERROR: relation "publishers" already exists
&lt;/h3&gt;

&lt;p&gt;The dump creates a table the database already has, for example because you imported the same file twice. I got exactly this on a second run; since it was the first statement, nothing changed. Import into an empty database, or drop the table first.&lt;/p&gt;

&lt;h3&gt;
  
  
  must be member of role "postgres"
&lt;/h3&gt;

&lt;p&gt;The dump sets owners. See What a dump may contain.&lt;/p&gt;

&lt;h3&gt;
  
  
  The import took too long
&lt;/h3&gt;

&lt;p&gt;The file needs more than the console's time limit. Run it with &lt;code&gt;psql&lt;/code&gt; as in Step 4.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Where to Deploy a SaaS Boilerplate</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Sat, 31 Oct 2026 18:29:42 +0000</pubDate>
      <link>https://dev.to/lightcloud/where-to-deploy-a-saas-boilerplate-2l9k</link>
      <guid>https://dev.to/lightcloud/where-to-deploy-a-saas-boilerplate-2l9k</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxhqsxn8oywwn284xggy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxhqsxn8oywwn284xggy.webp" alt="Where to Deploy a SaaS Boilerplate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a boilerplate that has no paying customers yet, the cheapest place to run its app and a PostgreSQL database is Light Cloud at $5 a month, followed by Railway at $5 plus usage. Vercel, the host that ShipFast, Makerkit and Supastarter all point you to, costs $20 a month once the app takes money, plus the database. That gap matters most for Supastarter and Open SaaS, which keep their data in plain Postgres. ShipFast and Makerkit keep theirs in MongoDB Atlas or Supabase, so only the app moves and that service stays on its own bill.&lt;/p&gt;

&lt;p&gt;We make Light Cloud, the first row below, so here is the method before the table. Every number links to the page it came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the four kits actually need
&lt;/h2&gt;

&lt;p&gt;A boilerplate is a promise that the boring parts are done. Where it runs is the part the kit can't decide for you, and each of the four says something different about it.&lt;/p&gt;

&lt;p&gt;ShipFast is a Next.js app whose own stack list reads "MongoDB / Supabase" (&lt;a href="https://shipfa.st" rel="noopener noreferrer"&gt;shipfa.st&lt;/a&gt;). The deployment page is three lines long: push to a private GitHub repo, then "use your favorite hosting provider (Vercel for me)", or anywhere Next.js runs, naming Netlify and Render too (&lt;a href="https://shipfa.st/docs/deployment" rel="noopener noreferrer"&gt;deployment docs&lt;/a&gt;). Its default database is a MongoDB Atlas cluster, opened to &lt;code&gt;0.0.0.0/0&lt;/code&gt; so the host can reach it.&lt;/p&gt;

&lt;p&gt;Makerkit's Next.js Supabase kit is built on Supabase for auth and data, and calls Vercel "the recommended hosting platform" (&lt;a href="https://makerkit.dev/docs/next-supabase-turbo/going-to-production/vercel" rel="noopener noreferrer"&gt;Vercel guide&lt;/a&gt;). It also documents Cloudflare and Docker. Its Docker guide generates a Dockerfile, switches Next.js to standalone output and runs the container with a 512 MB memory limit (&lt;a href="https://makerkit.dev/docs/next-supabase-turbo/going-to-production/docker" rel="noopener noreferrer"&gt;Docker guide&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Supastarter runs on "any hosting provider that supports Node.js", recommends Vercel, and has guides for Render, Fly.io, Netlify, Docker, Coolify and Railway (&lt;a href="https://supastarter.dev/docs/nextjs/deployment/overview" rel="noopener noreferrer"&gt;deployment overview&lt;/a&gt;). Its database is PostgreSQL by default, through Prisma or Drizzle, with any Postgres provider (&lt;a href="https://supastarter.dev/docs/nextjs/database/overview" rel="noopener noreferrer"&gt;database docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Open SaaS sits on Wasp: a React client, a Node.js server and Postgres. The quickest route is Wasp's one-command deploy to Fly.io or Railway (&lt;a href="https://docs.opensaas.sh/guides/deploying/" rel="noopener noreferrer"&gt;Open SaaS docs&lt;/a&gt;), and Wasp has written guides for Render, Heroku, Netlify and Cloudflare as well (&lt;a href="https://wasp.sh/docs/deployment/deployment-methods/paas" rel="noopener noreferrer"&gt;Wasp docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So the job is the same for all four: run one server-rendered app, keep a database next to it, and don't pay much for either before launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;The reference app is one boilerplate app, server-rendered Next.js or a Wasp Node server, plus a PostgreSQL database and a custom domain, at about 1,000 requests a day. Each platform gets its cheapest plan that allows a paid product. Prices are list prices from the vendors' own pages, checked on 2026-10-13, in US dollars, no trial credits.&lt;/p&gt;

&lt;p&gt;The first column shows which of the four kits names the platform in its own docs, because a written guide saves an evening. And the second shows whether the app costs anything while nobody is using it, which before launch is most of the day.&lt;/p&gt;

&lt;p&gt;Kept running all month, with no scale to zero, the same app gets the Always on prices in the table. Light Cloud comes fifth of seven there at about $56, because an always-on instance needs the $19 Starter plan and a Micro costs about $52 a month. Platforms that run the app only as functions have no documented way to keep it running, so they're listed last.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;App + Postgres a month&lt;/th&gt;
&lt;th&gt;Always on, a month&lt;/th&gt;
&lt;th&gt;Named in the kits' docs&lt;/th&gt;
&lt;th&gt;App while idle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;td&gt;about $56 (Starter, always-on Micro)&lt;/td&gt;
&lt;td&gt;None of the four&lt;/td&gt;
&lt;td&gt;Scales to zero, costs $0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5 plus usage over $5&lt;/td&gt;
&lt;td&gt;$5+&lt;/td&gt;
&lt;td&gt;Open SaaS, Supastarter&lt;/td&gt;
&lt;td&gt;Sleep is opt-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Netlify&lt;/td&gt;
&lt;td&gt;$9 plus credits beyond the plan&lt;/td&gt;
&lt;td&gt;No always-on option&lt;/td&gt;
&lt;td&gt;ShipFast, Supastarter&lt;/td&gt;
&lt;td&gt;Functions, idle is free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Heroku&lt;/td&gt;
&lt;td&gt;$10 to $12&lt;/td&gt;
&lt;td&gt;$12&lt;/td&gt;
&lt;td&gt;Open SaaS&lt;/td&gt;
&lt;td&gt;Eco sleeps; Basic bills 24/7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$13.30&lt;/td&gt;
&lt;td&gt;$13.30&lt;/td&gt;
&lt;td&gt;ShipFast, Supastarter, Open SaaS&lt;/td&gt;
&lt;td&gt;No scale to zero documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;$20 plus a database&lt;/td&gt;
&lt;td&gt;No always-on option&lt;/td&gt;
&lt;td&gt;ShipFast, Makerkit, Supastarter&lt;/td&gt;
&lt;td&gt;Functions, nothing between requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Fly.io&lt;/td&gt;
&lt;td&gt;about $40&lt;/td&gt;
&lt;td&gt;~$40&lt;/td&gt;
&lt;td&gt;Open SaaS, Supastarter&lt;/td&gt;
&lt;td&gt;Machines stop when idle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;List prices from each vendor's pricing and docs pages, checked 2026-10-13. Light Cloud usage uses the pricing page's own assumption of 0.2 s of instance time per request. ShipFast on MongoDB Atlas and Makerkit on Supabase add that service's own bill. Taxes and bandwidth beyond included allowances excluded.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; founders who want the app and its Postgres on one $5 bill while nobody is paying.&lt;/p&gt;

&lt;p&gt;Lite is $5 a month with $5 of usage included, a custom domain and one shared PostgreSQL database (&lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). The reference app uses about $4.24 of that: $4 for the database, about $0.20 for 1,000 requests a day at 0.2 s each, and a few cents of builds. Server-rendered Next.js runs on a Micro instance that scales between 0 and 3, and &lt;a href="https://blog.light-cloud.com/tutorials/deploy-nextjs" rel="noopener noreferrer"&gt;the Next.js tutorial&lt;/a&gt; shows the detection and the &lt;code&gt;output: "standalone"&lt;/code&gt; setting that cut my image from 201 MB to 74 MB. That's the same switch Makerkit's Docker guide makes. For Supastarter or a Node backend, &lt;a href="https://blog.light-cloud.com/tutorials/add-postgres-to-nodejs-app" rel="noopener noreferrer"&gt;the Postgres tutorial&lt;/a&gt; covers the connection string, including the &lt;code&gt;sslmode&lt;/code&gt; suffix that node-postgres needs.&lt;/p&gt;

&lt;p&gt;None of the four kits mentions us, so you're on your own docs. We &lt;a href="https://light-cloud.com/frameworks" rel="noopener noreferrer"&gt;host Next.js and Node.js apps&lt;/a&gt; from a plain repository, and the database is &lt;a href="https://light-cloud.com/databases" rel="noopener noreferrer"&gt;a Postgres database on the same bill&lt;/a&gt;. Every branch gets &lt;a href="https://light-cloud.com/previews" rel="noopener noreferrer"&gt;branch preview URLs&lt;/a&gt; at no idle cost, and you can &lt;a href="https://light-cloud.com/deploy-with-ai" rel="noopener noreferrer"&gt;deploy from Cursor or Claude Code&lt;/a&gt; if that's how the kit got written in the first place.&lt;/p&gt;

&lt;p&gt;Open SaaS deserves its own paragraph. The template gallery has an Open SaaS stack that creates the Wasp app and a shared Postgres database with &lt;code&gt;DATABASE_URL&lt;/code&gt; already wired. But stacks are created always-on so the first visit is warm, and an always-on Micro is about $52 a month and needs Starter. Set min instances to 0 in Scaling afterwards and it bills like any other app, with a cold start of 3.1 to 3.7 seconds after a quiet spell.&lt;/p&gt;

&lt;p&gt;What's missing: no MongoDB, so ShipFast's default database stays on Atlas. There are no cron jobs or background workers, which matters once the app needs a nightly job, and no built-in auth or email, which the kits bring themselves. Redirect files such as &lt;code&gt;vercel.json&lt;/code&gt; are ignored. And the shared database tier runs in Belgium only.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Open SaaS and Supastarter users who want a documented deploy at the same starting price.&lt;/p&gt;

&lt;p&gt;Hobby is $5 a month with $5 of usage included, and usage is billed by the RAM and CPU the services actually use: $10 per GB of RAM a month and $20 per vCPU a month (&lt;a href="https://docs.railway.com/pricing/plans" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). Wasp's Railway command creates the client, the server and a Postgres service and wires &lt;code&gt;DATABASE_URL&lt;/code&gt; for you (&lt;a href="https://wasp.sh/docs/deployment/deployment-methods/wasp-deploy/railway" rel="noopener noreferrer"&gt;Wasp on Railway&lt;/a&gt;). Supastarter's docs quote Railway's $5 starting price themselves.&lt;/p&gt;

&lt;p&gt;Railway also has cron jobs and private networking on every plan, the two things a SaaS tends to want by month three. Two catches: Railway &lt;a href="https://docs.railway.com/pricing/faqs" rel="noopener noreferrer"&gt;recommends Pro, $20 a month, for commercial apps&lt;/a&gt;, and the free plan has no custom domains.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Netlify
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Next.js kits that want first-party Postgres with real data in every preview.&lt;/p&gt;

&lt;p&gt;Personal is $9 a month for 1,000 credits (&lt;a href="https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/credit-based-pricing-plans/" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). Function compute is 10 credits per GB-hour, so 1,000 requests a day at 0.2 s each with the default 1 GB of memory comes to about 17 credits a month; production deploys cost 15 credits each, so a busy week of shipping eats more than the traffic does. Netlify Database is a first-party managed Postgres, and each deploy preview &lt;a href="https://docs.netlify.com/build/data-and-storage/netlify-database/" rel="noopener noreferrer"&gt;gets its own database branch&lt;/a&gt; with a copy of the production data taken when the preview is created.&lt;/p&gt;

&lt;p&gt;Netlify hasn't published a storage rate for the database yet, so the long-run price has a blank in it. Password protection is a Pro feature, not on Personal. When credits run out without auto recharge, every project on the team pauses.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Heroku
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams who already know &lt;code&gt;git push heroku&lt;/code&gt; and want Wasp's Heroku guide.&lt;/p&gt;

&lt;p&gt;An Eco dyno is $5 for 1,000 shared hours and sleeps after 30 minutes idle, but only personal apps can use it; Essential-0 Postgres is $5 (&lt;a href="https://www.heroku.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). That's $10, or $12 with an always-on Basic dyno. Wasp keeps a written Heroku guide, so Open SaaS has a known path there.&lt;/p&gt;

&lt;p&gt;Heroku needs a card before you deploy, and it &lt;a href="https://www.heroku.com/blog/an-update-on-heroku/" rel="noopener noreferrer"&gt;moved to a sustaining engineering model&lt;/a&gt; on 2026-02-06: stability and security, not new features. Fine for an app you'll run for a while. Odd for one you're starting today.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a kit with a separate long-running API, on fixed prices.&lt;/p&gt;

&lt;p&gt;A Starter web service is $7 a month for 512 MB, and the smallest Postgres is $6 plus $0.30 per GB (&lt;a href="https://render.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;): $13.30. Render and Vercel are the two hosts named by three of the four kits; for Render it's ShipFast's deployment page, Supastarter's guide and Wasp's Blueprint guide. If you run Supastarter's API as its own service, which its docs suggest for a "long-running" API, Render's fixed instances and private network suit that shape.&lt;/p&gt;

&lt;p&gt;The free tier spins down after 15 minutes and takes about a minute to wake, and free Postgres expires after 30 days (&lt;a href="https://render.com/docs/free" rel="noopener noreferrer"&gt;free tier docs&lt;/a&gt;), so a real product starts on paid instances that bill around the clock.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Vercel
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Next.js kits deployed exactly the way their authors do it.&lt;/p&gt;

&lt;p&gt;This is the path of least resistance, and three kits say so. The catch is the plan. ShipFast's FAQ says Vercel lets you "host a project for free", but Vercel's own &lt;a href="https://vercel.com/docs/limits/fair-use-guidelines" rel="noopener noreferrer"&gt;fair use guidelines&lt;/a&gt; limit Hobby to non-commercial use and count taking payments as commercial. A SaaS needs Pro: $20 a month per deploying seat with $20 of usage included (&lt;a href="https://vercel.com/docs/plans/pro-plan" rel="noopener noreferrer"&gt;Pro plan&lt;/a&gt;). The database comes from a Marketplace partner, billed separately.&lt;/p&gt;

&lt;p&gt;Previews are excellent and on every plan. A shared password on staging costs $20 per project a month on Pro since &lt;a href="https://vercel.com/changelog/password-protection-now-costs-20-per-project-per-month-on-pro" rel="noopener noreferrer"&gt;the September 2026 change&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Fly.io
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Open SaaS through Wasp's one-command deploy, with regions near your users.&lt;/p&gt;

&lt;p&gt;Wasp's Fly command creates three apps: the client, the server and the database (&lt;a href="https://wasp.sh/docs/deployment/deployment-methods/wasp-deploy/fly" rel="noopener noreferrer"&gt;Wasp on Fly&lt;/a&gt;). The smallest always-on machine is $2.19 a month, but Fly calls its self-managed Postgres officially unsupported, and Managed Postgres starts at $38 plus $0.28 per GB (&lt;a href="https://docs.fly.io/postgres" rel="noopener noreferrer"&gt;Postgres docs&lt;/a&gt;). That puts a supported setup near $40.&lt;/p&gt;

&lt;p&gt;There's no free tier for new accounts, and Fly &lt;a href="https://docs.fly.io/about/cost-management" rel="noopener noreferrer"&gt;doesn't support billing alerts yet&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;The written guide is the big one. Every other row has at least one kit that tells you, step by step, how to deploy there; we have none, so you follow our Next.js tutorial instead of the kit's. If you picked Makerkit or ShipFast for Supabase or MongoDB, we only take the app, not the data layer. Railway gives Open SaaS a one-command deploy at our price, with the cron jobs a SaaS eventually needs. Netlify's previews copy production data into a database branch, while ours share the production database until you point them elsewhere. And if you want Vercel's Next.js features as the kit authors use them, Vercel is the honest answer.&lt;/p&gt;

&lt;p&gt;Where we're ahead is the month before launch: one bill of $5 covering the app and Postgres, no cost while nobody visits, a preview of every branch, and a password on staging on any plan (&lt;a href="https://blog.light-cloud.com/tutorials/password-protect-a-staging-site" rel="noopener noreferrer"&gt;the five-minute setup&lt;/a&gt;). If that is the stretch you're in, &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;SaaS boilerplate hosting&lt;/a&gt; can stay at $5 until the first invoice goes out.&lt;/p&gt;

&lt;p&gt;Which kit did you buy, and where did its docs send you?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>saas</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Back Up a Database: Download a SQL Dump and Restore It</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Sat, 31 Oct 2026 09:14:37 +0000</pubDate>
      <link>https://dev.to/lightcloud/back-up-a-database-download-a-sql-dump-and-restore-it-npm</link>
      <guid>https://dev.to/lightcloud/back-up-a-database-download-a-sql-dump-and-restore-it-npm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr3fcssz2y19w12alq1dp.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr3fcssz2y19w12alq1dp.webp" alt="Back Up a Database: Download a SQL Dump and Restore It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To back up a PostgreSQL database on Light Cloud, open the database in the console, go to the &lt;strong&gt;Backup&lt;/strong&gt; tab and click &lt;strong&gt;Download backup&lt;/strong&gt;. You get a complete SQL dump as a &lt;code&gt;.sql.gz&lt;/code&gt; file. To restore it, unzip it and run it with &lt;code&gt;psql&lt;/code&gt; against an empty database. For scheduled backups, run &lt;code&gt;pg_dump&lt;/code&gt; with the connection string instead.&lt;/p&gt;

&lt;p&gt;This is part 4 of the database series. It backs up the &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;, then proves the backup works by restoring it into a second database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download a backup of &lt;code&gt;bookshop-db&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Look inside it.&lt;/li&gt;
&lt;li&gt;Restore it into a new database, &lt;code&gt;bookshop-copy&lt;/code&gt;, and check the data.&lt;/li&gt;
&lt;li&gt;Make the same backup from the terminal with &lt;code&gt;pg_dump&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;psql&lt;/code&gt; and &lt;code&gt;pg_dump&lt;/code&gt;, installed with &lt;code&gt;psql&lt;/code&gt; in &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;. Use a current version: I used 18.6.&lt;/li&gt;
&lt;li&gt;A Light Cloud account on the &lt;strong&gt;Lite&lt;/strong&gt; plan or higher.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Download the backup
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;bookshop-db&lt;/strong&gt; , go to the &lt;strong&gt;Backup&lt;/strong&gt; tab and click &lt;strong&gt;Download backup&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F297h9t1su1pdnwwol4w7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F297h9t1su1pdnwwol4w7.webp" alt="The Backup tab with Manual backup, the Download backup button highlighted, and Import a dump below" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The console makes a fresh dump of the database and downloads it; for my small bookshop that took about a second. The file is named after the database and the time in UTC, for example &lt;code&gt;bookshop-db-2026-09-25T15-41-43.sql.gz&lt;/code&gt;, and was 1.4 KB.&lt;/p&gt;

&lt;p&gt;Open a terminal in the folder with the file, usually &lt;code&gt;Downloads&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Look inside
&lt;/h2&gt;

&lt;p&gt;The file is gzip-compressed SQL. Unzip it and keep the original:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;gunzip&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; bookshop-db-&lt;span class="k"&gt;*&lt;/span&gt;.sql.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 8 bookshop-db-&lt;span class="k"&gt;*&lt;/span&gt;.sql
&lt;span class="nt"&gt;--&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; PostgreSQL database dump
&lt;span class="nt"&gt;--&lt;/span&gt;

&lt;span class="se"&gt;\r&lt;/span&gt;estrict asCDvFHFw2eKvwY4n71bGzNGHJM0iLagWYa5QvYYBYmRpBkzvdW4DCtA642ddcH

&lt;span class="nt"&gt;--&lt;/span&gt; Dumped from database version 15.18
&lt;span class="nt"&gt;--&lt;/span&gt; Dumped by pg_dump version 16.15


&lt;span class="c"&gt;# PowerShell has no gunzip, so extract the file with 7-Zip (www.7-zip.org):&lt;/span&gt;
&lt;span class="c"&gt;# right-click it, choose 7-Zip, then Extract Here.&lt;/span&gt;
&lt;span class="c"&gt;# Open the .sql file in Notepad. It starts with the same lines:&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt; PostgreSQL database dump
&lt;span class="nt"&gt;--&lt;/span&gt;

&lt;span class="se"&gt;\r&lt;/span&gt;estrict asCDvFHFw2eKvwY4n71bGzNGHJM0iLagWYa5QvYYBYmRpBkzvdW4DCtA642ddcH

&lt;span class="nt"&gt;--&lt;/span&gt; Dumped from database version 15.18
&lt;span class="nt"&gt;--&lt;/span&gt; Dumped by pg_dump version 16.15

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;\restrict&lt;/code&gt; line has a different random key.&lt;/p&gt;

&lt;p&gt;It is a plain SQL file made by &lt;code&gt;pg_dump&lt;/code&gt;. Further down are &lt;code&gt;CREATE TABLE&lt;/code&gt; statements for &lt;code&gt;authors&lt;/code&gt;, &lt;code&gt;books&lt;/code&gt; and &lt;code&gt;reviews&lt;/code&gt;, their rows as &lt;code&gt;COPY&lt;/code&gt; blocks, and the primary keys. It contains no owners or permissions, so it restores into any PostgreSQL database, not only the one it came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Restore into a new database
&lt;/h2&gt;

&lt;p&gt;A backup you have never restored is only a hope. Restore it into a second database to check it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the console, create a database named &lt;code&gt;bookshop-copy&lt;/code&gt;, size &lt;strong&gt;Dev&lt;/strong&gt; , as in &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Copy its connection string from &lt;strong&gt;Credentials&lt;/strong&gt; , add &lt;code&gt;?sslmode=require&lt;/code&gt;, and save it as &lt;code&gt;COPY_URL&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;COPY_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'postgresql://u_ ******:******** @bookshop-copy-yourworkspace.db.light-cloud.io:5432/db ******?sslmode=require'&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;PS&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;COPY_URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'postgresql://u_ ******:******** @bookshop-copy-yourworkspace.db.light-cloud.io:5432/db ******?sslmode=require'&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run the SQL file against it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ psql "$COPY_URL" -f bookshop-db-*.sql
SET
SET
...
CREATE TABLE
CREATE SEQUENCE
ALTER SEQUENCE
...
COPY 4
COPY 10
COPY 1
...
ALTER TABLE


# Use your own file name after -f.
PS&amp;gt; psql "$env:COPY_URL" -f bookshop-db-2026-09-25T15-41-43.sql
SET
SET
...
CREATE TABLE
CREATE SEQUENCE
ALTER SEQUENCE
...
COPY 4
COPY 10
COPY 1
...
ALTER TABLE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output is trimmed where you see &lt;code&gt;...&lt;/code&gt;. The &lt;code&gt;COPY&lt;/code&gt; lines are the rows: 4 authors, 10 books and 1 review, everything from parts 1 to 3.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COPY_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT count(*) AS books FROM books;"&lt;/span&gt;
&lt;span class="go"&gt; books
-------
    10
(1 row)


&lt;/span&gt;&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;:COPY_URL"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT count(*) AS books FROM books;"&lt;/span&gt;
&lt;span class="go"&gt; books
-------
    10
(1 row)

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The copy is complete. The same file restores into PostgreSQL on your laptop: point &lt;code&gt;psql&lt;/code&gt; at the local database instead of &lt;code&gt;COPY_URL&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Back up from the terminal
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Download backup&lt;/strong&gt; button is right for a backup before a risky change. For regular backups, run &lt;code&gt;pg_dump&lt;/code&gt; from a script or a scheduled job, with the &lt;code&gt;DATABASE_URL&lt;/code&gt; of &lt;code&gt;bookshop-db&lt;/code&gt; from part 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_dump&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-owner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bookshop.sql&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;PS&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pg_dump&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-owner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-privileges&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bookshop.sql&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It prints nothing when it works. &lt;code&gt;--no-owner --no-privileges&lt;/code&gt; makes the same kind of portable file as the console. My &lt;code&gt;bookshop.sql&lt;/code&gt; was 5 KB and said &lt;code&gt;Dumped by pg_dump version 18.6&lt;/code&gt;. Add &lt;code&gt;-Fc&lt;/code&gt; for PostgreSQL's compressed custom format, which you restore with &lt;code&gt;pg_restore&lt;/code&gt; instead of &lt;code&gt;psql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Keep backups somewhere other than your laptop's &lt;code&gt;Downloads&lt;/code&gt; folder, and remember they contain all your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Delete the copy
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bookshop-copy&lt;/code&gt; has done its job. Open it, go to &lt;strong&gt;Settings&lt;/strong&gt; , and click &lt;strong&gt;Delete Database&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4univpg5l774bt8j8iyj.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4univpg5l774bt8j8iyj.webp" alt="The Danger Zone on the Settings tab of bookshop-copy with the Delete Database button highlighted" width="800" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Type &lt;code&gt;bookshop-copy&lt;/code&gt; to confirm and click &lt;strong&gt;Delete&lt;/strong&gt;. Check the name twice: deleting cannot be undone, and part 5 still needs &lt;code&gt;bookshop-db&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  invalid command \restrict
&lt;/h3&gt;

&lt;p&gt;Your &lt;code&gt;psql&lt;/code&gt; is older than the &lt;code&gt;pg_dump&lt;/code&gt; that made the file. Recent &lt;code&gt;pg_dump&lt;/code&gt; versions add &lt;code&gt;\restrict&lt;/code&gt; and &lt;code&gt;\unrestrict&lt;/code&gt; lines as a safety guard. An older &lt;code&gt;psql&lt;/code&gt; prints &lt;code&gt;invalid command \restrict&lt;/code&gt; and &lt;code&gt;invalid command \unrestrict&lt;/code&gt; but restores everything else; in my tests with psql 14.13 and 17.5 all rows arrived. Update &lt;code&gt;psql&lt;/code&gt; to get rid of the messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  relation "authors" already exists
&lt;/h3&gt;

&lt;p&gt;The target database already has these tables. Restore into an empty database, or drop the tables first.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Run SQL in the Browser: Queries, Joins and Quick Fixes on a Live Database</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Fri, 30 Oct 2026 07:02:13 +0000</pubDate>
      <link>https://dev.to/lightcloud/run-sql-in-the-browser-queries-joins-and-quick-fixes-on-a-live-database-5gdf</link>
      <guid>https://dev.to/lightcloud/run-sql-in-the-browser-queries-joins-and-quick-fixes-on-a-live-database-5gdf</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3dkyqlqonft3a0x3zrf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff3dkyqlqonft3a0x3zrf.webp" alt="Run SQL in the Browser: Queries, Joins and Quick Fixes on a Live Database" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run SQL on a Light Cloud PostgreSQL database from the browser, open the database's &lt;strong&gt;Data&lt;/strong&gt; tab, type the query in the box above the table, and click &lt;strong&gt;Run query&lt;/strong&gt;. The box is read-only by default, so a stray &lt;code&gt;UPDATE&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt; is rejected. To change data, tick &lt;strong&gt;Allow writes&lt;/strong&gt; first.&lt;/p&gt;

&lt;p&gt;This is part 3 of the database series. It uses the &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt; and the &lt;code&gt;reviews&lt;/code&gt; table from &lt;a href="https://blog.light-cloud.com/tutorials/database-data-explorer" rel="noopener noreferrer"&gt;part 2&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run a first query with a join and totals.&lt;/li&gt;
&lt;li&gt;Join three tables.&lt;/li&gt;
&lt;li&gt;See a write being rejected, then make a quick fix safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;bookshop-db&lt;/code&gt; database from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;, with the changes from &lt;a href="https://blog.light-cloud.com/tutorials/database-data-explorer" rel="noopener noreferrer"&gt;part 2&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Light Cloud account on the &lt;strong&gt;Lite&lt;/strong&gt; plan or higher.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Run a first query
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;a href="https://console.light-cloud.com" rel="noopener noreferrer"&gt;Light Cloud console&lt;/a&gt;, open &lt;strong&gt;bookshop-db&lt;/strong&gt; and its &lt;strong&gt;Data&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Click into the box that says &lt;code&gt;SELECT * FROM my_table LIMIT 10;&lt;/code&gt; and paste this query. It shows how many books each author has, and what their stock is worth:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in_stock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;stock_value&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;stock_value&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Run query&lt;/strong&gt; , or press &lt;strong&gt;Cmd+Enter&lt;/strong&gt; ( &lt;strong&gt;Ctrl+Enter&lt;/strong&gt; on Windows and Linux).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkl4l7bgqczh3hq9s2skv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkl4l7bgqczh3hq9s2skv.webp" alt="The query box with the stock value query, the Run query button highlighted, and the result: Terry Pratchett 3 books 332.63, Ursula K. Le Guin 3 237.88, Octavia E. Butler 2 134.25, Stanislaw Lem 2 69.00" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result appears under &lt;strong&gt;Query result&lt;/strong&gt; , with the number of rows and how long the database took. Terry Pratchett has 3 books because of &lt;em&gt;Mort&lt;/em&gt;, the book you added in part 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Join three tables
&lt;/h2&gt;

&lt;p&gt;Reviews point at books, and books point at authors. To see each review with its book and author, join all three:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;reviews&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;book_id&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result has one row: &lt;em&gt;Mort&lt;/em&gt;, Terry Pratchett, rating 5, "Funny, kind and about Death."&lt;/p&gt;

&lt;p&gt;Queries like this are what the box is best at: quick questions about live data, without setting up a client. Another useful one, the books that are running low:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_stock&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;in_stock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;in_stock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns &lt;em&gt;The Cyberiad&lt;/em&gt; (2), &lt;em&gt;Parable of the Sower&lt;/em&gt; (3) and &lt;em&gt;The Left Hand of Darkness&lt;/em&gt; (4).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Try a write
&lt;/h2&gt;

&lt;p&gt;The shop raises the price of every Terry Pratchett book to 9.49. Paste this and click &lt;strong&gt;Run query&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;RETURNING&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fails:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskhcrcni9c1mtqplmxnm.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fskhcrcni9c1mtqplmxnm.webp" alt="The UPDATE statement in the query box and the result cannot execute UPDATE in a read-only transaction, highlighted" width="799" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is the safety net: the note under the box says &lt;strong&gt;Read-only session&lt;/strong&gt; , and every statement that would change data is rejected. Nothing was changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Make the fix with Allow writes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Tick &lt;strong&gt;Allow writes&lt;/strong&gt;. The note turns orange: &lt;strong&gt;Writes enabled - statements run with full access to this database.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Run query&lt;/strong&gt; again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkyap1xe7izvqb7vbq8ib.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkyap1xe7izvqb7vbq8ib.webp" alt="Allow writes ticked and highlighted, the warning that statements run with full access, and the result listing Guards! Guards!, Small Gods and Mort, each with price 9.49" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RETURNING id, title, price&lt;/code&gt; makes the statement list the rows it changed: three books, each now 9.49. Without &lt;code&gt;RETURNING&lt;/code&gt;, the result says &lt;strong&gt;0 rows&lt;/strong&gt; , even though the update worked, because the statement itself returns no rows.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Untick &lt;strong&gt;Allow writes&lt;/strong&gt; when you are done, so the next query is read-only again.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Before you write to a production database
&lt;/h2&gt;

&lt;p&gt;A few habits that keep quick fixes quick:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run the &lt;code&gt;SELECT&lt;/code&gt; first.&lt;/strong&gt; Write the &lt;code&gt;WHERE&lt;/code&gt; clause as a &lt;code&gt;SELECT&lt;/code&gt; (&lt;code&gt;SELECT id, title, price FROM books WHERE author_id = 2;&lt;/code&gt;), check the rows, then turn it into the &lt;code&gt;UPDATE&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always use &lt;code&gt;WHERE&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;UPDATE books SET price = 9.49&lt;/code&gt; without it changes every book.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add &lt;code&gt;RETURNING&lt;/code&gt;.&lt;/strong&gt; You see exactly what changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back up before big changes.&lt;/strong&gt; The &lt;strong&gt;Backup&lt;/strong&gt; tab downloads the whole database; &lt;a href="https://blog.light-cloud.com/tutorials/export-a-database-backup" rel="noopener noreferrer"&gt;part 4&lt;/a&gt; shows how.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leave schema changes to migrations.&lt;/strong&gt; &lt;code&gt;CREATE&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt; and &lt;code&gt;DROP&lt;/code&gt; belong in your app's migrations, so every environment gets them. Part 7 covers migrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A query stops after &lt;strong&gt;10 seconds&lt;/strong&gt; , with &lt;code&gt;canceling statement due to statement timeout&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The result shows at most &lt;strong&gt;500 rows&lt;/strong&gt; , marked &lt;strong&gt;truncated - refine the query to see more&lt;/strong&gt;. Add a &lt;code&gt;WHERE&lt;/code&gt; or &lt;code&gt;LIMIT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A query can be up to &lt;strong&gt;20,000 characters&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Several statements separated by semicolons all run; only the last one's result is shown.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For long jobs or large exports, connect with &lt;code&gt;psql&lt;/code&gt; as in &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  cannot execute UPDATE in a read-only transaction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Allow writes&lt;/strong&gt; is not ticked. The same applies to &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;CREATE&lt;/code&gt; and every other statement that changes something.&lt;/p&gt;

&lt;h3&gt;
  
  
  canceling statement due to statement timeout
&lt;/h3&gt;

&lt;p&gt;The query ran for more than 10 seconds. Narrow it with &lt;code&gt;WHERE&lt;/code&gt; or &lt;code&gt;LIMIT&lt;/code&gt;, or run it with &lt;code&gt;psql&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  relation "..." does not exist
&lt;/h3&gt;

&lt;p&gt;The table name is misspelt, or the table is in another schema. The table list on the left shows the exact names.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Free REST API Hosting</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Thu, 29 Oct 2026 17:31:02 +0000</pubDate>
      <link>https://dev.to/lightcloud/free-rest-api-hosting-mh3</link>
      <guid>https://dev.to/lightcloud/free-rest-api-hosting-mh3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdes5rfuzjqzu3k61yapn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdes5rfuzjqzu3k61yapn.webp" alt="Free REST API Hosting" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to host a small Express or FastAPI app for free, with no card and no surprise bill, Light Cloud's Free plan is the only one of the eight below that passes every check: it runs the app as it is, wakes in a few seconds and never bills you. It does that up to about 4,800 requests a day. Cloudflare Workers comes second and gives you far more room, 100,000 requests a day, but only for code written for its runtime. Vercel, Render, Google Cloud Run, Netlify, AWS Lambda and Railway are all free in some form, each with a catch the table names.&lt;/p&gt;

&lt;p&gt;Disclosure: I make Light Cloud. The checks are written down below, so you can score the eight yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;"Free API hosting" means different things on different pricing pages, so I fixed the API first. It's an Express or FastAPI app serving 3,000 requests a day, each taking 0.2 seconds, which is the "steady" API on Light Cloud's own pricing page. No database for now; that comes at the end.&lt;/p&gt;

&lt;p&gt;Each free plan then got a point for each of five checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it costs $0 for that API;&lt;/li&gt;
&lt;li&gt;the vendor's current pages say no card is needed to sign up;&lt;/li&gt;
&lt;li&gt;the app runs as it is, without being rewritten into a function format;&lt;/li&gt;
&lt;li&gt;nothing documented makes the first request after a quiet spell wait about a minute, or fail;&lt;/li&gt;
&lt;li&gt;the free plan has no end date and can't put a charge on a card.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ties go to the plan whose vendor restricts less what you may run on it, such as production or commercial use, and then to the faster first request. Fly.io, Heroku, Koyeb and DigitalOcean aren't scored: Fly has no free tier for new accounts, Heroku dropped its free dynos in 2022, Koyeb has asked new users to choose a paid plan since February 2026, and DigitalOcean's free tier covers static sites only. Everything was checked on 2026-10-13.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;th&gt;Reference API a month&lt;/th&gt;
&lt;th&gt;Card at sign-up&lt;/th&gt;
&lt;th&gt;After an idle spell&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;$0, uses $0.64 of the $1 included&lt;/td&gt;
&lt;td&gt;No card&lt;/td&gt;
&lt;td&gt;Answers in 3.1 to 3.7 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Cloudflare Workers&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;$0, up to 100,000 requests a day&lt;/td&gt;
&lt;td&gt;No card&lt;/td&gt;
&lt;td&gt;No sleep documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;$0 on Hobby, non-commercial only&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;Functions, no sleep documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;$0, one free web service&lt;/td&gt;
&lt;td&gt;No card&lt;/td&gt;
&lt;td&gt;Spins down; about a minute to wake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Google Cloud Run&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$0 inside the free tier&lt;/td&gt;
&lt;td&gt;Billing account&lt;/td&gt;
&lt;td&gt;Scales to zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Netlify&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$0, about 70 of 300 credits&lt;/td&gt;
&lt;td&gt;Not stated on current pages&lt;/td&gt;
&lt;td&gt;Functions, no sleep documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;AWS Lambda&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;$0 inside the free tier&lt;/td&gt;
&lt;td&gt;Not needed for most new accounts&lt;/td&gt;
&lt;td&gt;Functions, no sleep documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;$1 credit, may not cover a month&lt;/td&gt;
&lt;td&gt;No card&lt;/td&gt;
&lt;td&gt;Sleep is opt-in; first request may 502&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Vendors' own pricing, limits and docs pages, checked 2026-10-13. Reference API: 3,000 requests a day at 0.2 s each, no database. "Not stated" means the vendor's current pages don't say either way, so the point isn't given.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a small API that should stay free, need no card and never send a bill.&lt;/p&gt;

&lt;p&gt;Five points. The Free plan includes $1 of usage a month, 3 server apps and no card (&lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Our pricing page works out this exact API: 3,000 requests a day at 0.2 s is 5 instance-hours a month at $0.12, plus two deploys, $0.64 in all. You push the repository and it runs; there are &lt;a href="https://blog.light-cloud.com/tutorials/deploy-an-express-api" rel="noopener noreferrer"&gt;Express&lt;/a&gt; and &lt;a href="https://blog.light-cloud.com/tutorials/deploy-a-fastapi-app" rel="noopener noreferrer"&gt;FastAPI&lt;/a&gt; walkthroughs, and the same works to &lt;a href="https://light-cloud.com/frameworks" rel="noopener noreferrer"&gt;deploy Express, FastAPI, Go and Spring Boot APIs&lt;/a&gt; without a Dockerfile, with &lt;a href="https://light-cloud.com/deployments" rel="noopener noreferrer"&gt;deploys on every git push&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Free never bills. If the $1 runs out, the API pauses until next month and nothing reaches your card, because there isn't one. On the same formula the $1 lasts up to about 4,800 requests a day; past that, Lite is $5 a month with $5 of usage. A container that has scaled to zero answers its first request in &lt;a href="https://blog.light-cloud.com/tutorials/microservices-on-light-cloud-part-4-cold-starts" rel="noopener noreferrer"&gt;3.1 to 3.7 seconds&lt;/a&gt;, then fast.&lt;/p&gt;

&lt;p&gt;The limits, plainly: Free apps live on a light-cloud.io address, with no custom domain, and Free has no database at all. Your own domain and Postgres start on Lite, which is also where you get &lt;a href="https://light-cloud.com/domains" rel="noopener noreferrer"&gt;your own domain with free SSL&lt;/a&gt;. There's no cron and no private network between services.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cloudflare Workers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; APIs written for the Workers runtime that need far more free requests than anyone else gives.&lt;/p&gt;

&lt;p&gt;Four points. Workers Free allows 100,000 requests a day, reset at midnight UTC (&lt;a href="https://developers.cloudflare.com/workers/platform/limits/" rel="noopener noreferrer"&gt;limits&lt;/a&gt;), and Cloudflare's &lt;a href="https://workers.cloudflare.com/plans" rel="noopener noreferrer"&gt;plans page&lt;/a&gt; says no credit card is required. Go over and requests fail with Error 1027; nothing is billed. Nobody else here comes close on volume: that's 33 times the reference API.&lt;/p&gt;

&lt;p&gt;The point it loses is the runtime. A Worker isn't a Node server or a container; you write for Cloudflare's runtime in JavaScript, TypeScript, Python or Rust (&lt;a href="https://developers.cloudflare.com/workers/languages/" rel="noopener noreferrer"&gt;languages&lt;/a&gt;), and each invocation gets 10 ms of CPU on Free. Cloudflare's docs include a FastAPI guide for Python Workers, so a small FastAPI app may port with little work. An Express app built around a long-running server needs more.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Vercel
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; personal projects whose API lives next to a Vercel frontend.&lt;/p&gt;

&lt;p&gt;Four points. Hobby includes 1 million function invocations and 4 hours of active CPU a month and can't buy more, so it can't bill you; go over and the feature pauses (&lt;a href="https://vercel.com/docs/plans/hobby" rel="noopener noreferrer"&gt;Hobby&lt;/a&gt;). A Docker image can run as a function on every plan, in beta, so the app needn't change much.&lt;/p&gt;

&lt;p&gt;The catch is the use, not the money. Vercel's &lt;a href="https://vercel.com/docs/limits/fair-use-guidelines" rel="noopener noreferrer"&gt;fair use guidelines&lt;/a&gt; limit Hobby to non-commercial personal use, and a paid developer or taking payments counts as commercial. I also couldn't find a current Vercel page that says whether Hobby needs a card, so that point isn't given.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; running an unchanged app for free when a slow first request is fine.&lt;/p&gt;

&lt;p&gt;Four points. A free web service runs any Docker or native app as it is, no card is needed, and a workspace gets 750 free instance hours a month, enough for one service around the clock (&lt;a href="https://render.com/docs/free" rel="noopener noreferrer"&gt;free tier&lt;/a&gt;). Without a card on file, going over the free bandwidth suspends free services instead of billing.&lt;/p&gt;

&lt;p&gt;It loses the wake-up point. A free web service spins down after 15 minutes without traffic, and Render says waking takes about one minute. That's fine for a portfolio demo and painful for a mobile app's login call. Render also says plainly that free instances are not for production.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Google Cloud Run
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; the biggest free container allowance, if a billing account is fine.&lt;/p&gt;

&lt;p&gt;Three points. The free tier covers 2 million requests and 180,000 vCPU-seconds a month (&lt;a href="https://cloud.google.com/run/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), and the reference API uses 90,000 requests and about 18,000 vCPU-seconds. It runs your container unchanged and scales to zero.&lt;/p&gt;

&lt;p&gt;But the free tier needs a Google Cloud billing account, and usage beyond it is billed at standard rates, not paused. Spend caps that pause Cloud Run at a budget became generally available on 2026-10-12, which helps. You'll also wire up a custom domain yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Netlify
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; small function-based APIs next to a Netlify site.&lt;/p&gt;

&lt;p&gt;Three points. The Free plan has 300 credits a month with a hard limit and is never billed (&lt;a href="https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/credit-based-pricing-plans/" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). By its rates the reference API uses about 18 credits for requests and 50 for function compute at the default 1 GB, around 70, plus 15 per production deploy. It also includes Netlify Database, a Postgres that sleeps after 5 idle minutes, which matters for an API.&lt;/p&gt;

&lt;p&gt;Two points go missing: the API becomes Netlify Functions rather than your Express server, and the current pricing docs don't say whether a card is needed. When credits run out, every project on the team pauses, the site included.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. AWS Lambda
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams heading for AWS anyway.&lt;/p&gt;

&lt;p&gt;Three points. Lambda's free tier is one million requests and 400,000 GB-seconds a month (&lt;a href="https://aws.amazon.com/lambda/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;); the reference API at 512 MB uses about 9,000. A function URL gives it an HTTPS endpoint, and most new customers sign up without a payment method.&lt;/p&gt;

&lt;p&gt;The app needs adapting: a container image, for example, must include Lambda's runtime interface client. And AWS's Free plan &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;closes the account after six months&lt;/a&gt; or when its credits run out, unless you move to the Paid plan, which bills usage beyond the free limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; trying an API on the platform you'll pay $5 for later.&lt;/p&gt;

&lt;p&gt;Two points. After a 30-day trial, the Free plan gives $1 of credit a month, needs no card and runs your app as it is (&lt;a href="https://docs.railway.com/pricing/free-trial" rel="noopener noreferrer"&gt;free plan&lt;/a&gt;). But Railway bills RAM at $10 per GB a month for what your process holds, so an API holding 100 MB around the clock uses the whole dollar before any CPU. Turn on sleep to save it and Railway warns the first request may return a 502. Railway's docs don't say what happens when the free credit runs out, so the last point isn't given either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;On volume, Cloudflare Workers wins without contest: 100,000 free requests a day against our roughly 4,800. If your API is JavaScript or Python and you're happy to write it for Workers, that's the better free home. Need a free database too? We have none on Free; Netlify includes one, and a free Neon or Supabase database works next to any row here. A custom domain on a free API is something we only offer from Lite. And if your API is part of a bigger AWS or Google Cloud setup, Lambda and Cloud Run sit closer to everything else you run.&lt;/p&gt;

&lt;p&gt;What we do differently is the shape of the promise. No card, an unchanged Express or FastAPI app, a first request in seconds rather than a minute, and a plan that pauses instead of billing. If that's the &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;free REST API hosting&lt;/a&gt; you were looking for, it's &lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;free hosting with no credit card&lt;/a&gt; up to the point where your API has real users, and then $5.&lt;/p&gt;

&lt;p&gt;How many requests a day does your API actually get?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>api</category>
      <category>node</category>
    </item>
    <item>
      <title>Browse and Edit Your Data Without a SQL Client: the Data Explorer</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Thu, 29 Oct 2026 09:12:02 +0000</pubDate>
      <link>https://dev.to/lightcloud/browse-and-edit-your-data-without-a-sql-client-the-data-explorer-1i0b</link>
      <guid>https://dev.to/lightcloud/browse-and-edit-your-data-without-a-sql-client-the-data-explorer-1i0b</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv0nlheswwucmv6i7kjz0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv0nlheswwucmv6i7kjz0.webp" alt="Browse and Edit Your Data Without a SQL Client: the Data Explorer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To browse and edit a PostgreSQL database on Light Cloud without a SQL client, open the database in the console and click the &lt;strong&gt;Data&lt;/strong&gt; tab. It lists every table. Click a table to see its rows, click a row to edit it, and use &lt;strong&gt;Insert row&lt;/strong&gt; , &lt;strong&gt;Columns&lt;/strong&gt; and &lt;strong&gt;New&lt;/strong&gt; to add rows, columns and tables.&lt;/p&gt;

&lt;p&gt;This is part 2 of the database series. It uses the &lt;code&gt;bookshop-db&lt;/code&gt; database and sample data from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will do
&lt;/h2&gt;

&lt;p&gt;In the bookshop database, you will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;change the stock of one book,&lt;/li&gt;
&lt;li&gt;add a new book,&lt;/li&gt;
&lt;li&gt;add an &lt;code&gt;isbn&lt;/code&gt; column to &lt;code&gt;books&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;create a &lt;code&gt;reviews&lt;/code&gt; table and add reviews,&lt;/li&gt;
&lt;li&gt;delete a row safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;bookshop-db&lt;/code&gt; database with the sample data, from &lt;a href="https://blog.light-cloud.com/tutorials/create-a-postgres-database" rel="noopener noreferrer"&gt;part 1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A Light Cloud account on the &lt;strong&gt;Lite&lt;/strong&gt; plan or higher.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing to install: everything happens in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Open a table
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;a href="https://console.light-cloud.com" rel="noopener noreferrer"&gt;Light Cloud console&lt;/a&gt;, click &lt;strong&gt;bookshop-db&lt;/strong&gt; in the sidebar.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Data&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;books&lt;/strong&gt; in the table list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The table shows 50 rows per page. Click a column name to sort by it. Nothing you do while browsing changes the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Edit a row
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The Dispossessed&lt;/em&gt; is back in stock. Click its row. The &lt;strong&gt;Edit row&lt;/strong&gt; window shows every column with its type, and whether it may be empty (&lt;code&gt;not null&lt;/code&gt; means it may not):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change &lt;strong&gt;in_stock&lt;/strong&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;6&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save changes&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F277a1vnased7viisy9dv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F277a1vnased7viisy9dv.webp" alt="The Edit row window for The Dispossessed, with in_stock changed to 6 and the Save changes button highlighted" width="672" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only the fields you changed are saved, so you cannot overwrite a column you did not touch. The console confirms with &lt;strong&gt;Row updated&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Insert a row
&lt;/h2&gt;

&lt;p&gt;Click &lt;strong&gt;Insert row&lt;/strong&gt; above the table and fill in a new book:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;leave empty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;title&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Mort&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;author_id&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;year&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1987&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;price&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8.99&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;in_stock&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F33ft7mkus29ieoqdb4ve.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F33ft7mkus29ieoqdb4ve.webp" alt="The Insert row window with id showing default, title Mort, author_id 2, year 1987, price 8.99, in_stock 10, and the Insert button highlighted" width="672" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Insert&lt;/strong&gt;. Empty fields get the column's default, so PostgreSQL picks the next &lt;code&gt;id&lt;/code&gt;, 10. &lt;code&gt;author_id&lt;/code&gt; 2 is Terry Pratchett in the &lt;code&gt;authors&lt;/code&gt; table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Add a column
&lt;/h2&gt;

&lt;p&gt;The shop wants to store ISBNs. Click &lt;strong&gt;Columns&lt;/strong&gt; above the table, then &lt;strong&gt;Add column&lt;/strong&gt; :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Name it &lt;code&gt;isbn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Choose the type &lt;strong&gt;text&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Leave &lt;strong&gt;NULL&lt;/strong&gt; ticked, so existing books may have no ISBN yet.&lt;/li&gt;
&lt;li&gt;Click the green tick.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F07dgltp6npx7tjp8utro.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F07dgltp6npx7tjp8utro.webp" alt="The Manage columns window for books with a new column isbn of type text, NULL ticked, and the confirm tick highlighted" width="672" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Changes in this window apply at once. The pencil next to a column renames it, and the bin drops it. Click &lt;strong&gt;Done&lt;/strong&gt;. Every book now has an &lt;code&gt;isbn&lt;/code&gt; column showing &lt;code&gt;NULL&lt;/code&gt;, which means empty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Create a table
&lt;/h2&gt;

&lt;p&gt;Readers want to leave reviews. Click &lt;strong&gt;New&lt;/strong&gt; next to &lt;strong&gt;Tables&lt;/strong&gt; and fill in the &lt;strong&gt;New table&lt;/strong&gt; window:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Table name&lt;/strong&gt; : &lt;code&gt;reviews&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The first column is already there: &lt;code&gt;id&lt;/code&gt;, type &lt;strong&gt;serial&lt;/strong&gt; , &lt;strong&gt;PK&lt;/strong&gt; ticked. &lt;strong&gt;serial&lt;/strong&gt; numbers new rows automatically, and &lt;strong&gt;PK&lt;/strong&gt; makes &lt;code&gt;id&lt;/code&gt; the primary key.&lt;/li&gt;
&lt;li&gt;Second column: &lt;code&gt;book_id&lt;/code&gt;, type &lt;strong&gt;integer&lt;/strong&gt; , &lt;strong&gt;NULL&lt;/strong&gt; not ticked.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add column&lt;/strong&gt;. Third column: &lt;code&gt;rating&lt;/code&gt;, type &lt;strong&gt;integer&lt;/strong&gt; , &lt;strong&gt;NULL&lt;/strong&gt; not ticked.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add column&lt;/strong&gt;. Fourth column: &lt;code&gt;body&lt;/code&gt;, type &lt;strong&gt;text&lt;/strong&gt; , &lt;strong&gt;NULL&lt;/strong&gt; ticked.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faf4tmtbrd6erzvtu4v8g.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faf4tmtbrd6erzvtu4v8g.webp" alt="The New table window with table name reviews and the columns id serial PK, book_id integer, rating integer and body text with NULL ticked, and the Create table button highlighted" width="672" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create table&lt;/strong&gt;. &lt;code&gt;reviews&lt;/code&gt; appears in the table list, empty. Add two reviews with &lt;strong&gt;Insert row&lt;/strong&gt; , leaving &lt;code&gt;id&lt;/code&gt; empty each time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;book_id&lt;/code&gt; &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;rating&lt;/code&gt; &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt; &lt;code&gt;Funny, kind and about Death.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;book_id&lt;/code&gt; &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;rating&lt;/code&gt; &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt; &lt;code&gt;test&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep a primary key on every table you create here: the data explorer can only edit rows of tables that have one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Delete a row safely
&lt;/h2&gt;

&lt;p&gt;The second review was a test. Tick its checkbox, then click &lt;strong&gt;Delete selected&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0mjhd55q5byhv4ybb80.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0mjhd55q5byhv4ybb80.webp" alt="The reviews table with the test row ticked, 1 selected, and the Delete selected button highlighted" width="798" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The console asks first, and says how many rows will go:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdr3cgfknhhzrwpklxzk8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdr3cgfknhhzrwpklxzk8.webp" alt="The Delete 1 row confirmation saying the selected rows will be permanently deleted and the action cannot be undone, with the Delete row button highlighted" width="448" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check the number, then click &lt;strong&gt;Delete row&lt;/strong&gt;. To delete a single row, you can also open it and click &lt;strong&gt;Delete row...&lt;/strong&gt; in the &lt;strong&gt;Edit row&lt;/strong&gt; window.&lt;/p&gt;

&lt;p&gt;Deleting cannot be undone, and neither can dropping a column or a table. Before a big cleanup, download a backup from the &lt;strong&gt;Backup&lt;/strong&gt; tab; &lt;a href="https://blog.light-cloud.com/tutorials/export-a-database-backup" rel="noopener noreferrer"&gt;part 4&lt;/a&gt; shows how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the result
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;books&lt;/strong&gt; again and click &lt;strong&gt;id&lt;/strong&gt; to sort. The Dispossessed has 6 in stock, Mort is book 10, and every book has an empty &lt;code&gt;isbn&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftx6ccj4cx6p4v2ty0qmk.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftx6ccj4cx6p4v2ty0qmk.webp" alt="The books table sorted by id, showing 10 rows including Mort, and the new isbn column with NULL in every row" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same changes are visible to anything that connects to the database, such as &lt;code&gt;psql&lt;/code&gt; or your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clicking a row does nothing
&lt;/h3&gt;

&lt;p&gt;The table has no primary key, so the explorer cannot tell rows apart; the header above the rows says &lt;strong&gt;read-only - no primary key&lt;/strong&gt;. Add a primary key with SQL, or edit such tables with SQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Could not save the row
&lt;/h3&gt;

&lt;p&gt;The window shows the database's reason. The most common: a &lt;code&gt;not null&lt;/code&gt; field left empty, or text in a number field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Could not add the column
&lt;/h3&gt;

&lt;p&gt;Adding a column that may not be empty fails on a table that already has rows, because the existing rows would have no value. Leave &lt;strong&gt;NULL&lt;/strong&gt; ticked, fill in the values, and tighten the rule later with SQL.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Create a PostgreSQL Database in One Minute and Connect From Your Laptop</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Wed, 28 Oct 2026 08:28:52 +0000</pubDate>
      <link>https://dev.to/lightcloud/create-a-postgresql-database-in-one-minute-and-connect-from-your-laptop-1akb</link>
      <guid>https://dev.to/lightcloud/create-a-postgresql-database-in-one-minute-and-connect-from-your-laptop-1akb</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fcqn11ol9jnc0gwyacr.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6fcqn11ol9jnc0gwyacr.webp" alt="Create a PostgreSQL Database in One Minute and Connect From Your Laptop" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a PostgreSQL database on Light Cloud, click &lt;strong&gt;New...&lt;/strong&gt; , &lt;strong&gt;New Database&lt;/strong&gt; in the console and then &lt;strong&gt;Create database&lt;/strong&gt;. A Dev database is ready in about ten seconds. To connect from your laptop, copy the connection string from the &lt;strong&gt;Credentials&lt;/strong&gt; tab, add &lt;code&gt;?sslmode=require&lt;/code&gt; to the end, and pass it to &lt;code&gt;psql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is part 1 of a series on databases. Here you create the database, load a small bookshop into it, look at it in the console, and connect from Node.js and Python. Later parts use the same database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will build
&lt;/h2&gt;

&lt;p&gt;A PostgreSQL database named &lt;code&gt;bookshop-db&lt;/code&gt; with two tables, &lt;code&gt;authors&lt;/code&gt; and &lt;code&gt;books&lt;/code&gt;, that you can reach from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;psql&lt;/code&gt; in your terminal,&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Data&lt;/strong&gt; tab in the console,&lt;/li&gt;
&lt;li&gt;a Node.js script and a Python script.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source code and sample data: &lt;a href="https://github.com/light-cloud-com/tutorial-database-basics" rel="noopener noreferrer"&gt;github.com/light-cloud-com/tutorial-database-basics&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Light Cloud account on the &lt;strong&gt;Lite&lt;/strong&gt; plan or higher: the Free plan has no databases.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git&lt;/a&gt; and a terminal. On Windows, use &lt;a href="https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows" rel="noopener noreferrer"&gt;PowerShell 7&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For the last step, &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; 20 or later and &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; 3.10 or later. I used Node.js 22 and Python 3.13.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Install psql
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;psql&lt;/code&gt; is the PostgreSQL command-line client. You only need the client, not a PostgreSQL server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;libpq
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc


&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;postgresql-client

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On macOS this uses &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt;. Homebrew does not put &lt;code&gt;libpq&lt;/code&gt; on your &lt;code&gt;PATH&lt;/code&gt; by itself, hence the second line. On Fedora and other Linux distributions, the package is also called &lt;code&gt;postgresql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On Windows, run the &lt;a href="https://www.enterprisedb.com/downloads/postgres-postgresql-downloads" rel="noopener noreferrer"&gt;PostgreSQL installer&lt;/a&gt; and select only &lt;strong&gt;Command Line Tools&lt;/strong&gt;. Then add its &lt;code&gt;bin&lt;/code&gt; folder, for example &lt;code&gt;C:\Program Files\PostgreSQL\17\bin&lt;/code&gt;, to your &lt;code&gt;PATH&lt;/code&gt; and open a new PowerShell window.&lt;/p&gt;

&lt;p&gt;Check that it works. Any recent version is fine; I used 17.5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ psql --version
psql (PostgreSQL) 17.5


PS&amp;gt; psql --version
psql (PostgreSQL) 17.5

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create the database
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;a href="https://console.light-cloud.com" rel="noopener noreferrer"&gt;Light Cloud console&lt;/a&gt;, click &lt;strong&gt;New...&lt;/strong&gt; and then &lt;strong&gt;New Database&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;PostgreSQL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;bookshop-db&lt;/code&gt; and keep &lt;strong&gt;Size&lt;/strong&gt; at &lt;strong&gt;Dev&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create database&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bv0rbwjjqmer2mq9yem.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0bv0rbwjjqmer2mq9yem.webp" alt="The Create page with Database selected, Name bookshop-db, Size Dev, Storage 1 GB and Region Belgium, and the Create database button highlighted" width="768" height="784"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my run the database was &lt;strong&gt;Ready&lt;/strong&gt; ten seconds later.&lt;/p&gt;

&lt;p&gt;Which size to pick:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt; runs on a shared instance, is ready in seconds, and allows 10 connections per database user. It is the right choice for development, side projects and these tutorials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starter&lt;/strong&gt; (0.6 GB RAM) and &lt;strong&gt;Pro&lt;/strong&gt; (1.7 GB RAM) get an instance of their own, take 10 to 20 minutes to create, and need the Starter plan or higher.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Copy the connection string
&lt;/h2&gt;

&lt;p&gt;Open the &lt;strong&gt;Credentials&lt;/strong&gt; tab. It shows the host, port, database name, user and password, and the whole connection string. Click &lt;strong&gt;Copy&lt;/strong&gt; next to the connection string:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnvkek4e1psfqb5nfwlht.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnvkek4e1psfqb5nfwlht.webp" alt="The Credentials tab with host, port and masked database name, user and password, and the Copy button of the connection string highlighted" width="799" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;?sslmode=require&lt;/code&gt; to the end, and save it as &lt;code&gt;DATABASE_URL&lt;/code&gt; in your terminal. The database only accepts encrypted connections, and this setting asks for one. Paste your own string instead of the stars:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'postgresql://u_ ******:******** @bookshop-db-yourworkspace.db.light-cloud.io:5432/db ******?sslmode=require'&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;PS&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'postgresql://u_ ******:******** @bookshop-db-yourworkspace.db.light-cloud.io:5432/db ******?sslmode=require'&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the single quotes: they stop the shell from changing special characters in the password. The variable lasts until you close the terminal. It contains the password, so keep it out of Git and screenshots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Connect with psql
&lt;/h2&gt;

&lt;p&gt;Check the connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'\conninfo'&lt;/span&gt;
&lt;span class="go"&gt;You are connected to database "db ******" as user "u_******" on host "bookshop-db-yourworkspace.db.light-cloud.io" (address "***") at port "5432".
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: none)


&lt;/span&gt;&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;:DATABASE_URL"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'\conninfo'&lt;/span&gt;
&lt;span class="go"&gt;You are connected to database "db ******" as user "u_******" on host "bookshop-db-yourworkspace.db.light-cloud.io" (address "***") at port "5432".
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: none)

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SSL connection&lt;/code&gt; confirms the connection is encrypted. To work interactively, run &lt;code&gt;psql "$DATABASE_URL"&lt;/code&gt; (on Windows, &lt;code&gt;psql "$env:DATABASE_URL"&lt;/code&gt;) without &lt;code&gt;-c&lt;/code&gt;, and type &lt;code&gt;\q&lt;/code&gt; to leave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Load the sample data
&lt;/h2&gt;

&lt;p&gt;Clone the repository and run its &lt;code&gt;seed.sql&lt;/code&gt; against the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone https://github.com/light-cloud-com/tutorial-database-basics.git
&lt;span class="go"&gt;Cloning into 'tutorial-database-basics'...
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tutorial-database-basics
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; seed.sql
&lt;span class="go"&gt;psql:seed.sql:4: NOTICE: table "books" does not exist, skipping
DROP TABLE
psql:seed.sql:5: NOTICE: table "authors" does not exist, skipping
DROP TABLE
CREATE TABLE
CREATE TABLE
INSERT 0 4
INSERT 0 9


&lt;/span&gt;&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone https://github.com/light-cloud-com/tutorial-database-basics.git
&lt;span class="go"&gt;Cloning into 'tutorial-database-basics'...
&lt;/span&gt;&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tutorial-database-basics
&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;:DATABASE_URL"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; seed.sql
&lt;span class="go"&gt;psql:seed.sql:4: NOTICE: table "books" does not exist, skipping
DROP TABLE
psql:seed.sql:5: NOTICE: table "authors" does not exist, skipping
DROP TABLE
CREATE TABLE
CREATE TABLE
INSERT 0 4
INSERT 0 9

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two notices are expected on a new database: the script first drops its tables so you can run it again to reset the data. You now have 4 authors and 9 books. Ask for the five oldest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT title, year FROM books ORDER BY year LIMIT 5;"&lt;/span&gt;
&lt;span class="go"&gt;           title | year
---------------------------+------
 Solaris | 1961
 The Cyberiad | 1965
 A Wizard of Earthsea | 1968
 The Left Hand of Darkness | 1969
 The Dispossessed | 1974
(5 rows)


&lt;/span&gt;&lt;span class="gp"&gt;PS&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;psql &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;:DATABASE_URL"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SELECT title, year FROM books ORDER BY year LIMIT 5;"&lt;/span&gt;
&lt;span class="go"&gt;           title | year
---------------------------+------
 Solaris | 1961
 The Cyberiad | 1965
 A Wizard of Earthsea | 1968
 The Left Hand of Darkness | 1969
 The Dispossessed | 1974
(5 rows)

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: See the data in the console
&lt;/h2&gt;

&lt;p&gt;Back in the console, open the &lt;strong&gt;Data&lt;/strong&gt; tab and click &lt;strong&gt;books&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1et68mn1p0f7fj0fkzch.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1et68mn1p0f7fj0fkzch.webp" alt="The Data tab with the tables authors and books, books selected, showing 9 rows with id, title, author_id, year, price and in_stock" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the data explorer: every table in the database, its rows, and a SQL box above them. The session is read-only unless you tick &lt;strong&gt;Allow writes&lt;/strong&gt; , so browsing cannot change anything by accident. &lt;a href="https://blog.light-cloud.com/tutorials/database-data-explorer" rel="noopener noreferrer"&gt;Part 2&lt;/a&gt; covers editing rows and tables here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Connect from Node.js and Python
&lt;/h2&gt;

&lt;p&gt;The repository has one small script per language. Each connects with &lt;code&gt;DATABASE_URL&lt;/code&gt; and counts the books.&lt;/p&gt;

&lt;p&gt;Python, with &lt;a href="https://www.psycopg.org/psycopg3/" rel="noopener noreferrer"&gt;psycopg&lt;/a&gt;, uses the string exactly as you saved it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 -m venv .venv
$ .venv/bin/pip install -r requirements.txt
$ .venv/bin/python connect/python.py
Connected from Python: 9 books


PS&amp;gt; python -m venv .venv
PS&amp;gt; .venv\Scripts\pip install -r requirements.txt
PS&amp;gt; .venv\Scripts\python connect\python.py
Connected from Python: 9 books

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Node.js, with &lt;a href="https://node-postgres.com/" rel="noopener noreferrer"&gt;node-postgres&lt;/a&gt;, needs one more setting at the end, &lt;code&gt;&amp;amp;uselibpqcompat=true&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install
$ DATABASE_URL="$DATABASE_URL&amp;amp;uselibpqcompat=true" node connect/node.mjs
Connected from Node.js: 9 books


PS&amp;gt; npm install
PS&amp;gt; $env:DATABASE_URL = "$env:DATABASE_URL&amp;amp;uselibpqcompat=true"
PS&amp;gt; node connect/node.mjs
Connected from Node.js: 9 books

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npm install&lt;/code&gt; also prints how many packages it added. On Windows, the variable keeps the Node.js ending from now on, so run the Python script before the Node.js one.&lt;/p&gt;

&lt;p&gt;The ending each client needs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Client&lt;/th&gt;
&lt;th&gt;Add to the connection string&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;psql, Python (psycopg), Prisma, GUI tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?sslmode=require&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js (node-postgres, &lt;code&gt;pg&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?sslmode=require&amp;amp;uselibpqcompat=true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In node-postgres 8, &lt;code&gt;sslmode=require&lt;/code&gt; also checks the server's certificate against the certificate authorities Node.js trusts, and fails. &lt;code&gt;uselibpqcompat=true&lt;/code&gt; gives &lt;code&gt;require&lt;/code&gt; the meaning it has in every other PostgreSQL client: encrypt, without that check. Only node-postgres knows this setting; the others reject it.&lt;/p&gt;

&lt;p&gt;To connect a GUI tool such as &lt;a href="https://tableplus.com/" rel="noopener noreferrer"&gt;TablePlus&lt;/a&gt;, &lt;a href="https://dbeaver.io/" rel="noopener noreferrer"&gt;DBeaver&lt;/a&gt; or &lt;a href="https://www.pgadmin.org/" rel="noopener noreferrer"&gt;pgAdmin&lt;/a&gt;, copy the host, port, database name, user and password from the &lt;strong&gt;Credentials&lt;/strong&gt; tab into a new PostgreSQL connection, and set &lt;strong&gt;SSL mode&lt;/strong&gt; to &lt;strong&gt;require&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  pg_hba.conf rejects connection ... no encryption
&lt;/h3&gt;

&lt;p&gt;The client connected without encryption. Add &lt;code&gt;?sslmode=require&lt;/code&gt; to the end of the connection string.&lt;/p&gt;

&lt;h3&gt;
  
  
  unable to verify the first certificate
&lt;/h3&gt;

&lt;p&gt;node-postgres with &lt;code&gt;?sslmode=require&lt;/code&gt; only. Add &lt;code&gt;&amp;amp;uselibpqcompat=true&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  invalid URI query parameter: "uselibpqcompat"
&lt;/h3&gt;

&lt;p&gt;psql or psycopg got the Node.js ending. Remove &lt;code&gt;&amp;amp;uselibpqcompat=true&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  psql: command not found
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;psql&lt;/code&gt; is not on your &lt;code&gt;PATH&lt;/code&gt;. On macOS, run the &lt;code&gt;echo&lt;/code&gt; and &lt;code&gt;source&lt;/code&gt; lines from Step 1. On Windows, add the PostgreSQL &lt;code&gt;bin&lt;/code&gt; folder to &lt;code&gt;PATH&lt;/code&gt; and open a new window.&lt;/p&gt;

&lt;h3&gt;
  
  
  password authentication failed
&lt;/h3&gt;

&lt;p&gt;The password in the string is wrong or was changed. Copy the connection string again from the &lt;strong&gt;Credentials&lt;/strong&gt; tab.&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>tutorial</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Password Protect a Website for Free</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Tue, 27 Oct 2026 16:36:39 +0000</pubDate>
      <link>https://dev.to/lightcloud/password-protect-a-website-for-free-3hhp</link>
      <guid>https://dev.to/lightcloud/password-protect-a-website-for-free-3hhp</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz7ln7c323s9qs3wtbz0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz7ln7c323s9qs3wtbz0.webp" alt="Password Protect a Website for Free" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three platforms let you password protect a website for free. Light Cloud does it with one shared password, set in four clicks on every plan, Free included. Cloudflare Access is free for teams under 50 people and makes each visitor sign in with a code sent to their email, which is safer and takes about a dozen steps to set up. Render has no setting for it, but its blog shows how to encrypt a static page at build time with PageCrypt. Everywhere else the password sits behind a paid plan: $20 a month on Netlify, $21 per user on GitHub, $29 on Koyeb and $40 on Vercel for one developer and one project.&lt;/p&gt;

&lt;p&gt;We make Light Cloud, so it's our row at the top. Below is how the order was decided, and every row links to the vendor's own page so you can check it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The September price change that started this
&lt;/h2&gt;

&lt;p&gt;On 2026-09-09 Vercel moved Password Protection from a $150-a-month team add-on to &lt;a href="https://vercel.com/changelog/password-protection-now-costs-20-per-project-per-month-on-pro" rel="noopener noreferrer"&gt;$20 per protected project a month&lt;/a&gt; on Pro. For a team with one project, that's a price cut. An agency with ten client projects now pays $200 a month, more than the old add-on. The same day, Vercel let its account-based gate, Vercel Authentication, protect production deployments too, at no cost on every plan.&lt;/p&gt;

&lt;p&gt;Answers to "how do I lock a staging site for free" tend to mix three different things: a shared password, a login with a personal account, and code you write yourself. They're priced very differently, so this table keeps them apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;The scenario is the one I meet most: a commercial project has a staging site, and a client who has no account anywhere needs to open it, while search engines and strangers must not.&lt;/p&gt;

&lt;p&gt;Each platform is priced on the cheapest plan where its own protection works, for one developer and one site, using list prices checked on 2026-10-13. "Commercial" rules out plans that forbid it, such as Vercel's Hobby. Ties on price are broken by the number of steps, which I counted from each vendor's own instructions, starting at the settings page and leaving out sign-up.&lt;/p&gt;

&lt;p&gt;The table also says what the visitor has to type. A shared password is the least work for the client. Personal logins are better security, and more work for everyone. Neither is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Password on one site a month&lt;/th&gt;
&lt;th&gt;What the visitor enters&lt;/th&gt;
&lt;th&gt;Steps in the vendor's docs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;$0, every plan&lt;/td&gt;
&lt;td&gt;One shared password&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;td&gt;$0, Access Free under 50 users&lt;/td&gt;
&lt;td&gt;Emailed code or company login&lt;/td&gt;
&lt;td&gt;1 for preview links, about 12 for a hostname&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$0, with PageCrypt&lt;/td&gt;
&lt;td&gt;Shared password, decrypted in the browser&lt;/td&gt;
&lt;td&gt;3, plus inlining CSS, JavaScript and images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Netlify&lt;/td&gt;
&lt;td&gt;$20, Pro&lt;/td&gt;
&lt;td&gt;One shared password&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;GitHub Pages&lt;/td&gt;
&lt;td&gt;$21 per user, Enterprise Cloud&lt;/td&gt;
&lt;td&gt;GitHub sign-in with read access to the repo&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Koyeb&lt;/td&gt;
&lt;td&gt;$29, Pro&lt;/td&gt;
&lt;td&gt;Username and password (HTTP basic auth)&lt;/td&gt;
&lt;td&gt;1 CLI flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;$40: $20 Pro seat plus $20 per project&lt;/td&gt;
&lt;td&gt;One shared password&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5,000 committed-spend tier&lt;/td&gt;
&lt;td&gt;Railway account sign-in&lt;/td&gt;
&lt;td&gt;Not counted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Prices and steps from each vendor's docs and pricing pages, checked 2026-10-13, US dollars. Light Cloud steps from our own tutorial. Sign-up, plan upgrades and DNS changes not counted as steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a staging site that one shared password should cover.&lt;/p&gt;

&lt;p&gt;Password protection works on every plan, and &lt;a href="https://blog.light-cloud.com/tutorials/password-protect-a-staging-site" rel="noopener noreferrer"&gt;the tutorial&lt;/a&gt; runs on Free: open the environment's Security tab, click Set password, type it twice, click Save password. It applies from the next request, with no redeploy. The check happens at the edge before the request reaches your app, so images and JavaScript are covered too, and the password page answers with a 401 and &lt;code&gt;X-Robots-Tag: noindex, nofollow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A few details I like. The password belongs to one environment, so production stays public while the &lt;code&gt;staging&lt;/code&gt; branch is locked; &lt;a href="https://blog.light-cloud.com/tutorials/preview-url-for-every-branch" rel="noopener noreferrer"&gt;the branch preview tutorial&lt;/a&gt; shows how a branch gets that environment in the first place. A visitor stays signed in for 12 hours. After 8 wrong guesses from one address within 15 minutes, further attempts are refused for a while. Clicking Change signs everyone out, which is what you want when a review ends. That's the whole of how we &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;password protect a website for free&lt;/a&gt;: it comes with &lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;free hosting with no credit card&lt;/a&gt;, for static sites and containers alike.&lt;/p&gt;

&lt;p&gt;Now the limits. Everyone shares one password, so you can't remove one person without changing it for all. There's no single sign-on. On Free the site lives on a light-cloud.io address with a small "by Light Cloud" link; &lt;a href="https://light-cloud.com/domains" rel="noopener noreferrer"&gt;a custom domain with automatic SSL&lt;/a&gt; starts on Lite at $5 a month.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cloudflare
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams that want every visitor to sign in as themselves.&lt;/p&gt;

&lt;p&gt;Cloudflare doesn't do shared passwords. It does Cloudflare Access, which is $0 for teams under 50 users and $7 per user a month, paid annually, above that (&lt;a href="https://www.cloudflare.com/sase/products/access/" rel="noopener noreferrer"&gt;Access pricing&lt;/a&gt;). For preview links on Pages it's one setting, Settings &amp;gt; General &amp;gt; Enable access policy, which limits them to your Cloudflare account until you add people. That setting &lt;a href="https://developers.cloudflare.com/pages/configuration/preview-deployments/" rel="noopener noreferrer"&gt;doesn't cover the pages.dev domain or a custom domain&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;staging.example.com&lt;/code&gt; you create a self-hosted Access application, and the domain has to be active on Cloudflare. The &lt;a href="https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-public-app/" rel="noopener noreferrer"&gt;docs list nine actions&lt;/a&gt; before the optional settings. A client without a company login signs in with a &lt;a href="https://developers.cloudflare.com/cloudflare-one/identity/one-time-pin/" rel="noopener noreferrer"&gt;one-time PIN sent by email&lt;/a&gt;, which new organizations add as an identity provider in three more steps. So about a dozen, once. In return you can let in one email address and later remove exactly that one.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a small static site where a password in the page is good enough.&lt;/p&gt;

&lt;p&gt;Render has no password setting. Its blog suggests &lt;a href="https://render.com/blog/static-site-auth-pagecrypt" rel="noopener noreferrer"&gt;PageCrypt&lt;/a&gt;, an open source library that encrypts an HTML file at build time; the browser decrypts it when the visitor types the password. Setup is three steps: add the dependency, change the build command, and set the password as an environment variable. Render's static sites are free, so the cost is $0.&lt;/p&gt;

&lt;p&gt;Render is upfront about the catch. PageCrypt encrypts a single HTML file by default, so CSS, JavaScript and images have to be inlined into it to be protected, and there's only one shared password. It's a static-site trick; an API behind it needs its own authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Netlify
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; agencies that want a password on every project for one flat price.&lt;/p&gt;

&lt;p&gt;On the credit-based plans, the shared password comes with Pro, $20 a month with unlimited team members, and it's not available on Free or Personal (&lt;a href="https://docs.netlify.com/manage/security/secure-access-to-sites/password-protection/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;). Free and Personal can make a project private instead, but then only the Team Owner can see it, which doesn't help with a client.&lt;/p&gt;

&lt;p&gt;Five steps under Project configuration &amp;gt; Visitor access &amp;gt; Project visibility: Edit visibility, choose Password, type it, choose Production and previews or Previews only, Save. There's no team-wide default password, so each project gets its own. The flat price is the real draw: the password adds no per-project fee, so twenty client sites don't multiply it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. GitHub Pages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; internal docs for people who already work in the repository.&lt;/p&gt;

&lt;p&gt;A GitHub Pages site can be published privately only if the organization uses GitHub Enterprise Cloud, which starts at $21 per user a month (&lt;a href="https://github.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Then only people with read access to the repository can open it, and only project sites from private or internal organization repositories qualify (&lt;a href="https://docs.github.com/en/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site" rel="noopener noreferrer"&gt;docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The switch itself is three clicks: Settings, Pages, the visibility dropdown. It's a fine answer for an engineering handbook. For a client outside your GitHub organization, it isn't one.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Koyeb
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; an API or app that should answer only to a username and password.&lt;/p&gt;

&lt;p&gt;Koyeb's CLI can put HTTP basic auth on every route of a service with one flag, &lt;code&gt;--auth USERNAME:PASSWORD&lt;/code&gt;, or require an API key instead (&lt;a href="https://www.koyeb.com/docs/build-and-deploy/cli/reference" rel="noopener noreferrer"&gt;CLI reference&lt;/a&gt;). That's the shortest setup in this table if you live in a terminal, and it protects an API as well as a website.&lt;/p&gt;

&lt;p&gt;The price comes from the plan, not the feature. Since Koyeb &lt;a href="https://www.koyeb.com/blog/koyeb-is-joining-mistral-ai-to-build-the-future-of-ai-infrastructure" rel="noopener noreferrer"&gt;announced it is joining Mistral AI&lt;/a&gt;, new users must pick a paid plan, and Pro is $29 a month with $10 of compute included. The browser shows its own plain sign-in box, which looks dated to a client but works everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Vercel
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams already on Pro that need a password on one or two projects.&lt;/p&gt;

&lt;p&gt;Password Protection is &lt;a href="https://vercel.com/docs/deployment-protection/methods-to-protect-deployments/password-protection" rel="noopener noreferrer"&gt;$20 per protected project a month on Pro&lt;/a&gt; and isn't available on Hobby. Pro itself is $20 per deploying seat, so one developer with one protected project pays $40. The docs list six actions: pick the project, open Deployment Protection, flip the toggle, pick the environment, type the password, Save.&lt;/p&gt;

&lt;p&gt;The free alternative is Vercel Authentication, on every plan. Visitors log in with a Vercel account and request access, which you approve, and &lt;a href="https://vercel.com/docs/deployment-protection/methods-to-protect-deployments/vercel-authentication" rel="noopener noreferrer"&gt;Hobby allows one external user&lt;/a&gt;. For a team reviewing its own previews it's excellent; for a client it means asking them to create a Vercel account.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; large teams that want staging services behind Railway accounts.&lt;/p&gt;

&lt;p&gt;Railway's gate, &lt;a href="https://blog.railway.com/p/railway-authentication-identity-aware-proxy" rel="noopener noreferrer"&gt;announced on 2026-10-08&lt;/a&gt;, puts services such as staging previews and internal tools behind a Railway login. It requires the $5,000-a-month committed-spend tier. Below that tier, you'd put authentication into the app itself, which is a fine answer, just not a setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;On security, Cloudflare Access wins outright. Each visitor proves who they are, you can remove one person without touching anyone else, and you can plug in a company login. Our shared password can't do any of that, and if it leaks, the fix is to change it and send the new one around. Vercel Authentication and GitHub's private Pages do the same job for teams whose reviewers already have accounts there.&lt;/p&gt;

&lt;p&gt;For an agency with many client sites, Netlify's flat $20 covers a password on every project, and its team login can be tied to single sign-on through an identity provider. If you need production itself behind company sign-in, that's what these products are built for.&lt;/p&gt;

&lt;p&gt;Where we're ahead is the plain case: a client, a staging link, a password in a message. It's four clicks on any &lt;a href="https://light-cloud.com/previews" rel="noopener noreferrer"&gt;branch preview URL&lt;/a&gt;, on any plan, and the &lt;a href="https://light-cloud.com/deployments" rel="noopener noreferrer"&gt;git push deploys&lt;/a&gt; keep redeploying the protected branch without anyone touching the setting again. If you're choosing a host for the whole app, &lt;a href="https://blog.light-cloud.com/comparisons/where-to-host-a-saas" rel="noopener noreferrer"&gt;where to host a SaaS app&lt;/a&gt; prices the rest of it.&lt;/p&gt;

&lt;p&gt;How many people outside your team need to open your staging site this month?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>passwordprotection</category>
      <category>security</category>
    </item>
    <item>
      <title>Kubernetes Alternatives for Small Teams</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Sun, 25 Oct 2026 17:34:00 +0000</pubDate>
      <link>https://dev.to/lightcloud/kubernetes-alternatives-for-small-teams-2eig</link>
      <guid>https://dev.to/lightcloud/kubernetes-alternatives-for-small-teams-2eig</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9k0fhy5q8t6bigprkb8i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9k0fhy5q8t6bigprkb8i.webp" alt="Kubernetes Alternatives for Small Teams" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a small team that wants containers without Kubernetes, the options with the least to learn are Light Cloud, Railway and Render: you connect a repository and get HTTPS URLs, with no cluster, no registry and no config file to master. Fly.io and Coolify each add one new thing, Google Cloud Run and AWS ECS add cloud permissions and plumbing, and Kamal, Docker Swarm and Nomad hand you the servers. Light Cloud is first because, of the three, it is also the cheapest way to keep a few quiet services online.&lt;/p&gt;

&lt;p&gt;I run Light Cloud, so weigh that. The scoring below is simple enough to redo yourself from the vendors' own docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;Kubernetes is hard for a small team for a boring reason: the list of things you have to understand before anything runs. Nodes, a registry, ingress, certificates, YAML for each object. &lt;a href="https://blog.light-cloud.com/kubernetes/kubernetes-won-developers-lost" rel="noopener noreferrer"&gt;The longer argument&lt;/a&gt; ran on this blog earlier this month, so this post stays practical.&lt;/p&gt;

&lt;p&gt;Every option below got one point for each of these six things it makes you learn or run yourself before your first deploy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;machines you rent, patch and keep alive;&lt;/li&gt;
&lt;li&gt;a config file in the tool's own format;&lt;/li&gt;
&lt;li&gt;a container registry to set up and log in to;&lt;/li&gt;
&lt;li&gt;HTTPS and load balancing you configure;&lt;/li&gt;
&lt;li&gt;cloud permissions, such as IAM roles;&lt;/li&gt;
&lt;li&gt;extra tools that must run next to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing a Dockerfile doesn't count, since every option accepts one. Fewer points rank higher. Where two options tie, the one where someone else runs the machines goes first, and after that the lower bill for a reference system: three small services that are quiet most of the day. Facts come from the vendors' own docs and pricing pages, checked on 2026-10-13. Self-hosted tools get "your servers" in the price column, because I couldn't check a server price on a page I trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;th&gt;Who runs the machines&lt;/th&gt;
&lt;th&gt;What you write&lt;/th&gt;
&lt;th&gt;Three quiet services a month&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;Nothing; a Dockerfile is optional&lt;/td&gt;
&lt;td&gt;$0 on Free, $5 with your own domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;Nothing required&lt;/td&gt;
&lt;td&gt;$5 plus usage over $5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;Nothing; render.yaml optional&lt;/td&gt;
&lt;td&gt;$21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Fly.io&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Fly.io&lt;/td&gt;
&lt;td&gt;fly.toml, generated for you&lt;/td&gt;
&lt;td&gt;up to $6.57&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Coolify&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Nothing; it has a dashboard&lt;/td&gt;
&lt;td&gt;Your servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Google Cloud Run&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;IAM, plus a load balancer for your domain&lt;/td&gt;
&lt;td&gt;$0 inside the free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;AWS ECS Express Mode&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;AWS (Fargate)&lt;/td&gt;
&lt;td&gt;IAM roles, an image in a registry&lt;/td&gt;
&lt;td&gt;about $43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Kamal&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;config/deploy.yml&lt;/td&gt;
&lt;td&gt;Your servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Docker Swarm&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Service definitions, an outside load balancer&lt;/td&gt;
&lt;td&gt;Your servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Nomad&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Job files, plus Consul and Vault&lt;/td&gt;
&lt;td&gt;Your servers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scored from each vendor's own docs, checked 2026-10-13. Prices in US dollars from the vendors' pricing pages; "your servers" means the tool is free and you pay whoever hosts the machines. Kamal scores 4 once you run more than one server.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams that want push-to-URL with nothing to configure and services that cost nothing while idle.&lt;/p&gt;

&lt;p&gt;Zero points. You connect a GitHub repository and each push builds and deploys; with a Dockerfile at the root it builds exactly that, and without one it detects the framework and writes the Dockerfile for you, so you can &lt;a href="https://light-cloud.com/frameworks" rel="noopener noreferrer"&gt;deploy Node.js, Python, Go and Java without a Dockerfile&lt;/a&gt;. Certificates are issued and renewed automatically. There is no registry to log in to and no IAM. Those &lt;a href="https://light-cloud.com/deployments" rel="noopener noreferrer"&gt;git push deploys&lt;/a&gt; come with a preview URL per branch, and &lt;a href="https://light-cloud.com/observability" rel="noopener noreferrer"&gt;logs and metrics&lt;/a&gt; sit next to the deploy history.&lt;/p&gt;

&lt;p&gt;Three quiet services fit the Free plan. The pricing page puts a quiet server app at about $0.10 a month of usage, so three use $0.30 of Free's $1, with no card (&lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Your own domain and a database start on Lite at $5. That's &lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pay-per-use container hosting&lt;/a&gt; in practice: every container scales to zero by default and bills by the hour while it runs.&lt;/p&gt;

&lt;p&gt;Now the part a Kubernetes refugee should read twice. Services talk to each other over public HTTPS, not a private network; &lt;a href="https://blog.light-cloud.com/tutorials/microservices-on-light-cloud-part-2-connect-services" rel="noopener noreferrer"&gt;the microservices series&lt;/a&gt; shows the CORS and shared-secret setup that takes. There is no cron and no background worker type. An app scales to 3 instances on Free and Lite, 10 on Starter and 50 on Business, and a warm instance that never sleeps costs about $52 a month and needs Starter. A cold service takes &lt;a href="https://blog.light-cloud.com/tutorials/microservices-on-light-cloud-part-4-cold-starts" rel="noopener noreferrer"&gt;3.1 to 3.7 seconds to answer&lt;/a&gt;. And settings live in the console, not in a manifest in your repository (the CLI's small &lt;code&gt;.lightcloud&lt;/code&gt; file only records which app a folder belongs to). That's the point of it, but it also means no infrastructure diff to review in a pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; small systems that need private networking and cron between services from day one.&lt;/p&gt;

&lt;p&gt;Also zero points. Railway builds from your repository, and services in a project reach each other over a private WireGuard network with internal DNS, which is exactly what Light Cloud lacks (&lt;a href="https://docs.railway.com/networking/private-networking" rel="noopener noreferrer"&gt;docs&lt;/a&gt;). Cron jobs and pull request environments come on every paid plan.&lt;/p&gt;

&lt;p&gt;Hobby is $5 a month with $5 of usage included, billed by the RAM and CPU your services actually use (&lt;a href="https://docs.railway.com/pricing/plans" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). Three quiet services may stay inside that, but I can't promise it: Railway has no fixed sizes, so it depends on how much memory your processes hold. Sleep is opt-in, and Railway warns that the first request to a sleeping service may get a 502.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; fixed prices per service, and a whole system in one optional file.&lt;/p&gt;

&lt;p&gt;Zero points, because nothing beyond a repository is required. When you want it, a Blueprint describes services, databases and environment groups in &lt;a href="https://render.com/docs/infrastructure-as-code" rel="noopener noreferrer"&gt;a single render.yaml&lt;/a&gt;, which is the closest thing here to the manifests you'd keep in a Kubernetes repo. Private networking, background workers and cron jobs are all built in.&lt;/p&gt;

&lt;p&gt;It ranks third on the tiebreak. A paid service is a fixed instance, the smallest $7 a month (&lt;a href="https://render.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), so three services are $21 whether anyone calls them or not. The free instances spin down after 15 minutes and Render says not to use them in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Fly.io
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; the same containers in many regions, with a private network between them.&lt;/p&gt;

&lt;p&gt;One point: &lt;code&gt;fly launch&lt;/code&gt; writes a fly.toml for your app's Fly-specific settings (&lt;a href="https://fly.io/docs/launch/create/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;), and you'll edit it sooner or later. In exchange, every organization gets a private WireGuard network across regions, and machines can stop when idle so you pay only for their disk.&lt;/p&gt;

&lt;p&gt;The smallest always-on machine is $2.19 a month (&lt;a href="https://docs.fly.io/about/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), so three are at most $6.57, less if they stop. There is no free tier for new accounts, a card is required after the trial, and Fly says it doesn't support billing alerts yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Coolify
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a Heroku-style dashboard on servers you already pay for.&lt;/p&gt;

&lt;p&gt;One point, but it's the big one: you run the machines. Everything else is handled from a dashboard. Coolify builds with Nixpacks, a Dockerfile or Docker Compose, issues Let's Encrypt certificates, starts databases from a list and deploys pull requests separately (&lt;a href="https://coolify.io/" rel="noopener noreferrer"&gt;features&lt;/a&gt;). It also runs cron jobs inside your apps, which several managed rows can't.&lt;/p&gt;

&lt;p&gt;Self-hosted Coolify is free with every feature; Coolify Cloud, where they run the dashboard and you bring the servers, is $5 a month for two servers plus $3 per extra one (&lt;a href="https://coolify.io/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). The Coolify server needs 2 CPU cores, 2 GB of RAM and 10 GB of disk on its own (&lt;a href="https://coolify.io/docs/get-started/installation" rel="noopener noreferrer"&gt;installation&lt;/a&gt;). Patching, backups to your own S3 bucket, and what happens when the box dies are yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Google Cloud Run
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams already on Google Cloud that want scale to zero at raw cloud prices.&lt;/p&gt;

&lt;p&gt;Two points. &lt;code&gt;gcloud run deploy --source&lt;/code&gt; builds from a Dockerfile or buildpacks and creates the registry for you (&lt;a href="https://cloud.google.com/run/docs/deploying-source-code" rel="noopener noreferrer"&gt;docs&lt;/a&gt;), which is kind. But you set up a billing account and IAM, and your own domain needs a load balancer or Firebase Hosting, because Cloud Run's built-in domain mapping is a preview that Google calls &lt;a href="https://cloud.google.com/run/docs/mapping-custom-domains" rel="noopener noreferrer"&gt;not production-ready&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Three quiet services cost $0 inside the free tier of 180,000 vCPU-seconds and 2 million requests a month (&lt;a href="https://cloud.google.com/run/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Light Cloud runs on Cloud Run, so this is the same engine with the setup handed back to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. AWS ECS Express Mode
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; AWS shops that want Fargate with the load balancer and TLS done for them.&lt;/p&gt;

&lt;p&gt;Two points. AWS says an Express Mode service needs only three things: &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-overview.html" rel="noopener noreferrer"&gt;a container image, a task execution role and an infrastructure role&lt;/a&gt;. It then creates the Fargate service, a load balancer with TLS, auto scaling and monitoring. The image has to live in a registry first, and the roles are IAM.&lt;/p&gt;

&lt;p&gt;Express Mode is free; Fargate isn't. The smallest task, 0.25 vCPU with 0.5 GB, is about $8.89 a month around the clock in us-east-1 (&lt;a href="https://aws.amazon.com/fargate/pricing/" rel="noopener noreferrer"&gt;Fargate pricing&lt;/a&gt;), and a load balancer adds about $16.20 before usage charges. Three services sharing one load balancer come to about $43, before the load balancer's usage charges.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Kamal
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Linux-comfortable teams putting containers on cheap servers.&lt;/p&gt;

&lt;p&gt;Three points on one server, four on more. You run the servers, you write config/deploy.yml, and you need a registry, because &lt;code&gt;kamal setup&lt;/code&gt; builds the image, pushes it, and pulls it on each host (&lt;a href="https://kamal-deploy.org/docs/installation/" rel="noopener noreferrer"&gt;installation&lt;/a&gt;). On a single server kamal-proxy gets Let's Encrypt certificates for you; with more than one, you put a load balancer in front yourself.&lt;/p&gt;

&lt;p&gt;What you get back is a lot: zero-downtime deploys to any Ubuntu box with an SSH key, under the MIT license, from the team at 37signals that uses it for their own apps. Kamal's own homepage is candid that you're &lt;a href="https://kamal-deploy.org/" rel="noopener noreferrer"&gt;probably better off with a fully managed service&lt;/a&gt; if basic Linux or Docker is still difficult.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Docker Swarm
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a real multi-machine cluster for people who already know Docker Compose.&lt;/p&gt;

&lt;p&gt;Three points: machines, service definitions, and a load balancer for outside traffic. Swarm is &lt;a href="https://docs.docker.com/engine/swarm/" rel="noopener noreferrer"&gt;built into Docker Engine&lt;/a&gt;, so there is no extra orchestrator to install, and it gives you service discovery by DNS name, rolling updates and rollbacks. Docker's tutorial uses three Linux hosts with ports 2377, 7946 and 4789 open between them.&lt;/p&gt;

&lt;p&gt;It is the gentlest way to learn what a cluster is. It's also a cluster, with managers, workers and reconciliation, and Docker's own docs call it an advanced feature and suggest plain Compose if you don't plan to run Swarm in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Nomad
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; mixed fleets that schedule containers, Java apps and VMs side by side.&lt;/p&gt;

&lt;p&gt;Three points: machines, job files, and the tools Nomad expects next to it. HashiCorp describes Nomad as a single binary that focuses on scheduling and &lt;a href="https://developer.hashicorp.com/nomad/docs/what-is-nomad" rel="noopener noreferrer"&gt;composes with Consul for service discovery and Vault for secrets&lt;/a&gt;. It schedules more than containers, which no other row here does.&lt;/p&gt;

&lt;p&gt;The license matters for some teams: Nomad Community Edition is under the Business Source License, per &lt;a href="https://developer.hashicorp.com/nomad/docs/ce-license-support" rel="noopener noreferrer"&gt;HashiCorp's own page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;Plenty of places, and they're the reasons people pick Kubernetes in the first place. If your services must talk privately, Railway, Render and Fly give you a private network today and we don't. Cron jobs are built into Railway, Render and Coolify, and Render sells background workers as a service type. Once your services are busy around the clock, a server running Kamal or Coolify is far cheaper than our always-on price, and Render's fixed $7 beats our $52. Teams that want the whole system in a reviewed file will prefer Render's Blueprint or a Kamal config to our console. And Nomad runs workloads that aren't containers at all.&lt;/p&gt;

&lt;p&gt;What we do better is the first step and the quiet months. There is nothing to install, no file to learn and no registry, and a service nobody calls costs nothing. For three small services that's $0 on Free, and the &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;Kubernetes alternative for small teams&lt;/a&gt; I'd pick for a first product is the one where you can &lt;a href="https://blog.light-cloud.com/tutorials/deploy-any-app-with-a-dockerfile" rel="noopener noreferrer"&gt;bring your own Dockerfile&lt;/a&gt; and be live before lunch.&lt;/p&gt;

&lt;p&gt;Which of the six points would you happily take on, and which made you leave Kubernetes in the first place?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>kubernetes</category>
      <category>docker</category>
    </item>
    <item>
      <title>Heroku Alternatives in 2026</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Fri, 23 Oct 2026 15:25:00 +0000</pubDate>
      <link>https://dev.to/lightcloud/heroku-alternatives-in-2026-2f55</link>
      <guid>https://dev.to/lightcloud/heroku-alternatives-in-2026-2f55</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcynzkar6ijmdqwwxmzyy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcynzkar6ijmdqwwxmzyy.webp" alt="Heroku Alternatives in 2026" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your team opens a review app for every pull request, the cheapest &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;Heroku alternative&lt;/a&gt; for a small app is Light Cloud at $5 a month, review apps included, against $16.80 for the same app and four review apps on Heroku. Railway starts at the same $5 and copies the database into each pull request environment, which we don't. If you rely on worker dynos and Heroku Scheduler, look at Render first: it feels the most like Heroku and lands at $16.10.&lt;/p&gt;

&lt;p&gt;We make Light Cloud, the first row below. The method comes before the table so you can check every number on the vendors' own pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why move off Heroku now
&lt;/h2&gt;

&lt;p&gt;Nothing broke. On 2026-02-06 Heroku said it is &lt;a href="https://www.heroku.com/blog/an-update-on-heroku/" rel="noopener noreferrer"&gt;transitioning to a sustaining engineering model&lt;/a&gt; "focused on stability, security, reliability, and support", and that Enterprise contracts will no longer be offered to new customers. Apps keep running, and prices for card-paying customers did not change. What changed is the direction: the platform you deploy to has stopped adding things.&lt;/p&gt;

&lt;p&gt;The money side is older news. Free dynos and free Postgres &lt;a href="https://devcenter.heroku.com/changelog-items/2502" rel="noopener noreferrer"&gt;ended on 2022-11-28&lt;/a&gt;, and you need a verified card before you can create an app. Any dyno scaled above zero bills &lt;a href="https://devcenter.heroku.com/articles/usage-and-billing" rel="noopener noreferrer"&gt;whether or not it gets traffic&lt;/a&gt;; only Eco dynos sleep, and Eco is for personal apps, not team apps. For teams that live on review apps, that means paying for a dyno and a database per pull request while the reviewer is at lunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;The reference app is the one from &lt;a href="https://blog.light-cloud.com/comparisons/where-to-host-a-saas" rel="noopener noreferrer"&gt;where to host a SaaS app&lt;/a&gt;: a React frontend, one Node.js API, a small PostgreSQL database and a custom domain, at about 1,000 API requests a day. On top of it I added the Heroku habit this post is about: four pull requests a month, each with a preview of the frontend and API that stays open for three days.&lt;/p&gt;

&lt;p&gt;On Heroku that costs $12 for the app on a Basic dyno with Essential-0 Postgres (&lt;a href="https://www.heroku.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), plus four review apps. Review apps are &lt;a href="https://devcenter.heroku.com/articles/github-integration-review-apps" rel="noopener noreferrer"&gt;billed like normal apps&lt;/a&gt;, so a Basic dyno and Essential-0 for three days is about $1.20 each. Total: $16.80.&lt;/p&gt;

&lt;p&gt;For every other platform I priced the cheapest way to get a preview of the frontend and API per pull request, with list prices from the vendor's own pages, checked on 2026-10-13, in US dollars. Whether that preview also gets its own database is in the table, because Heroku review apps can carry one and not every alternative copies it. The second column covers the other two Heroku habits: worker dynos and the Scheduler add-on.&lt;/p&gt;

&lt;p&gt;Kept running all month, with no scale to zero, the same app gets the Always on prices in the table. Light Cloud comes last there at about $56, because an always-on instance needs the $19 Starter plan and a Micro costs about $52 a month. Every other platform here already runs the API around the clock at the price above, so their bills don't move.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;App + review apps a month&lt;/th&gt;
&lt;th&gt;Always on, a month&lt;/th&gt;
&lt;th&gt;Review apps&lt;/th&gt;
&lt;th&gt;Scheduler and workers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;$5&lt;/td&gt;
&lt;td&gt;about $56 (Starter, always-on Micro)&lt;/td&gt;
&lt;td&gt;Every branch, shares the production database&lt;/td&gt;
&lt;td&gt;Neither yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5 plus usage over $5&lt;/td&gt;
&lt;td&gt;$5 plus usage over $5&lt;/td&gt;
&lt;td&gt;Every pull request, own database&lt;/td&gt;
&lt;td&gt;Cron jobs built in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;DigitalOcean App Platform&lt;/td&gt;
&lt;td&gt;$12 plus preview apps&lt;/td&gt;
&lt;td&gt;$12 plus preview apps&lt;/td&gt;
&lt;td&gt;Through GitHub Actions&lt;/td&gt;
&lt;td&gt;Scheduled jobs and workers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$16.10, or $43.50 with full-stack previews&lt;/td&gt;
&lt;td&gt;$16.10&lt;/td&gt;
&lt;td&gt;Per service on the free workspace; full stack on Pro&lt;/td&gt;
&lt;td&gt;Cron jobs and workers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Koyeb&lt;/td&gt;
&lt;td&gt;$29 plus usage over $10&lt;/td&gt;
&lt;td&gt;$29 plus usage over $10&lt;/td&gt;
&lt;td&gt;Through GitHub Actions&lt;/td&gt;
&lt;td&gt;Workers; no scheduler documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Fly.io&lt;/td&gt;
&lt;td&gt;about $41&lt;/td&gt;
&lt;td&gt;about $41&lt;/td&gt;
&lt;td&gt;GitHub Action, one app, no database&lt;/td&gt;
&lt;td&gt;Workers; cron is an app you run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;List prices from each vendor's pricing and docs pages, checked 2026-10-13. Four pull requests a month, each previewed for three days. For comparison, the same app with four review apps is $16.80 on Heroku. Taxes and bandwidth beyond included allowances excluded.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams that open a review app for every pull request and are tired of paying for idle dynos.&lt;/p&gt;

&lt;p&gt;Lite is $5 a month with $5 of usage included, a custom domain and one shared PostgreSQL database (&lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). The reference app uses about $4.33 of that: $4 for the database, around 20 cents for the API, a few cents of builds. Four previews add about eight cents, because a preview only costs its two builds and then sits at $0 until somebody opens it. That's the trade in &lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pay-per-use hosting from $5 a month&lt;/a&gt;: no dyno waits for a reviewer.&lt;/p&gt;

&lt;p&gt;You get &lt;a href="https://light-cloud.com/previews" rel="noopener noreferrer"&gt;a review app for every branch&lt;/a&gt;, frontend and API, on every plan including Free, and a pull request comment with the link. Deploys come from GitHub, so &lt;code&gt;git push heroku main&lt;/code&gt; becomes a plain push to your repository and &lt;a href="https://light-cloud.com/deployments" rel="noopener noreferrer"&gt;deploys on every git push&lt;/a&gt; take it from there. The database is &lt;a href="https://light-cloud.com/databases" rel="noopener noreferrer"&gt;managed Postgres in the same console&lt;/a&gt;; moving yours over is a plain-SQL &lt;code&gt;pg_dump&lt;/code&gt; (the import doesn't take the custom format) and an upload of up to 512 MB.&lt;/p&gt;

&lt;p&gt;The gaps a Heroku team will hit first: there is no worker app type and no scheduler, so a &lt;code&gt;worker:&lt;/code&gt; line in your Procfile has nowhere to go. A branch preview uses the production database until you point it at another one, which is not what a Heroku review app with its own Postgres does; &lt;a href="https://blog.light-cloud.com/tutorials/preview-url-for-every-branch" rel="noopener noreferrer"&gt;the preview tutorial&lt;/a&gt; shows the setup. Shared databases run in Belgium only. Containers scale to zero, so a quiet API answers its first request in &lt;a href="https://blog.light-cloud.com/tutorials/microservices-on-light-cloud-part-4-cold-starts" rel="noopener noreferrer"&gt;3.1 to 3.7 seconds&lt;/a&gt;, and an always-on instance needs Starter and costs about $52 a month.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; review apps that copy the whole app, database included.&lt;/p&gt;

&lt;p&gt;Hobby is $5 a month with $5 of usage included (&lt;a href="https://docs.railway.com/pricing/plans" rel="noopener noreferrer"&gt;plans&lt;/a&gt;), and usage is metered by the resource: $10 per GB of RAM a month and $20 per vCPU a month. Pull request environments &lt;a href="https://docs.railway.com/pricing/faqs" rel="noopener noreferrer"&gt;mirror the production workloads&lt;/a&gt;, Postgres included, and are billed as normal usage while they exist. If the app and its previews stay under about half a GB of RAM on average, the bill stays at $5; busier review apps push it over.&lt;/p&gt;

&lt;p&gt;Railway also has cron jobs (at least 5 minutes apart) and private networking on every plan, and a hard usage limit you can set from $10 (&lt;a href="https://docs.railway.com/pricing/cost-control" rel="noopener noreferrer"&gt;cost control&lt;/a&gt;). It recommends Pro, $20 a month, for commercial apps. Of everything here, it's the closest to Heroku's review apps at our price.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. DigitalOcean App Platform
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; fixed container prices with workers and scheduled jobs.&lt;/p&gt;

&lt;p&gt;A 512 MiB container is $5 a month and a development database $7 (&lt;a href="https://www.digitalocean.com/pricing/app-platform" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), so the app is $12 with the frontend on the free static tier. Worker components are priced like services, and scheduled jobs are &lt;a href="https://docs.digitalocean.com/products/app-platform/how-to/manage-jobs/" rel="noopener noreferrer"&gt;billed only while they run&lt;/a&gt;, which covers both Heroku habits.&lt;/p&gt;

&lt;p&gt;There is no review app switch. DigitalOcean documents &lt;a href="https://docs.digitalocean.com/products/app-platform/how-to/deploy-from-github-actions/" rel="noopener noreferrer"&gt;a GitHub Actions workflow&lt;/a&gt; that deploys a separate app per pull request and deletes it on merge; each one is an ordinary app billed by the second. The development database has no backups by default, so a real product moves to managed Postgres from $15, and a payment method is needed before you create anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; the closest feel to Heroku, workers and cron included.&lt;/p&gt;

&lt;p&gt;A Starter web service is $7 a month and the smallest Postgres $6 plus $0.30 per GB (&lt;a href="https://render.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;): $13.30, with the frontend as a free static site. On the free Hobby workspace each service gets its own &lt;a href="https://render.com/docs/service-previews" rel="noopener noreferrer"&gt;pull request previews&lt;/a&gt;, billed at the service's rate, so four API previews for three days add $2.80. That's $16.10, about Heroku's bill, but those previews come without a database of their own. &lt;a href="https://render.com/docs/preview-environments" rel="noopener noreferrer"&gt;Full-stack preview environments&lt;/a&gt; that copy the database need the $25 Pro workspace, which makes it $43.50.&lt;/p&gt;

&lt;p&gt;Render is where a Heroku app maps over with the least rethinking: web services, background workers, cron jobs (minimum $1 a month each), a private network and fixed monthly prices. What its docs don't describe is scaling a paid service to zero while it's idle, or a visitor password for a staging site.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Koyeb
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; worker services on a private network, on one paid plan.&lt;/p&gt;

&lt;p&gt;New users have needed a paid plan and a card since Koyeb &lt;a href="https://www.koyeb.com/blog/koyeb-is-joining-mistral-ai-to-build-the-future-of-ai-infrastructure" rel="noopener noreferrer"&gt;announced it is joining Mistral AI&lt;/a&gt; on 2026-02-17. Pro is $29 a month with $10 of compute included (&lt;a href="https://www.koyeb.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), so the reference app is $29 plus whatever passes $10. Workers are a service type, services talk over a private mesh, and scale to zero is in public preview with a 1 to 5 second cold start.&lt;/p&gt;

&lt;p&gt;Previews per pull request come from a &lt;a href="https://www.koyeb.com/tutorials/deploy-preview-environments-on-koyeb-for-github-pull-requests" rel="noopener noreferrer"&gt;2023 GitHub Actions tutorial&lt;/a&gt;, not a setting. I found no scheduled-job feature in the docs, and Koyeb says spending limits are still in the works.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Fly.io
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; apps that should run close to users in several regions.&lt;/p&gt;

&lt;p&gt;Machines are cheap, from $2.19 a month always on (&lt;a href="https://docs.fly.io/about/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), and can stop when idle. Postgres is the expensive part: Managed Postgres starts at $38 plus $0.28 per GB (&lt;a href="https://docs.fly.io/postgres" rel="noopener noreferrer"&gt;docs&lt;/a&gt;). With four preview machines for three days each, about $41.&lt;/p&gt;

&lt;p&gt;Fly's review apps come from a GitHub Action that deploys &lt;a href="https://docs.fly.io/blueprints/review-apps-guide" rel="noopener noreferrer"&gt;one app without other resources&lt;/a&gt;, so a database per pull request is your own workflow to write. Workers are just Machines; scheduled jobs run through Cron Manager, which you &lt;a href="https://docs.fly.io/blueprints/task-scheduling" rel="noopener noreferrer"&gt;deploy as its own Fly app&lt;/a&gt;. No free tier for new accounts, and no billing alerts yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;Worker dynos and Heroku Scheduler are the big ones. If your Procfile has a &lt;code&gt;worker:&lt;/code&gt; line or your app depends on a nightly job, Render, Railway and DigitalOcean run those today and we can't. A review app with its own copy of Postgres is a Railway feature at our price, and a Render one on Pro. If your users are on several continents, Fly is the better home. And if your company buys software through procurement, Upsun is worth a call: &lt;a href="https://upsun.com/pricing/" rel="noopener noreferrer"&gt;its pricing page&lt;/a&gt; lists full-stack preview environments for every branch, a per-project fee and per-user licenses. I left it out of the table because I couldn't find its smallest app size next to the prices, so I can't price the reference app there.&lt;/p&gt;

&lt;p&gt;Where we come out ahead is the bill for waiting. On Heroku a review app is a dyno and a database that run for as long as the pull request is open, and most of that time nobody is looking. Here the preview of every branch costs its build and then nothing, the API scales to zero when traffic stops, and a five-dollar plan covers the app, the database and the domain. If your Heroku invoice is mostly review apps, that's the comparison to run.&lt;/p&gt;

&lt;p&gt;What's the first thing in your Procfile you'd have to change?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>heroku</category>
      <category>hosting</category>
    </item>
    <item>
      <title>Free Hosting for Startups</title>
      <dc:creator>Julia</dc:creator>
      <pubDate>Wed, 21 Oct 2026 16:11:11 +0000</pubDate>
      <link>https://dev.to/lightcloud/free-hosting-for-startups-55gc</link>
      <guid>https://dev.to/lightcloud/free-hosting-for-startups-55gc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5lup6qpfc3hz6ge8qxzq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5lup6qpfc3hz6ge8qxzq.webp" alt="Free Hosting for Startups" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloudflare stays free the longest for a startup whose app fits in Workers and static assets: custom domains, previews and extra people cost nothing, and the first bill is usually a $5 Postgres database. Light Cloud's first bill is also $5, and that $5 covers your own domain, the database and an API in any language, all in. Railway's step is $5 plus usage, Netlify's $9, and Vercel's is $20 per founder the day you take a payment.&lt;/p&gt;

&lt;p&gt;We make Light Cloud, the second row below. It isn't first here, and the method explains why.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we ranked
&lt;/h2&gt;

&lt;p&gt;Every free plan ends the same way: the startup needs something the plan doesn't include. So this ranking asks two questions per platform. What forces the first bill, and how big is it?&lt;/p&gt;

&lt;p&gt;The reference startup is small and ordinary: a frontend, one API, a PostgreSQL database and its own domain, with one founder deploying and about 1,000 API requests a day. Each price is the first monthly bill once the free plan no longer covers that stack, from each vendor's own pricing and docs pages, checked on 2026-10-13, in US dollars. Ties go to the platform whose free plan lasts longer before the bill arrives.&lt;/p&gt;

&lt;p&gt;A third column covers the moment a co-founder starts deploying, because that is the second bill most startups meet. Commercial use matters too: one platform's free plan bans it outright, and it changes the answer for that row.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ranking
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;First bill a month&lt;/th&gt;
&lt;th&gt;What forces the first bill&lt;/th&gt;
&lt;th&gt;Second founder&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;td&gt;$5, Postgres from PlanetScale&lt;/td&gt;
&lt;td&gt;Postgres, or 100,000 requests a day&lt;/td&gt;
&lt;td&gt;Free, no seat fee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Light Cloud&lt;/td&gt;
&lt;td&gt;$5, all in&lt;/td&gt;
&lt;td&gt;Your own domain or a database&lt;/td&gt;
&lt;td&gt;Starter, $19 a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5 plus usage over $5&lt;/td&gt;
&lt;td&gt;Your own domain, or a second project&lt;/td&gt;
&lt;td&gt;Pro, $20 a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Google Cloud Run&lt;/td&gt;
&lt;td&gt;about $8, Cloud SQL&lt;/td&gt;
&lt;td&gt;A database; card from day one&lt;/td&gt;
&lt;td&gt;IAM, no seat fee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Netlify&lt;/td&gt;
&lt;td&gt;$9, Personal plan&lt;/td&gt;
&lt;td&gt;300 credits, about 20 production deploys&lt;/td&gt;
&lt;td&gt;Pro, $20 a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;DigitalOcean App Platform&lt;/td&gt;
&lt;td&gt;$12&lt;/td&gt;
&lt;td&gt;Any backend; card for anything&lt;/td&gt;
&lt;td&gt;No seat fee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$13.30&lt;/td&gt;
&lt;td&gt;Free Postgres expires after 30 days&lt;/td&gt;
&lt;td&gt;Pro, $25 a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;$20 per deploying seat&lt;/td&gt;
&lt;td&gt;Commercial use, such as taking payments&lt;/td&gt;
&lt;td&gt;$20 per deploying seat&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;List prices from each vendor's pricing and docs pages, checked 2026-10-13. Reference startup: frontend, one API, PostgreSQL, its own domain, one founder deploying, about 1,000 API requests a day. Taxes and usage beyond included allowances excluded.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cloudflare
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; startups whose app fits in Workers and static assets.&lt;/p&gt;

&lt;p&gt;Cloudflare's free plan is the most generous here if your code runs as a Worker. Workers Free allows 100,000 requests a day, static asset requests are &lt;a href="https://developers.cloudflare.com/workers/platform/pricing/" rel="noopener noreferrer"&gt;free and unlimited&lt;/a&gt;, and a Pages project gets 100 custom domains and unlimited preview deployments on the free plan (&lt;a href="https://developers.cloudflare.com/pages/platform/limits/" rel="noopener noreferrer"&gt;limits&lt;/a&gt;). Cloudflare also says a Pages site can be managed by an unlimited number of users, so the co-founder costs nothing.&lt;/p&gt;

&lt;p&gt;The first bill usually comes from the database. Cloudflare's own D1 is SQLite, not Postgres; since 2026-06-18 you can create a &lt;a href="https://developers.cloudflare.com/changelog/post/2026-06-18-planetscale-databases-cloudflare-billing/" rel="noopener noreferrer"&gt;PlanetScale Postgres database billed on your Cloudflare invoice&lt;/a&gt;, and PlanetScale's single node &lt;a href="https://planetscale.com/pricing" rel="noopener noreferrer"&gt;starts at $5 a month&lt;/a&gt;. If D1 is enough for you, the bill stays at $0 for a long time.&lt;/p&gt;

&lt;p&gt;The limits are real, though. A Worker gets 10 ms of CPU per request on the free plan, and past 100,000 requests a day requests fail with Error 1027 until midnight UTC (&lt;a href="https://developers.cloudflare.com/workers/platform/limits/" rel="noopener noreferrer"&gt;limits&lt;/a&gt;). Running a container needs Workers Paid, a $5 minimum. And Cloudflare's budget alerts only notify; they never cap spend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Light Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; the smallest first bill that covers a container API in any language, Postgres and your domain.&lt;/p&gt;

&lt;p&gt;Free costs $0 with no card: unlimited static sites, 3 server apps and a preview URL for every branch, with $1 of usage a month (&lt;a href="https://light-cloud.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). It never bills you. When the $1 runs out, server apps pause until next month and static sites keep serving. The catch for a startup is plain: Free has no custom domain and no databases, and free pages carry a small "by Light Cloud" link.&lt;/p&gt;

&lt;p&gt;So the first bill comes early, the day you point your own domain at the app or create a database, and it is Lite at $5 a month. That $5 includes $5 of usage, a &lt;a href="https://light-cloud.com/domains" rel="noopener noreferrer"&gt;custom domain with automatic SSL&lt;/a&gt; and one shared PostgreSQL database. The reference startup uses about $4.25 of it: $4 for the database, about 20 cents for the API and a few cents of builds. Your API can be Node, Python, Go, Java or .NET, from &lt;a href="https://light-cloud.com/deployments" rel="noopener noreferrer"&gt;git push deploys&lt;/a&gt; or a Dockerfile.&lt;/p&gt;

&lt;p&gt;Where it falls behind in this ranking: the second bill. Lite has one team member, so a co-founder who deploys means Starter at $19 a month. There are no cron jobs, workers or private networking, the shared database runs in Belgium only, and a scaled-to-zero API takes &lt;a href="https://blog.light-cloud.com/tutorials/microservices-on-light-cloud-part-4-cold-starts" rel="noopener noreferrer"&gt;3.1 to 3.7 seconds&lt;/a&gt; to answer its first request after a quiet spell.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Railway
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; a $5 first step with cron jobs and private networking built in.&lt;/p&gt;

&lt;p&gt;After a 30-day trial with $5 of credit, Railway's Free plan gives $1 of credit a month, one project, three services and no custom domains (&lt;a href="https://docs.railway.com/pricing/free-trial" rel="noopener noreferrer"&gt;free trial docs&lt;/a&gt;). No card is needed. The first bill comes with your own domain or a second project: Hobby at $5 a month, with $5 of usage included (&lt;a href="https://docs.railway.com/pricing/plans" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). Postgres is billed as usage like any other service.&lt;/p&gt;

&lt;p&gt;Railway has extras we don't: cron jobs, private networking and pull request environments on every plan. Against it: Hobby is a single-developer workspace, and Railway &lt;a href="https://docs.railway.com/pricing/faqs" rel="noopener noreferrer"&gt;recommends Pro, $20 a month, for commercial applications&lt;/a&gt;, which a startup with paying customers is.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Google Cloud Run
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; teams already in Google Cloud.&lt;/p&gt;

&lt;p&gt;The compute is free for a long time. Cloud Run's free tier covers 180,000 vCPU-seconds and 2 million requests a month (&lt;a href="https://cloud.google.com/run/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;), far more than the reference API needs. But you need a billing account with a card to use it, and anything over the free tier is billed, not paused.&lt;/p&gt;

&lt;p&gt;The database is the first bill: Cloud SQL's smallest shared-core instance is $0.0105 an hour, about $8 a month before storage (&lt;a href="https://cloud.google.com/sql/pricing" rel="noopener noreferrer"&gt;Cloud SQL pricing&lt;/a&gt;). Your own domain takes setup, because Cloud Run's &lt;a href="https://cloud.google.com/run/docs/mapping-custom-domains" rel="noopener noreferrer"&gt;domain mapping is in preview&lt;/a&gt; and Google calls it not production-ready. Since 2026-10-12, a spend cap can pause Cloud Run at a budget. People are managed through IAM, with no seat fee.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Netlify
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; frontend-heavy startups.&lt;/p&gt;

&lt;p&gt;Netlify's free plan covers a lot of the reference startup: custom domains with SSL, functions, unlimited deploy previews and Netlify Database, a managed Postgres (&lt;a href="https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/credit-based-pricing-plans/" rel="noopener noreferrer"&gt;plans&lt;/a&gt;). It is never billed. But it runs on 300 credits a month, and each production deploy costs 15 of them, so about 20 deploys use the lot. When credits run out, every project on the team pauses until next month.&lt;/p&gt;

&lt;p&gt;The first bill is Personal at $9 for 1,000 credits. A co-founder can't join Free or Personal at all; Netlify's pricing page says those plans &lt;a href="https://www.netlify.com/pricing/" rel="noopener noreferrer"&gt;cannot add team member seats&lt;/a&gt;, so the second step is Pro at $20 a month with unlimited members. Password protection is a Pro feature too.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. DigitalOcean App Platform
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; fixed monthly prices from the first bill.&lt;/p&gt;

&lt;p&gt;The free tier is three static sites (&lt;a href="https://www.digitalocean.com/pricing/app-platform" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;). Any backend is paid, and you need a payment method to create anything at all, even a free static site. The reference startup is a $5 container (512 MiB) plus a $7 development database: $12. There is no seat fee as the team grows.&lt;/p&gt;

&lt;p&gt;The development database has no backups by default and is deleted with the app, so a real product moves to managed Postgres at about $15 soon after.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Render
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; predictable per-service prices.&lt;/p&gt;

&lt;p&gt;Render's free tier needs no card and includes free web services and a free Postgres database (&lt;a href="https://render.com/docs/free" rel="noopener noreferrer"&gt;free tier docs&lt;/a&gt;). Two things force the first bill. Free web services spin down after 15 minutes without traffic and take about a minute to wake, and the free database expires 30 days after it is created. A Starter web service is $7 and the smallest Postgres $6 plus $0.30 per GB: $13.30.&lt;/p&gt;

&lt;p&gt;The free workspace has one team member. A co-founder means the Pro workspace, $25 a month flat with unlimited seats, plus compute.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Vercel
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Next.js startups that will pay per founder from the first payment.&lt;/p&gt;

&lt;p&gt;Vercel's free Hobby plan is generous and includes custom domains, but its &lt;a href="https://vercel.com/docs/limits/fair-use-guidelines" rel="noopener noreferrer"&gt;fair use guidelines&lt;/a&gt; restrict it to non-commercial personal use, and count a paid developer or taking payments as commercial. For a startup that is the trigger, whatever the traffic. Pro is $20 a month per deploying seat with $20 of usage included (&lt;a href="https://vercel.com/docs/plans/pro-plan" rel="noopener noreferrer"&gt;Pro plan&lt;/a&gt;), and Postgres comes from a Marketplace partner, billed by them. Two founders deploying is $40.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the others beat us
&lt;/h2&gt;

&lt;p&gt;Cloudflare beats us outright on staying free: your own domain, previews and a co-founder all cost nothing there, while our Free plan has no custom domain at all. If your app is JavaScript and fits in a Worker, start there. Netlify's free plan includes a custom domain and a database, which ours doesn't. Railway's $5 buys cron jobs and private networking we don't have. And DigitalOcean, Cloud Run and Cloudflare never charge for a second person, while our Lite plan stops at one.&lt;/p&gt;

&lt;p&gt;Where we come out ahead is the shape of the first step. It is $5, it covers a container in whatever language the API is written in, a database and your domain on one invoice, and nothing on the free plan can ever bill you. If that's your startup's stack, our &lt;a href="https://light-cloud.com" rel="noopener noreferrer"&gt;free hosting for startups&lt;/a&gt; turns into a $5 bill the day you need more, with &lt;a href="https://light-cloud.com/databases" rel="noopener noreferrer"&gt;a Postgres database ready in seconds&lt;/a&gt; included. A password on staging stays free on every plan; &lt;a href="https://blog.light-cloud.com/tutorials/password-protect-a-staging-site" rel="noopener noreferrer"&gt;the staging tutorial&lt;/a&gt; takes five minutes. For the full monthly picture after launch, see &lt;a href="https://blog.light-cloud.com/comparisons/where-to-host-a-saas" rel="noopener noreferrer"&gt;where to host a SaaS app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which limit hit your startup first: the domain, the database or the second person?&lt;/p&gt;

</description>
      <category>lightcloud</category>
      <category>cloudplatform</category>
      <category>startup</category>
      <category>hosting</category>
    </item>
  </channel>
</rss>
