This commit is contained in:
Paul Copplestone committed 2021-04-02 23:11:10 +08:00
1 parent efe66808e0
commit f410affb0a
14 files changed
+443 -1

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
---
title: Supabase Dot Com
description: The Supabase Domain name is changing.
author: paul_copplestone
author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://github.com/kiwicopple.png
authorURL: https://github.com/kiwicopple
image: supabase-dot-com-og.jpg
thumb: supabase-dot-com-og.jpg
tags:
- supabase
date: '2021-04-02'
---
*tl;dr* During the next week, we'll be migrating from "supabase.io" to "supabase.com".
There are no changes required on your end. Your API URLs will remain on "supabase.co", and only our website URLs will change.
The rest of this post talks a bit about the origin of the name, but there's nothing important to know.
## SupaWhat?
At the end of 2019 we released a Postgres [Realtime](https://github.com/supabase/realtime) engine on GitHub.
We created this in my previous company after migrating from Firebase to Postgres.
It started gaining traction (if you count "GitHub stars" as traction) and so I tapped my friend, [Ant](https://twitter.com/AntWilson),
on the shoulder to see if he wanted to build an open source company with me (he was building another start up at the time).
The company we envisaged had Postgres at the core. We searched for every "dot com" we could think of with "base" in the name - hyperbase,
superbase, suprabase, uberbase. It turns out this is what every database start does. We couldn't find any good "dot coms".
And so we moved on to "dot io" domains.
Anybody who knows Ant, knows that he [loves memes](https://supabase.io/blog/2021/03/25/launch-week). While we were brainstorming
we found that "supabase.io" was available.
To be honest, this name wasn't a strong contender, but it served a very important purpose - it was extremely "meme-able" because
it sounds similar to Nikki Minaj's [Super Bass](https://youtu.be/4JipHEz53sU).
We chose it as a placeholder and found it was, indeed, very funny to send each other Nikki memes while we brainstormed the business.
![Booom booom booom booom](/new/images/blog/nikki-supabase.jpg)
Note to anyone starting a business, don't use a placeholder. You'll never change it.
Luckily for us, the name [grew on us](https://news.ycombinator.com/item?id=23325430) and now we love it.
## Supabase Dot Com
When we joined Y Combinator, they gave this advice:
> Except in unusual circumstances (like [Twitch.tv](http://twitch.tv/)), if you don't have the .com version of your name,
you should probably change it.
We decided to try purchasing [supabase.com](http://supabase.com) from the current owner. The YC forums were full of founders
recommending a particular Domain Specialist who would help us negotiate and purchase the domain. The only catch - he would take
a percentage of the purchase price.
This struck us as odd. The incentives were more aligned to the domain seller than the purchaser.
We're not afraid to roll up our sleeves at Supabase, so we decided we could handle it ourselves.
We were in for a huge surprise. After searching on the (old) [supabase.com](http://supabase.com) website, we found a company address.
And it was literally 100m from my home.
Of all the places in the world that the domain could be registered, the owner was within yelling-distance. But we didn't yell. We simply
asked, and after some negotiation, the owner agreed to sell it.
We were always willing to walk away from the Supabase brand if we needed to, but the price was reasonable for both parties. There really
isn't much more to it than that.
## What's next?
Over the next few weeks, we'll update our domain name across most of the sites. If you're using a Supabase database and API, you're on
a ".co" domain so your apps won't be affected at all.
You may also find some [easter eggs](https://twitter.com/AntWilson/status/1354343248098070530) appear ...
+100
View File
@@ -0,0 +1,100 @@
---
title: PgBouncer is now available in Supabase
description: Better support for Serverless and Postgres.
author: angelico_de_los_reyes
author_title: Supabase
author_url: https://github.com/dragarcia
author_image_url: https://github.com/dragarcia.png
authorURL: https://github.com/dragarcia
image: bouncer/pgbouncer-og.jpg
thumb: bouncer/pgbouncer-thumb.jpg
tags:
- database
- engineering
date: '2021-04-02'
---
Javascript Frameworks like [Next.js,](https://nextjs.org/) [Redwood](https://redwoodjs.com/), [Blitz](https://blitzjs.com/), and tools
like [Prisma](https://www.prisma.io/docs/guides/deployment/deployment#pgbouncer) are all moving in one direction. Serverless.
Serverless functions work great for developers using the Supabase API because we manage a [PostgREST](https://postgrest.org/en/v7.0.0/)
server for every project. Supabase also provides direct access to the Postgres database, so that developers can connect any tool they want.
Unfortunately, Serverless function don't work well for direct Postgres connections (for reasons we'll discuss soon).
Jamstack developers make up a large portion of the Supabase Community. While we'd love for developers to use PostgREST, we mostly want
developers to use Postgres. This means supporting the tools which they already love.
So today we are adding [PgBouncer](https://www.pgbouncer.org/), an open source connection pooler for Postgres.
## What is Connection Pooling?
![Connection Pooling](/new/images/blog/bouncer/connection-pool.png)
Typically when a client connects to a PostgreSQL database, they need to open and manage their own database connection. With a connection pool,
connections are already opened and available for use. When a client makes a request, they use a connection from the pool. When the transaction
or session is completed the underlying connection is simply returned to the pool and is once again free to be used by another user or application.
### Handling connection surges
In a traditional architecture, middleware servers (e.g. APIs) manage a small number of connection to a Postgres database.
Essentially, the middleware server is a connection pool.
In a Serverless environment, there is no middleware server to maintain a connection, so they create a **new** connection for
each concurrent request. Since Serverless functions are typically used for bursty workloads, this can end up opening a lot of
connections to the database and overwhelm your Postgres server.
Connection pools mitigate this. Connections are opened beforehand and recycled across users and applications. What's more,
[connection pools are specialized for this task](https://medium.com/@k.wahome/database-connections-less-is-more-86c406b6fad).
A small number of connections is sufficient to handle demand ten, twenty times its size, or even more. Whenever a new connection
is required it is taken from a pool of open and available connections instead of initializing an entirely new one. This eliminates
the need to spawn a new process.
## Misconceptions
It's a common misconception that PgBouncer increases the number of connections a Postgres instance can open.
This is not the case. If Postgres is configured for a maximum of 50 connections before connection pooling, it
will still only be able to open 50. Connection pooling simply keeps connections open and idle, ready to accept clients. Nevertheless,
as mentioned above, PgBouncer allows your database to be able to handle more than it can without a connection pool.
## Connection "Queuing"
PgBouncer is like a Queue. With regular Postgres, when you hit your connection limit, new connections are rejected. PgBouncer overcomes this
limitation. When all connections in the pool are in-use, it doesn't reject any incoming requests. Instead,
[PgBouncer queues them](https://www.percona.com/blog/2021/02/26/connection-queuing-in-pgbouncer-is-it-a-magical-remedy/) until a
connection is returned to the pool and made available. This doesn't mean connection pooling is a magic bullet. If your clients is
running expensive queries then the connections might take a long time before they are returned to the pool. The natural solution to
this is to increase your database resources so that it processes queries faster or PgBouncer can open more connections.
## Using Connection Pooling in Supabase
![Pooling UI](/new/images/blog/bouncer/pooler-supabase.png)
From today, all new projects will include connection pooling. In the `Database` section of our dashboard, you will notice a new section for it.
Under the hood, we utilise PgBouncer which is installed in the same server as PostgreSQL. Through the dashboard, we provide you with the
necessary connection details to start using the connection pool as well as the ability to modify `Pool Mode`. Not sure which mode to use?
Below is a quick primer on each mode.
## Pool modes
`Pool Mode` determines how PgBouncer handles a connection.
### Session
When a new client connects, a connection is assigned to the client until it disconnects. Afterward, the connection is returned back to the pool. All PostgreSQL features can be used with this option.
### Transaction
This is the suggested option for serverless functions. With this, the connection is only assigned to the client for the duration of a transaction. Once done, the connection is returned to the pool. Two consecutive transactions from the same client could be done over two, different connections. Some session-based PostgreSQL features such as prepared statements are not available with this option. A more comprehensive list of incompatible features can be found [here](https://www.pgbouncer.org/features.html).
### Statement
This is the most granular option. Connections are returned to the pool after every statement. Transactions with multiple statements are not allowed. This is best used when `AUTOCOMMIT` is in use.
## What's next?
Try out connection pooling now with a new project in the [dashboard.](http://app.supabase.io) For now, we do not have any plans to port this over to older projects.
Eventually, we will expose more PgBouncer settings to the UI such as `Pool Size`. At the moment it is set to `15`.
We are still working towards getting the latest version of Supabase Postgres to both the AWS and Digital Ocean marketplaces. Follow us on [Twitter](https://www.notion.so/PgBouncer-is-now-available-in-Supabase-345a74d402464670923cf404b714a354) to be informed once it's released!
+234
View File
@@ -0,0 +1,234 @@
---
title: Workflows are coming to Supabase
description: Functions are great, but you know what's better?
author: fracek
author_title: Supabase
author_url: https://github.com/fracek
author_image_url: https://github.com/fracek.png
authorURL: https://github.com/fracek
image: workflows/workflows-og.jpg
thumb: workflows/workflows-thumb.jpg
tags:
- functions
- workflows
date: '2021-04-02'
---
This week we [launched Supabase Storage](https://supabase.io/blog/2021/03/30/supabase-storage), which leaves one other huge piece of the
stack that everyone is asking for: Functions.
## TLDR
We're not releasing Functions today. Trust us, we know you want them. They are coming, just not today.
But we are building something that we think you're going to like: Workflows. We haven't finished building it yet, but Workflows are
a "piece" of the Function story and arguably an even more exciting feature.
![Everyone wants functions](/new/images/blog/workflows/functions.jpg)
## Firebase Functions
Firebase functions are relatively simple. If you use Serverless, AWS Lambda, Cloudflare Workers, Next.js API routes, or
Netlify Functions, then you know how they work. A Firebase function executes some code which you provide, without you managing a server.
Specifically for Firebase, they have another key feature - they can be triggered by database events. For example, you can
trigger a function whenever a Firestore Document is updated.
This is great, but it is still limited for a few real-world use cases. For example, what if you want to send an email to a user
one day after a user signs up. Or one year? There is no queuing functionality in Firebase. You'd have to manage a process like
this yourself, probably using a cron-job.
## A better solution?
We searched for some open source tools which we think are solving this problem well. We looked at
[NodeRed](https://supabase.io/blog/2021/03/30/supabase-storage#designing-the-storage-middleware), [n8n](https://n8n.io/),
[Airflow](http://airflow.apache.org/blog/airflow-two-point-oh-is-here/), and about 10 other tools. They are amazing tools on their
own, but for the Supabase Stack they ultimately had the
[same shortcomings](https://supabase.io/blog/2021/03/30/supabase-storage#integration-with-the-supabase-ecosystem) that we found
with Storage providers - most of them lacked deep Postgres integration.
We went back to the drawing board and asked, "if we could wave a wand and get the perfect solution, what would it look like?".
The tool that came very close is [AWS Step Functions](https://aws.amazon.com/step-functions/). The only problem: it's not open source.
Luckily, their [state language](https://states-language.net/spec.html) is.
Using this states language, we are [building an open source orchestration engine](https://github.com/supabase/workflows) for
managing very complex Workflows with queueing, etc. It will be built with Elixir.
This engine won't execute code. Instead, it will coordinate and execute existing functions wherever they live: AWS, GCP, Azure,
OpenFaas, and of course Postgres.
We plan to add "modules" which work natively: email services, notification services, and other platforms.
The engine is deeply integrated with Postgres. `Jobs`, `queues`, and `logs` will be stored and accessible by SQL.
Once ready, we will make this available in the Supabase Dashboard with a Zapier-like interface.
## What are Workflows
Workflows orchestrate and execute functions in response to a database event (insert, update, delete) or a HTTP call (direct invocation).
You can use them to rapidly develop microservices (once we have functions) without worrying about servers.
Workflows are stateless - the output of a state becomes the input of the next state.
Workflows are defined using Amazon States Languages, so you can import your workflows from AWS (although we are still building handlers
for most AWS resources).
Workflows can be _persistent_ (the default). This means they are tolerant to server restarts, but it also means they need to use
the database to store their state.
Workers can be _transient._ These are are fully in-memory if you don't want to store the execution state (for example, IoT
applications that trigger workflows very often). Transient workflows are not restarted if the server crashes or is restarted.
## Example
A typical use-case for workflows is sending emails. For example, you might want to send a user an email one day after they
sign up. In database terms we can say: "trigger an email workflow whenever there is an insert on the `users` table."
Let's break this down into steps, then tie it all together at the end:
### Sending an email
```yaml
SendEmail:
Type: Task
Next: Complete
Resource: my-email-service
Parameters:
api_key: my-api-key
template_id: welcome-email
payload:
name.$: '$.record.name'
email.$: '$.record.email'
```
Here we have a "Task" which triggers a call to an email service (like Mailgun or Postmark). Specifically, it's telling
the service to send the `welcome-email` template, and it's providing it a `name` and an `email` as parameters.
### Waiting a day
Since we don't want to send the email immediately, we need to tell Workflows to wait one day
```yaml
WaitOneDay:
Type: Wait
Next: SendEmail
Seconds: 86400
```
Here "one day" is specified in seconds.
### Trigger on insert
We mentioned that you could trigger a workflow whenever there is an "insert" on the `users` table. But what if you insert
multiple users at once? Not a problem - we can loop through all the inserts with a `Map`:
```yaml
EmailUsers:
Type: Map
End: true
InputPath: '$.changes'
Iterator:
StartAt: CheckInsert
States:
CheckInsert:
Type: Choice
Default: Complete
Choices:
- Variable: '$.type'
StringEquals: INSERT
Next: WaitOneDay
```
In this part, we have a task "EmailUsers", which iterates through all the database events (`$.changes`) and checks if they are INSERTs.
### Tying it all together
Let's see how it looks all together:
```yaml
---
Comment: Email users after one day
StartAt: EmailUsers
States:
EmailUsers:
Type: Map
End: true
InputPath: '$.changes'
Iterator:
StartAt: CheckInsert
States:
CheckInsert:
Type: Choice
Default: Complete
Choices:
- Variable: '$.type'
StringEquals: INSERT
Next: WaitOneDay
WaitOneDay:
Type: Wait
Next: SendEmail
Seconds: 86400
SendEmail:
Type: Task
Next: Complete
Resource: send-templated-email
Parameters:
api_key: my-api-key
template_id: welcome-email
payload:
name.$: '$.record.name'
email.$: '$.record.email'
Complete:
Type: Succeed
```
The workflow receives the following JSON data from Supabase [Realtime](https://github.com/supabase/realtime):
```json
{
"changes": [
{
"columns": [
{
"flags": ["key"],
"name": "id",
"type": "int8",
"type_modifier": 4294967295
},
{
"flags": [],
"name": "name",
"type": "text",
"type_modifier": 4294967295
},
{
"flags": [],
"name": "email",
"type": "text",
"type_modifier": 4294967295
}
],
"commit_timestamp": "2021-03-17T14:00:26Z",
"record": {
"id": "101492",
"name": "Alfred",
"email": "alfred@example.org"
},
"schema": "public",
"table": "users",
"type": "INSERT"
}
],
"commit_timestamp": "2021-03-17T14:00:26Z"
}
```
## Next Steps
We've already open sourced the Workflow interpreter [here](https://github.com/supabase/workflows). It's built with Elixir,
so you can find it on Hex [here](https://hexdocs.pm/workflows/readme.html).
After we've ironed out a few bugs we will integrate it into the Supabase Stack. As with all Supabase features, we'll add a
[nice UI](https://ui.supabase.io/) to make prototyping extremely rapid. We'll integrate the UI with the code (via Git) to make
sure everything is version controlled.
+7
View File
@@ -54,5 +54,12 @@
"position": "Engineering",
"username": "soedirgo",
"author_image_url": "https://github.com/soedirgo.png"
},
"fracek": {
"author": "Francesco Ceccon",
"author_url": "https://github.com/fracek",
"position": "Engineering",
"username": "fracek",
"author_image_url": "https://github.com/fracek.png"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

+25 -1
View File
@@ -5,9 +5,33 @@
<link>https://supabase.io</link>
<description>Latest news from Supabase</description>
<language>en</language>
<lastBuildDate>Wed, 31 Mar 2021 16:00:00 GMT</lastBuildDate>
<lastBuildDate>Thu, 01 Apr 2021 16:00:00 GMT</lastBuildDate>
<atom:link href="https://supabase.io/blog/rss.xml" rel="self" type="application/rss+xml"/>
<item>
<guid>https://supabase.io/blog/2021/04/02/supabase-workflows</guid>
<title>Workflows are coming to Supabase</title>
<link>https://supabase.io/blog/2021/04/02/supabase-workflows</link>
<description>Functions are great, but you know what's better?</description>
<pubDate>Thu, 01 Apr 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/04/02/supabase-pgbouncer</guid>
<title>PgBouncer is now available in Supabase</title>
<link>https://supabase.io/blog/2021/04/02/supabase-pgbouncer</link>
<description>Better support for Serverless and Postgres.</description>
<pubDate>Thu, 01 Apr 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/04/02/supabase-dot-com</guid>
<title>Supabase Dot Com</title>
<link>https://supabase.io/blog/2021/04/02/supabase-dot-com</link>
<description>The Supabase Domain name is changing.</description>
<pubDate>Thu, 01 Apr 2021 16:00:00 GMT</pubDate>
</item>
<item>
<guid>https://supabase.io/blog/2021/04/01/supabase-nft-marketplace</guid>
<title>Supabase Launches NFT Marketplace</title>