diff --git a/apps/docs/pages/guides/cli/local-development.mdx b/apps/docs/pages/guides/cli/local-development.mdx
index 1682de48d8c..2ca4caf7dfd 100644
--- a/apps/docs/pages/guides/cli/local-development.mdx
+++ b/apps/docs/pages/guides/cli/local-development.mdx
@@ -423,39 +423,17 @@ If you have additional triggers or RLS policies defined on your `auth` schema, y
supabase db remote commit --schema auth
```
-### Enabling Local Logging
+### Local Logging
-Local logs rely on the Supabase Analytics Server. This can be enabled via the CLI configuration, and requires a Google Cloud project and BigQuery access.
+Local logs rely on the Supabase Analytics Server, and are available in the Studio automatically.
- The Google Cloud project must have billing enabled. The dataset created and managed by Analytics
- will be within the US. Read more about this requirement
+ For advanced logs analysis using the Logs Explorer, it is advised to use the BigQuery backend
+ instead of the default Postgres backend. Read about the steps
[here](https://supabase.com/docs/reference/self-hosting-analytics/introduction#bigquery).
-Requirements:
-
-1. Google Cloud project number
-2. Google Cloud project ID
-3. Google Cloud Service Account Key, obtained through [Google Cloud IAM dashboard](https://console.cloud.google.com/iam-admin/iam), with BigQuery Admin role assigned to the service account.
-
-Once you have these 3 items, follow these steps:
-
-First, update your project's `supabase/config.toml`:
-
-```bash
-[analytics]
-enabled = true
-gcp_project_number = "123456"
-gcp_project_id = "my-project-id"
-gcp_jwt_path = "supabase/gcloud.json"
-```
-
-Next, place your service account key (a JSON file) at the corresponding path and ensure that it is correctly named.
-
-Last, start your local stack using `supabase start`
-
-This will switch the logging drivers and will direct logs to the Analytics server. You will be able to view and query your logs via the Studio Logs Explorer and Logs UI.
+Logs will be directed to the Analytics server instead of the docker logging driver. All logs will be stored in the local database under the `_analytics` schema.
## Limitations and considerations
diff --git a/apps/docs/pages/guides/database/column-encryption.mdx b/apps/docs/pages/guides/database/column-encryption.mdx
index d750f6c33b1..1734d88a6af 100644
--- a/apps/docs/pages/guides/database/column-encryption.mdx
+++ b/apps/docs/pages/guides/database/column-encryption.mdx
@@ -9,9 +9,27 @@ export const meta = {
video: 'https://www.youtube.com/v/J9mTPY8rIXE',
}
-Supabase provides a secure method for encrypting columns using [Vault](/docs/guides/database/vault), our Postgres secrets manager. Vault is a Postgres extension with an integrated UI intended to act as a secure global secrets management for your project.
+Supabase provides a secure method for encrypting data using [Vault](/docs/guides/database/vault), our Postgres secrets manager. Vault is a Postgres extension with an [integrated UI](https://app.supabase.com/project/_/settings/vault/secrets) intended to act as a secure global secrets management for your project.
-Vault enables an advanced feature called Transparent Column Encryption (TCE) which provides a safe way to encrypt your data so that it doesn't leak into logs and backups. It can also provide row-level authenticated encryption.
+In addition to the Vault secret storage table, Supabase also enables an advanced feature called Transparent Column Encryption (TCE) which provides a safe way to encrypt columns in your own tables so that they doesn't leak into logs and backups. It can also provide row-level authenticated encryption.
+
+Column Encryption comes with tradeoffs that need to be considered before using it.
+
+ - Encryption and decryption both take time, inserting and selecting encrypted data takes more time than a "plain" column of data. Queries that must load a lot of rows with encrypted columns will be slower than those that are not encrypted.
+
+ - Encrypted columns should never be indexed. This is because the index will store the encrypted value of a column, which would not be useful. To look up an encrypted column, you must first look up its row by some other unencrypted column, like a primary key.
+
+ - Encrypted columns can be queried in a `WHERE` clause, but this can also have some negative performance consequences, since the value must be decrypted in order to matched to any `WHERE` qualifiers. For small result sets the impact is small, but queries that match many rows will cause each row to be decrypted in order to check against the `WHERE` clause. In the worst case, the entire table must be scanned and decrypted to check against a `WHERE` clause.
+
+ - While you can encrypt multiple columns in the same table, each column must go through a full encryption cycle, so two columns will take twice the time as one, three columns three time as long, and so on. It is usually better to break up large tables into smaller tables with at most one or two encrypted columns, and associated them with [foreign keys](https://www.postgresql.org/docs/current/tutorial-fk.html) that can be used to JOIN them when necessary.
+
+In general, it is a bad idea to over-use column encryption for mundane data or data that you need to search against such as names, user or account types, addresses, country codes, etc. Column encryption is intended to be used for very sensitive data that would cause serious issues if it were to leak, such as API keys, payment keys, highly sensitive personal information, etc.
+
+## Encryption Keys
+
+Encryption requires keys. Keeping the keys in the same database as the encrypted data would be unsafe. It would be like leaving a key in a door lock. For that reason, encryption keys are kept separate from the database.
+
+Supabase column encryption and the Vault both use a low level Postgres extension library called [pgsodium](https://github.com/michelp/pgsodium/). This library in turn wraps a very popular encryption library called [libsodium](https://doc.libsodium.org/). These libraries provide functionally for doing something called [Key Derivation](https://libsodium.gitbook.io/doc/key_derivation). Supabase uses key derivation to _derive_ the encryption keys used by column encryption. These keys are derived from a _Root Key_ that is stored by Supabase, outside the database. If you need to migrate encrypted data from one system to another, you must ensure that this root key is copied over as well. There is a [REST API for getting the root key for a project](https://supabase.com/docs/reference/api/gets-projects-pgsodium-config).
## Encrypting columns
@@ -23,15 +41,19 @@ Once you've created an encrypted column, you can insert data into the table like

+As mentioned above, indexing an encrypted column serves no purpose and has a detrimental effect on performance. Indexing encrypted values is not useful since the index needs to store the unencrypted value to be usable, and that would defeat the purpose of storing encrypted data. Do not create indexes on encrypted columns.
+
## Decrypting data
Decrypted data is accessed using a special view that is automatically created after adding an encrypted column to a table. This view decrypts the data row-by-row as you access it. By default, this view is called `decrypted_`. In the example below, the decryption view for the `profiles` table is called `decrypted_profiles`. Notice there is a new column in the view called `decrypted_emails` that contains the decrypted email value.

+Accessing decrypted data is slower than accessing unencrypted data. Any row you query from this view will go through a decryption function, which takes some time and can be a significant performance pentalty if your query loads lots of rows. It's always advisable to look up rows by some indexed unencrypted key first, like a primary key, so that only one row is decrypted at a time.
+
## Using an Encrypted Table
-Now that you have TCE setup for a table, it's easy to use by simply inserting data into the table, and querying that data by looking at its generated view. The view is named `decrypted_` and by default is in the same schema as your table:
+Now that you have column encryption setup for a table, it's easy to use by simply inserting data into the table, and querying that data by looking at its generated view. The view is named `decrypted_` and by default is in the same schema as your table:
```sql
insert into secrets
@@ -67,6 +89,22 @@ nonce | \x300a14aa721184ff7cf0f6bf088da267
Notice how there is a new column called `decrypted_secret`. This column is not stored in database or on disk at all, it is generated “on-the-fly” as you select from the view. Database dumps do not contain this information, only the view itself, and most importantly, **raw decryption keys are never stored**.
+## Granting API Access to encrypted columns
+
+When you create an encrypted column in the `public` database schema, then that column and the decryption view that is created for it are given _public access via the PostgREST API_. In general it is not recommended to encrypt columns in the public schema, as this adds some additional security considerations that you need to think about, but it is still possible and useful in some cases depending on your level of security comfort. Only you can decide the risks and rewards of making decrypted data available to public API access. It is very strongly recommended that you must protect your public encrypted columns with a [Row Level Security (RLS) Policy](docs/guides/auth/row-level-security).
+
+Even though objects created in the `public` schema default to public access, There is an additional layer of security with pgsodium that must be enabled in order for decryption to work with the PostgREST API. The permissions necessary to call pgsodium functions must be granted to one of the API role that is accessing the public objects.
+
+There are three roles available for API access with Supabase, The `anon` role represents unauthenticated anonymous users and should _never_ be granted access to pgsodium. The `service_role` which is meant to be used by other services in your system, and whose token should never be exposed publicly, and the `authenticated` role which represents authenticated users who present a valid JWT token and are identified by the system as a known user.
+
+By default, only the `service_user` role is granted access to the column encryption functions. If you wish to make encrypted columns available to your authenticated users, then you must run `GRANT pgsodium_keyiduser TO authenticated;` from the Supabase console or logged in as the `postgres` role. This table shows the default permission settings for API roles accessing the pgsodium encryption functions:
+
+| Role | pgsodium_keyiduser | pgsodium_keymaker |
+| ------------- | ------------------ | ----------------- |
+| anon | X | X |
+| authenticated | X | X |
+| service_role | Y | X |
+
## How Key Derivation Works
The current state-of-the-art in encryption libraries is [libsodium](https://doc.libsodium.org/).
diff --git a/apps/docs/pages/guides/database/connecting-to-postgres.mdx b/apps/docs/pages/guides/database/connecting-to-postgres.mdx
index 3b6ba626626..2140019c23b 100644
--- a/apps/docs/pages/guides/database/connecting-to-postgres.mdx
+++ b/apps/docs/pages/guides/database/connecting-to-postgres.mdx
@@ -51,6 +51,20 @@ Every Supabase project comes with PgBouncer for connection pooling. A connection
/>
+## Supavisor
+
+Supavisor is a new connection pooler by Supabase. It can provide a more scalable connection pool than PgBouncer, and runs on a highly available cluster not on your database.
+
+This can free up some CPU cycles for your database to use for queries. It also makes connecting to Postgres in a serverless environment much easier.
+
+We're building compatibility with PgBouncer. It won't require any application changes to switch from PgBouncer to Supavisor.
+
+To use Supavisor [contact support](https://supabase.com/dashboard/support/new) and we will expose the connection string in your project dashboard.
+
+Supavisor is open source and compatible with any Postgres deployment.
+
+Check out [the Github repository](https://github.com/supabase/supavisor).
+
## Choosing a connection method
- The Serverless APIs provide programmatic access and have [built-in connection pooling](https://postgrest.org/en/stable/references/connection_pool.html). You can use these for all browser and application interactions. We recommend using these wherever possible.
diff --git a/apps/docs/pages/guides/platform/network-restrictions.mdx b/apps/docs/pages/guides/platform/network-restrictions.mdx
index 8d7fe089fcb..cb86b8008fd 100644
--- a/apps/docs/pages/guides/platform/network-restrictions.mdx
+++ b/apps/docs/pages/guides/platform/network-restrictions.mdx
@@ -68,6 +68,7 @@ Restrictions applied successfully: true
- The current iteration of Network Restrictions applies to connections to Postgres and PgBouncer and doesn't currently apply to APIs offered over HTTPS (e.g., PostgREST, Storage, and Auth).
- Network Restrictions should not be used if you need to connect to your Postgres database using Edge Functions.
+- [Supavisor](https://github.com/supabase/supavisor/) does not currently support Network Restrictions.
export const Page = ({ children }) =>
diff --git a/apps/docs/pages/guides/realtime/postgres-changes.mdx b/apps/docs/pages/guides/realtime/postgres-changes.mdx
index 57b1d355830..c776b9d706c 100644
--- a/apps/docs/pages/guides/realtime/postgres-changes.mdx
+++ b/apps/docs/pages/guides/realtime/postgres-changes.mdx
@@ -531,6 +531,33 @@ For example, if you're using the `supabase-js` `v2` client then you can pass you
supabase.realtime.setAuth('fresh-token')
```
+## Limitations
+
+The current version of Realtime's Postgres Changes feature has some performance limitations to keep in mind. There can be a bottleneck on the database that limits the number of messages streamed to subscribed clients.
+
+The polling query that fetches the changes is currently single-threaded. If you are frequently changing your database, the polling query may not be able to fetch the changes rapidly enough. The delivery of the changes will be delayed until you will get timeout. Additionally, there is a polling query per subscribed client, which means that each unique pair of `filters` and `JWT token` (logged-in user) affects the performance of the polling query. In other words, RLS and filters can further limit the number of messages that can be streamed to subscribed clients.
+
+From our testing and observation of the performance of the polling query, we have found that the following limits are safe to use:
+
+| Database Add-on | Filters | RLS Usage | Concurrent Clients | Records per second per client | Messages per second (total) | Latency p95 (ms) |
+| ---------------- | ------- | --------- | ------------------ | ----------------------------- | --------------------------- | ---------------- |
+| micro < > medium | 🚫 | 🚫 | 500 | 10 | 5,000 | 257 |
+| micro < > medium | 🚫 | 🚫 | 1,000 | 10 | 10,000 | 800 |
+| micro < > medium | 🚫 | 🚫 | 5,000 | 2 | 10,000 | 1,120 |
+| large and above | 🚫 | 🚫 | 1,000 | 10 | 10,000 | 261 |
+| large and above | 🚫 | 🚫 | 5,000 | 2 | 10,000 | 952 |
+| large and above | 🚫 | 🚫 | 10,000 | 1 | 10,000 | 949 |
+| large and above | 🚫 | 🚫 | 200,000 | 0.04 (1 in 25 seconds) | 8,000 | 15,709 |
+| large and above | ✅ | ✅ | 500 | 2 | 1,000 | 262 |
+| large and above | ✅ | ✅ | 1,000 | 1 | 1,000 | 431 |
+| large and above | ✅ | ✅ | 5,000 | 0.2 (1 in 5 seconds) | 1,000 | 702 |
+
+If you want to use Realtime's Postgres Changes feature you should be aware of these limitations. And if you are using this feature at scale, you should consider using separate table without RLS and filters for the purpose of streaming changes to subscribed clients. Alternatively, you can use Realtime server-side only and then re-stream the changes to your clients using a Realtime Broadcast. Don't forget to run your own benchmarks to make sure that the performance is acceptable for your use case.
+
+We are making many improvements to Realtime's Postgres Changes.
+
+If you are uncertain about the performance of your use case, please reach out using [Support Form](https://supabase.com/dashboard/support/new) and we will be happy to help you. We have a team of engineers that can advise you on the best solution for your use-case.
+
## More Realtime Quickstarts
- [Broadcast Quickstart](/docs/guides/realtime/broadcast)
diff --git a/apps/www/_blog/2023-08-09-supabase-studio-3-0.mdx b/apps/www/_blog/2023-08-09-supabase-studio-3-0.mdx
index 2fa636a2c88..4a79f060d79 100644
--- a/apps/www/_blog/2023-08-09-supabase-studio-3-0.mdx
+++ b/apps/www/_blog/2023-08-09-supabase-studio-3-0.mdx
@@ -5,7 +5,7 @@ launchweek: 8
tags:
- launch-week
- studio
- - ai
+ - AI
date: '2023-08-09'
published_at: '2023-08-09T09:00:00.000-07:00'
toc_depth: 3
@@ -59,11 +59,11 @@ Today, we're releasing a huge improvement to our SQL Editor. First up, we've add
Supabase AI is aware of the SQL snippet in the editor and can modify it for you. You can ask it to change `customers` to `customer_orders`, for example. You can interact with the code the same way you would converse with ChatGPT until it's just right.
-
+
Next, we've added a diff view for changes that Supabase AI makes to your SQL snippet. You can tell Supabase AI what you want changed, and visualize it as you would a Git diff. From this view, you can accept or reject the diffs, and keep asking Supabase AI to make changes until you're satisfied.
-
+
We've wondered for a long time how to make it easier to teach developers how to use SQL. It's fortunate we didn't solve this problem too quickly, as it turns out that AI does a much better job than we could do ourselves.
@@ -86,7 +86,7 @@ Along with these huge AI features, we also added a bunch of new improvements els
## Schema Visualizer
-
+
For a while now, many Supabase users have been using [Zernonia's](https://github.com/zernonia) [Supabase Schema visualization tool](https://supabase-schema.vercel.app/). While this was an amazing tool, many users wanted to see something like this directly integrated into the Studio.
@@ -100,7 +100,7 @@ Postgres has built-in support for managing users and roles, and this release, we
A few months back, we saw this [PR](https://github.com/supabase/supabase/pull/13745) come in out of the blue from [HTMHell](https://github.com/HTMHell). They built the entire thing with zero help or direction from our team. We were blown away. We had some changes to make on the backend to properly accommodate the UI, and now we're almost ready to get this out into the wild!
-
+
Due to the security focus of this feature, we want to make sure we do a very thorough job of testing, so we're hoping to make this generally available in the next week or so.
@@ -110,7 +110,7 @@ Massive thanks to [HTMHell](https://github.com/HTMHell) (amazing handle btw) for
Speaking of commonly requested features, this one has to be in the all-time top 5. Your beautiful, hand-crafted SQL snippets used to be yours and yours alone. Now you can share them with team members and let them bask in your technical prowess.
-
+
You can create a set of project-wide snippets for doing common tasks, making it faster to collaborate and build. To share a snippet, just take a personal snippet that ~~Supabase AI~~ you wrote and share it with the project. It will show up in a new Project Snippets list that's visible to everyone on the team.
@@ -122,7 +122,7 @@ We're releasing a new UI for working with database migrations right from the Stu
As migrations get run against your project from the CLI, you can see information in the Studio about when the migration was run, by who and what changes were made. [See the documentation](https://supabase.com/docs/guides/cli/local-development#database-migrations) to get started with migrations.
-
+
## Wrappers UI
@@ -130,7 +130,7 @@ During Launch Week 6, we [announced](https://supabase.com/blog/postgres-foreign-
When we released Wrappers, we had support for just two providers — Stripe and Firebase. We're now up to 6! This round, we're happy to release support for S3, ClickHouse, BigQuery, and Logflare! Wrappers add a mind-bending level of extensibility to Supabase projects. You can pull data straight into your projects as though they were normal Supabase tables — you can even query them with our client libraries. It's a whole new world of possibilities.
-
+
## Wrapping Up
diff --git a/apps/www/_blog/2023-08-11-launch-week-8-community-highlights.mdx b/apps/www/_blog/2023-08-11-launch-week-8-community-highlights.mdx
new file mode 100644
index 00000000000..f80b7ea6b70
--- /dev/null
+++ b/apps/www/_blog/2023-08-11-launch-week-8-community-highlights.mdx
@@ -0,0 +1,145 @@
+---
+title: 'Launch Week 8 Community Highlights'
+description: Highlights from the community for the past 4 months.
+launchweek: 8
+tags:
+ - launch-week
+date: '2023-08-11'
+published_at: '2023-08-11T06:00:00.000-06:00'
+toc_depth: 3
+author: paul_copplestone
+image: launch-week-8/day-5-community/community-highlights-OG.jpg
+thumb: launch-week-8/day-5-community/community-highlights-thumbs.jpg
+---
+
+Supabase aims to be as collaborative as possible - working with, sponsoring, and supporting as many open source tools as possible. In many ways, we're more like a "community of communities". Here are a few highlights from the past 4 months.
+
+## State of the community
+
+We've seen a number of milestones this Launch Week. We passed 50,000 stars on GitHub ([and getting close to 55k!](https://github.com/supabase/supabase)), putting Supabase in the top 160 most-popular repositories. We reached 80k followers on [𝕏witter](https://twitter.com/supabase), 17k [Discord](https://discord.supabase.com) members, and 14k [YouTube](https://youtube.com/supabase) subscribers. We are exploring new platforms (thanks to [Yuri's](https://twitter.com/yuricodesbot) arrival) - [Instagram](https://www.instagram.com/supabasecom/), [TikTok](https://www.tiktok.com/@supabase.com), and [Threads](https://www.threads.net/@supabasecom).
+
+To our incredible community, thank you. Here are a few ways that you've contributed to the growth:
+
+### Stack Overflow Survey
+
+
+
+This was the first year that Supabase appeared on the Stack Overflow survey for [Databases](https://survey.stackoverflow.co/2023/#most-popular-technologies-database) as the 17th “most used”. As a bonus, Postgres took the #1 spot for the first time, and we hope we can continue to contribute to that trend.
+
+## InfraRed 100 and Times Square
+
+
+
+We were featured in Redpoint's [InfraRed 100](https://www.redpoint.com/infrared/100/), a report that recognizes 100 transformative companies in cloud infrastructure. We are honored to be included there with so many amazing companies we admire. We even made an appearance in Times Square.
+
+[Read the full report](https://www.redpoint.com/infrared/100/)
+
+### Community Meetups
+
+
+
+Supabase started as a remote company, and almost everything we've done so far has been digital. This Launch Week included in-person meetups throughout the world, 100% organized by the community. We had meetups in 5 countries, with hundreds of attendees across the world. It has been a successful experiment, something we'll consider for next time. Thanks to Fatuma, Isheanesu, Daniel, Philip, and Thor for organizing!
+
+### New Kotlin Library
+
+
+
+Are you a mobile dev? We now have client libraries for Android. This is thanks to one of our community members - [@TheRealJanGER](https://twitter.com/TheRealJanGER). Check out the [Tutorial](/blog/native-mobile-auth) and [Docs](/docs/reference/kotlin/introduction), and feel free to contribute any changes that you need to build with Kotlin.
+
+### Contributors
+
+There are so many humans who have made meaningful contributions to the Supabase ecosystem since our last Launch Week:
+
+- We've continued growing our [community maintainers](https://github.com/orgs/supabase-community/teams), with a particular focus on Mobile. We now have docs for [Swift](/docs/reference/swift/introduction) and [Kotlin](/docs/reference/kotlin/introduction).
+- [kamilogorek](https://github.com/kamilogorek) and [adiologydev](https://github.com/adiologydev) for integrating Schema Visualizer into the Studio. And another shoutout to the legend, [Zernonia](https://twitter.com/zernonia), for providing the inspiration.
+- As always, a big shoutout to [Gary](https://github.com/GaryAustin1) and [Olyno](https://github.com/olyno) - official moderators of our [Discord](https://discord.supabase.com/) and overall incredibly helpful people. The community would not be the same without them.
+
+## Ecosystem partners
+
+The past few months we had a focus on integrations and welcomed a lot of new partners.
+
+### Integrations Marketplace
+
+We've been running our Integrations Marketplace in “stealth mode” for about a year now and has now grown to [over 60 integrations](/partners/integrations). In the last couple of months, we've added amazing products like [N8N](/partners/integrations/n8n), [Passage by 1 Password](/partners/integrations/passageidentity), and [Refine](/partners/integrations/refine_dev). This Launch Week we've made it easy to [build an integration](/docs/guides/platform/oauth-apps/build-a-supabase-integration#create-an-oauth-app) using OAuth2 and the Management API in the new [Supabase Integrations Marketplace](/blog/supabase-integrations-marketplace). We've started with a few partners to help us build and test the OAuth functionality, including [Cloudflare](/partners/integrations/cloudflare-workers), [Resend](/partners/integrations/resend), [Snaplet](/partners/integrations/snaplet), [Trigger.dev](/partners/integrations/triggerdotdev), [Windmill](/partners/integrations/vercel), and [Vercel](/partners/integrations/windmill).
+
+### pgvector
+
+[pgvector](github.com/pgvector/pgvector/) adds vector capabilities to Postgres. We continue to work with the pgvector creator, [Andrew Kane](https://twitter.com/andrewkane), and others contributing to the project. In the past few months, we've added robust benchmarks to show how to [scale your ivfflat workloads](/blog/pgvector-performance) and established guidance on the [best models](/blog/fewer-dimensions-are-better-pgvector) to use with pgvectors. With v0.5.0 coming soon, we're extremely excited about the improved HNSW index. Performance and recall improvement are looking [significantly better](https://jkatz05.com/post/postgres/pgvector-hnsw-performance/) than the current ivfflat index in pgvector.
+
+### PostgREST
+
+Last month we rolled out support across the platform [PostgREST 11.1](/blog/postgrest-11-1-release). A huge shoutout to [Steve Chavez](https://twitter.com/_steve_chavez) for his continued support as the primary maintainer of the project. [PostgREST 11.2](https://github.com/PostgREST/postgrest/releases/tag/v11.2.0) was released yesterday, adding [Domain Representations](https://postgrest.org/en/v11.2/references/api/domain_representations.html), and we'll roll it out to platform soon.
+
+### LlamaIndex
+
+In one of the most community-driven contributions ever, a tweet from [us](https://twitter.com/kiwicopple/status/1664377669935349760?s=20), and a tweet from [LlamaIndex](https://twitter.com/jerryjliu0/status/1664413942045904896), led to a contribution from [a16z](https://twitter.com/stuffyokodraws/status/1664532449815302145?s=20). And a few days later we had a [Supabase Vector Store implementation in LlamaIndex](https://gpt-index.readthedocs.io/en/stable/examples/vector_stores/SupabaseVectorIndexDemo.html).
+
+### Transloadit
+
+The team at Transloadit are committed to building an open protocol for resumable uploads, to make it the standard for file uploads on the internet. We used two of their [tus-node-server](https://github.com/tus/tus-node-server/) for our recent [updates to Storage](/blog/storage-v3-resumable-uploads) and contributed back a few important changes as a result. [Check out their post about our collaboration](https://transloadit.com/blog/2023/08/casestudy-supabase/).
+
+### Mozilla
+
+We are huge fans of Mozilla at Supabase, so it was an honor when they chose [Supabase Vector](/vector) to build AI Help, a ChatGPT-like interface to the most popular developer docs on the internet: **[MDN](https://developer.mozilla.org/en-US/)**. [Learn more in their official announcement](https://developer.mozilla.org/en-US/blog/introducing-ai-help/).
+
+## Framework support
+
+Supabase is easier to use in your favorite frameworks.
+
+### Next.js Supabase Starter template
+
+We added support for Next.js 13's App router, including Cookie-based Auth; styled authentication forms with Tailwind CSS; examples for Client Components, server components, route handlers, server actions; and - of course - 100% TypeScript. Get started with one simple command:
+
+```bash
+npx create-next-app -e with-supabase
+```
+
+### Nuxt Supabase module
+
+The team at Nuxt [added support](https://twitter.com/_larbish/status/1687044609522778112) for the PKCE Auth Flow in their [Supabase x Nuxt module](https://supabase.nuxtjs.org/), making it even more secure. This module is a simple wrapper around [supabase-js](https://github.com/supabase/supabase-js) to enable usage and integration within Nuxt.
+
+### Tamagui Takeout
+
+The Tamagui team launched [TakeOut](https://tamagui.dev/takeout), a web and mobile starter that takes featuring everything you need to launch - including a nice backend, powered by Supabase.
+
+### PowerSync
+
+The team at PowerSync just dropped [an (extremely attractive) integration](https://docs.powersync.co/integration-guides/supabase-+-powersync) for building offline-first Flutter apps. This uses Postgres' built-in Publication functionality to track changes, which are then synced to an offline cache.
+
+## Courses
+
+### Modern Full Stack course
+
+Probably the most comprehensive Supabase resource on the internet, the team at Modern Full Stack just released a 7 chapter, 21 lesson [course on Supabase](https://modernfullstack.com/course/mfs401). The course includes:
+
+1. **Supabase Foundations**
+2. **Supabase Authentication**
+3. **A Masterclass on Supabase Databases**
+4. **Exploring the Supabase Storage API**
+5. **Supabase Realtime**
+6. **Unleashing Supabase's Edge Functions**
+7. **Achieving Mastery of Supabase**
+
+[Get started with Modern Full Stack.](https://modernfullstack.com/course/mfs401)
+
+### EggHead: Build a 𝕏witter clone course
+
+Our very own (and very talented) [Jon Meyers](https://twitter.com/jonmeyers_io) has released a new EggHead course that steps you through the process of creating a [Twitter clone with Next.js App Router and Supabase](https://egghead.io/courses/build-a-twitter-clone-with-the-next-js-app-router-and-supabase-19bebadb). You'll learn about:
+
+1. Cookie-based Auth
+2. Generating Typescript definitions from your PostgreSQL schema
+3. Tailwind CSS and styling
+4. Optimistic UI updates
+5. Subscribing to realtime database changes
+6. Configuring Supabase Auth to use cookies
+7. Using Row Level Security (RLS) policies to implement Authorization
+
+[Get started on EggHead.](https://egghead.io/courses/build-a-twitter-clone-with-the-next-js-app-router-and-supabase-19bebadb)
+
+## Bonus track: Supabase Album
+
+And finally, I promised Sam (CEO of Planetscale) that we'd [release an album](https://twitter.com/kiwicopple/status/1664118998169014273) before the end of the year, otherwise I'd give him 1% of my equity.
+
+
+
+As promised Sam, here is the [Official Supabase Album](https://www.youtube.com/watch?v=dQw4w9WgXcQ)
diff --git a/apps/www/_blog/2023-08-11-supavisor-1-million.mdx b/apps/www/_blog/2023-08-11-supavisor-1-million.mdx
new file mode 100644
index 00000000000..f0909feb6a6
--- /dev/null
+++ b/apps/www/_blog/2023-08-11-supavisor-1-million.mdx
@@ -0,0 +1,370 @@
+---
+title: 'Supavisor: Scaling Postgres to 1 Million Connections'
+description: 'Supavisor is a scalable, cloud-native Postgres connection pooler. We connected a million clients to it to see how it performs.'
+launchweek: 8
+tags:
+ - launch-week
+ - supavisor
+ - postgres
+date: '2023-08-11'
+published_at: '2023-08-11T09:00:00.000-07:00'
+toc_depth: 3
+author: egor_romanov,chasers,stas
+image: launch-week-8/day-5/supavisor-og.jpg
+thumb: launch-week-8/day-5/supavisor-thumb.jpg
+---
+
+One of the most [widely-discussed shortcomings](https://news.ycombinator.com/item?id=24735012) of Postgres is it's connection system. Every Postgres connection has a reasonably high memory footprint, and determining the maximum number of connections your database can handle is a [bit of an art](https://momjian.us/main/blogs/pgblog/2020.html#April_22_2020).
+
+A common solution is [connection pooling](https://supabase.com/docs/guides/database/connecting-to-postgres#how-connection-pooling-works). Supabase currently offers [pgbouncer](http://www.pgbouncer.org/) which is single-threaded, making it difficult to scale. We've seen some [novel ways](https://twitter.com/viggy28/status/1677674197664038912?s=12&t=_WCn3v_QJ7tkQLvOvkZkqg) to scale pgbouncer, but we have a [few other goals](https://github.com/supabase/supavisor#motivation) in mind for our platform.
+
+And so we've built [Supavisor](https://github.com/supabase/supavisor), a Postgres connection pooler that can handle millions of connections.
+
+## What is Supavisor?
+
+Supavisor is a scalable, cloud-native Postgres connection pooler. It has been developed with multi-tenancy in mind, handling millions of connections without significant overhead or latency. Supavisor is built in Elixir, in partnership with [José Valim](https://twitter.com/josevalim) (the creator of Elixir) and the [Dashbit](https://dashbit.co/) team.
+
+
+
+
+
+
+Supavisor will enable us to build some exciting new features for your Postgres cluster:
+
+- query caching
+- automatic read-replica load balancing
+- query blocking
+- and much more
+
+## Benchmarking 1 million connections
+
+We've benchmarked the characteristics Supavisor exhibits under load before rolling it out to our entire Postgres fleet. We tested how we can scale the cluster vertically and horizontally. These results have given us confidence that Supavisor is ready.
+
+### Setup
+
+We use a [custom load-testing application](https://github.com/supabase/benchmarks) to test the features of the Supabase platform. It consists of:
+
+1. Terraform scripts for creating a testing environment on AWS.
+2. k6 as the load generator. We used the k6 guides for [running large-scale tests](https://k6.io/docs/testing-guides/running-large-tests/) and [fine-tuning OS](https://k6.io/docs/misc/fine-tuning-os/) to tweak the config for AWS instances.
+3. Grafana + Prometheus for monitoring.
+
+To simulate 1,000,000 concurrent active connections, we used 20 AWS EC2 instances with 16 cores and 32GB of RAM. We ran the tests for up to 2 hours to ensure that the Supavisor can handle load over long periods.
+
+### Establishing a baseline
+
+In the first test, we set up a single ARM 16-core Supavisor instance on Ubuntu 22.04.2 aarch64 connected to one database instance.
+
+
+
+We wanted to assess the capacity of a single Supavisor instance. We achieved:
+
+- 250,000 concurrent connections to Supavisor
+- Supavisor was running with a pool of 400 direct connections to the database
+- The system was processing 20,000 queries per second (QPS)
+
+
+
+With this setup the database is the bottleneck - 20,000 QPS was the maximum this instance could handle. Increasing QPS would have been possible with a larger instance or read-replicas, but we wanted to focus on the scalability of Supavisor's connection limit (not Postgres's). Since Supavisor is built with multi-tenancy, addition of read-replicas is as easy as sending a single post request.
+
+
+
+
+
+
+### Supavisor's scaling capabilities
+
+In the next step, we focused on Supavisor's vertical scaling capabilities by connecting **500,000 concurrent users** with a 64-core Supavisor instance while the single database instance configuration remained the same.
+
+
+
+The system showed no signs of instability or performance degradation. QPS remained constant at 20,000, proving that an increased number of connections doesn't negatively affect Supavisor's overall performance (this is generally expected from a [BEAM-based language](https://stressgrid.com/blog/webserver_benchmark/) like Elixir).
+
+
+
+
+
+
+We also monitored how the load was distributed over Supavisor instance's cores:
+
+
+
+
+
+
+The load is spread evenly between all cores, which is great. CPU usage is high, signaling that the current setup has reached its capacity: a single Supavisor instance with 64 core handles around 500,000 connections. With this reference number, we moved on to horizontal scaling tests.
+
+### Scaling to 1,000,000 connections
+
+To examine horizontal scalability, we deployed two 64-core Supavisor instances, with the first instance connected directly to the database and the other relaying queries through the first.
+
+
+
+In the Supavisor architecture, only a single node holds direct connections to each database instance. When you add more Postgres databases or read-replicas, Supavisor spreads the connections to the replicas. Every Supavisor instance can accept incoming connections and either execute queries themselves (if they directly connected) or relay to another node (if not).
+
+This setup successfully handled:
+
+- **1,003,200 simultaneous connections** to the Supavisor instances.
+- **20,000 QPS** or **1.2 million queries per minute.** Each connection executed a `select` query once every 50 seconds.
+
+
+
+
+
+
+Within the cluster:
+
+- The directly connected instance was under almost the same load as when handling 500,000 concurrent clients in a single-node mode.
+- The relaying instance was extremely over-resourced. Most cores had little-to-no workload because relayed connections are more lightweight.
+
+
+
+
+
+
+In a multi-tenant setup (or when using Read-Replicas), the load is much more evenly spread because all Supavisor instances connect to comparable numbers of databases and have both direct and relayed connections evenly distributed between each other.
+
+
+
+### Supavisor's impact on query duration
+
+To measure the impact on query duration, we started with 5,000 queries per second. This allows us to exclude side effects from the database side (long query execution times).
+
+The query used in the experiment was the following:
+
+```sql
+select *
+from (
+ values
+ (1, 'one'),
+ (2, 'two'),
+ (3, 'three')
+) as t (num, letter);
+```
+
+We found with Supavisor median query duration was less than 2ms. And this includes not only time from client to Supavisor but the whole roundtrip: from Client to Supavisor ➡️ from Supavisor to Postgres ➡️ then query execution time on Postgres ➡️ and back to Supavisor ➡️ and to the Client.
+
+| | Query Duration |
+| ------ | -------------- |
+| Median | 2ms |
+| p95 | 3ms |
+| p99 | 23ms |
+
+
+
+
+
+
+We can see that 95% of queries were completed in less than 3 milliseconds. A slightly higher query duration at the beginning of the test can be explained by the dynamic nature of Supavisor-to-Database connection pool. It is being scaled up to the hard limit when more clients establish connections to Supavisor itself and scaled back down when users leave.
+
+We continued to scale up to 20,000QPS to assess the impact on query duration and measured a median of 18.4ms:
+
+| | Query Duration |
+| ------ | -------------- |
+| Median | 18.4ms |
+| p95 | 46.9ms |
+| p99 | 68ms |
+
+
+
+
+
+
+Database experiences much more load and more concurrent queries, which leads to higher execution times on the database side. And here are some metrics from the database side:
+
+
+
+The scalability can be further enhanced by adding more databases (or read-replicas if you want to scale a single app) to increase QPS or deploying additional Supavisor instances to accommodate tens of millions of concurrent connections.
+
+### Supavisor on Supabase Platform
+
+Additionally we compared current setup with pgbouncer and the new Supavisor setup on Supabase Platform in the cloud, so you will be aware how it may affect query duration.
+
+- Right now every Supabase project comes with its own pgbouncer instance, running on the same instance as the database to ensure that the latency is as low as possible. But this setup comes with a trade-off: it uses the same compute resources as your database.
+
+
+
+- With Supavisor, you connect to a distinct multi-tenant Supavisor cluster through load-balancer. This cluster maintains a connection pool to your database. In this case the pooler doesn't consume your database's CPU and RAM resources, but it does involve extra network communication.
+
+
+
+We were running 5,000 queries per second for each configuration, and at this time we decided to make an experiment with `insert` query. We also enabled PostGIS extension to store coordinates:
+
+```sql
+insert into positions (
+ stud_id,
+ first_name,
+ last_name,
+ title,
+ reports_to,
+ timestamp,
+ location,
+ email
+)
+values (
+ ${name},
+ 'Virtual ${name}',
+ 'User ${name}',
+ 'Load Tester',
+ 1,
+ ${Date.now()},
+ st_point(-73.946${x}, 40.807${y}),
+ 'vu${name}@acme.corp'
+);
+```
+
+We observed additional 2ms required for query to be executed for Supavisor cluster compared to PgBouncer running on the same machine as the database itself.
+
+| | Query Duration with Supavisor | Query Duration with PgBouncer |
+| ------ | ----------------------------- | ----------------------------- |
+| Median | 4ms | 1ms |
+| p95 | 4ms | 2ms |
+| p99 | 5ms | 3ms |
+
+
+
+
+ Fig.1 - Query Duration with Supavisor
+
+
+
+
+
+ Fig.2 - Query Duration with PgBouncer
+
+
+### Getting started
+
+Supavisor has been rolled out to all Supabase projects in all regions.
+
+Contact [support](https://www.notion.so/83ee995954214527986a8375156c9e6c?pvs=21) to start using it today, and we'll provide connection details. We will be exposing a new connection string in project dashboards over the next few weeks.
+
+You'll be able to use both PgBouncer and Supavisor for a few months in parallel. Nothing will change with your PgBouncer setup if you need to switch back.
+
+Supavisor will be added to the self-hosted stack as soon as we have tested it across our database fleet. That said - we're confident that it's ready for use if you want to try it with your own Postgres database. [Sequin](https://sequin.io/), one of our partners, has been using Supavisor for several months:
+
+
+
+ With Supavisor, we've been able to ship incredible features that would have been very hard to
+ build otherwise. For example, our customers can now read from and write to Salesforce and
+ HubSpot via Postgres. We achieve this by intercepting queries that route through Supavisor.
+
+
+ We chose Supavisor because it's scalable, multi-tenant, and written in Elixir. We were able to
+ integrate it easily with our own Elixir infrastructure. As partners, we look forward to helping
+ shape the future of Postgres connection pooling with Supabase.
+
+
+
+## Conclusion
+
+Supavisor's vertical and horizontal scaling ability make it the optimal solution for developers who aim to create applications that can effortlessly scale, even under extreme workloads, avoiding issues such as "too many connections" and enabling the full power of edge functions and serverless.
+
+If you are interested in exploring Supavisor's potential or want to implement its scalability in your upcoming project, check out [the GitHub repository](https://github.com/supabase/supavisor) to know more.
diff --git a/apps/www/components/LaunchWeek/8/Releases/LWAnnouncement.tsx b/apps/www/components/LaunchWeek/8/Releases/LWAnnouncement.tsx
index 5165d574340..9b9a07036c3 100644
--- a/apps/www/components/LaunchWeek/8/Releases/LWAnnouncement.tsx
+++ b/apps/www/components/LaunchWeek/8/Releases/LWAnnouncement.tsx
@@ -12,7 +12,7 @@ const LWAnnouncement = ({
title?: string
isLaunchWeekPage?: boolean
}) => {
- const [_pre, _d1, _d2, _d3, currentDay, _d5] = days
+ const [_pre, _d1, _d2, _d3, _d4, currentDay] = days
const announcement = (
<>
@@ -35,7 +35,7 @@ const LWAnnouncement = ({
/>
- {title ?? 'Launch Week 8: Day 4'}
+ {title ?? 'Launch Week 8: Day 5'}{currentDay.steps[0].title}
@@ -50,7 +50,7 @@ const LWAnnouncement = ({
{isLaunchWeekPage ? (
}
/>
diff --git a/apps/www/components/LaunchWeek/8/Releases/index.tsx b/apps/www/components/LaunchWeek/8/Releases/index.tsx
index 376952a1467..6a5405b2e3e 100644
--- a/apps/www/components/LaunchWeek/8/Releases/index.tsx
+++ b/apps/www/components/LaunchWeek/8/Releases/index.tsx
@@ -3,7 +3,13 @@ import Link from 'next/link'
import { Accordion } from 'ui'
import { useBreakpoint } from 'common/hooks/useBreakpoint'
-import { AccordionHeader, CartTitle, CheckCircleSolidIcon, SectionButtons } from './components'
+import {
+ AccordionHeader,
+ CartTitle,
+ CheckCircleSolidIcon,
+ MultistepSectionHeader,
+ SectionButtons,
+} from './components'
import SectionContainer from '~/components/Layouts/SectionContainer'
import days, { WeekDayProps } from './lw8_data'
@@ -457,22 +463,139 @@ export default function LW8Releases() {
)}
-