new digs
No files matched your search
@@ -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.
|
||||
|
||||

|
||||
|
||||
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 ...
|
||||
@@ -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?
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
||||

|
||||
|
||||
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!
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 347 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 299 KiB |
|
After Width: | Height: | Size: 342 KiB |
|
After Width: | Height: | Size: 319 KiB |
@@ -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>
|
||||
|
||||