惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
宝玉的分享
宝玉的分享
I
InfoQ
P
Privacy International News Feed
V
V2EX
IT之家
IT之家
S
SegmentFault 最新的问题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V2EX - 技术
V2EX - 技术
C
CERT Recently Published Vulnerability Notes
C
Check Point Blog
The Register - Security
The Register - Security
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
AWS News Blog
AWS News Blog
M
MIT News - Artificial intelligence
C
Cyber Attacks, Cyber Crime and Cyber Security
F
Fortinet All Blogs
B
Blog
N
Netflix TechBlog - Medium
B
Blog RSS Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
T
Threatpost
Forbes - Security
Forbes - Security
U
Unit 42
A
Arctic Wolf
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Palo Alto Networks Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recorded Future
Recorded Future
L
Lohrmann on Cybersecurity
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
月光博客
月光博客
Spread Privacy
Spread Privacy
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
I
Intezer
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
The Hacker News
The Hacker News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LangChain Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
MyScale Blog
MyScale Blog
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
量子位

Blog — PlanetScale

Keeping a Postgres queue healthy — PlanetScale Patterns for Postgres Traffic Control — PlanetScale Graceful degradation in Postgres — PlanetScale High memory usage in Postgres is good, actually — PlanetScale Stripe Projects partnership: Provision PlanetScale Postgres and MySQL databases from the Stripe CLI — PlanetScale Enhanced tagging in Postgres Query Insights — PlanetScale Behind the scenes: How Database Traffic Control works — PlanetScale Introducing Database Traffic Control — PlanetScale Scaling Postgres connections with PgBouncer — PlanetScale Drizzle joins PlanetScale — PlanetScale Video Conferencing with Postgres — PlanetScale Faster PlanetScale Postgres connections with Cloudflare Hyperdrive — PlanetScale Introducing the PlanetScale MCP server — PlanetScale Database Transactions — PlanetScale Automating our changelog with Cursor commands — PlanetScale Postgres 18 is now available — PlanetScale Using MotherDuck with PlanetScale — PlanetScale $50 PlanetScale Metal is GA for Postgres — PlanetScale AI-Powered Postgres index suggestions — PlanetScale $5 PlanetScale is live — PlanetScale Announcing Vitess 23 — PlanetScale $50 PlanetScale Metal — PlanetScale Report on our investigation of the 2025-10-20 incident in AWS us-east-1 — PlanetScale $5 PlanetScale — PlanetScale Benchmarking Postgres 17 vs 18 — PlanetScale Larger than RAM Vector Indexes for Relational Databases — PlanetScale Partnering with Cloudflare to bring you the fastest globally distributed applications — PlanetScale Processes and Threads — PlanetScale PlanetScale for Postgres is now GA — PlanetScale Postgres High Availability with CDC — PlanetScale Announcing Neki — PlanetScale Caching — PlanetScale The principles of extreme fault tolerance — PlanetScale Announcing PlanetScale for Postgres — PlanetScale Benchmarking Postgres — PlanetScale Announcing Vitess 22 — PlanetScale The Real Failure Rate of EBS — PlanetScale IO devices and latency — PlanetScale Announcing PlanetScale Metal — PlanetScale PlanetScale Metal: There’s no replacement for displacement — PlanetScale Upgrading Query Insights to Metal — PlanetScale Automating cherry-picks between OSS and private forks — PlanetScale Database Sharding — PlanetScale Anatomy of a Throttler, part 3 — PlanetScale Introducing sharding on PlanetScale with workflows — PlanetScale Announcing Vitess 21 — PlanetScale Announcing the PlanetScale vectors public beta — PlanetScale Anatomy of a Throttler, part 2 — PlanetScale Instant deploy requests — PlanetScale Anatomy of a Throttler, part 1 — PlanetScale Increase IOPS and throughput with sharding — PlanetScale Tracking index usage with Insights — PlanetScale Faster backups with sharding — PlanetScale Building data pipelines with Vitess — PlanetScale The State of Online Schema Migrations in MySQL — PlanetScale Optimizing aggregation in the Vitess query planner — PlanetScale Dealing with large tables — PlanetScale Announcing Vitess 20 — PlanetScale Self-managed Vitess vs Managed Vitess with PlanetScale — PlanetScale Achieving data consistency with the consistent lookup Vindex — PlanetScale The MySQL adaptive hash index — PlanetScale Introducing global replica credentials — PlanetScale Profiling memory usage in MySQL — PlanetScale Summer 2023: Fuzzing Vitess at PlanetScale — PlanetScale How PlanetScale makes schema changes — PlanetScale Identifying and profiling problematic MySQL queries — PlanetScale The Problem with Using a UUID Primary Key in MySQL — PlanetScale Announcing Vitess 19 — PlanetScale PlanetScale forever — PlanetScale Introducing schema recommendations — PlanetScale Amazon Aurora Pricing: The many surprising costs of running an Aurora database — PlanetScale Three common MySQL database design mistakes — PlanetScale OAuth applications are now available to everyone — PlanetScale Deprecating the Scaler plan — PlanetScale PlanetScale branching vs. Amazon Aurora blue/green deployments — PlanetScale Databases at scale — PlanetScale Considerations for building a database disaster recovery plan — PlanetScale Working with Geospatial Features in MySQL — PlanetScale PlanetScale vs Amazon Aurora replication — PlanetScale Introducing the Vantage and PlanetScale integration — PlanetScale MySQL isolation levels and how they work — PlanetScale Introducing the schemadiff command line tool — PlanetScale $ pscale ping — PlanetScale Announcing foreign key constraints support — PlanetScale The challenges of supporting foreign key constraints — PlanetScale What is HTAP? — PlanetScale Introducing Insights Anomalies — PlanetScale Webhook security: a hands-on guide — PlanetScale Announcing the Fivetran integration — PlanetScale Introducing webhooks — PlanetScale What is MySQL replication and when should you use it? — PlanetScale Sync user data between Clerk and a PlanetScale MySQL database — PlanetScale Introducing database reports — PlanetScale Distributed caching systems and MySQL — PlanetScale What is MySQL partitioning? — PlanetScale MySQL High Availability: Connection handling and concurrency — PlanetScale Personalizing your onboarding with Markdoc — PlanetScale PlanetScale vs. Amazon Aurora — PlanetScale PlanetScale vs. Amazon RDS — PlanetScale PlanetScale is bringing vector search and storage to MySQL — PlanetScale
Using PlanetScale with Serverless Framework Node applications on AWS — PlanetScale
Matthieu Napoli · 2023-06-14 · via Blog — PlanetScale

Matthieu Napoli |

The Serverless Framework is great for building Node applications on AWS Lambda. The only thing missing is a serverless database. In this article, we will explore how to use PlanetScale as the database for a serverless Node application.

Prerequisites

Before deploying to AWS Lambda, you will need:

  • an AWS account (to create one, go to aws.amazon.com and click Sign up),
  • the serverless CLI installed on your computer.

Note

While the example of this article should stay under the AWS free tier (1 million free AWS Lambda invocations per month), be advised that building on AWS can incur costs.

You can install the serverless CLI using NPM:

npm install -g serverless

If you don't have NPM or want to learn more, read the Serverless documentation.

Now connect the serverless CLI to your AWS account via AWS access keys. Create AWS access keys by following this guide, then set them up on your computer using the following command:

serverless config credentials --provider aws --key <key> --secret <secret>

Creating a new serverless Node application

Serverless Framework is a CLI tool that helps us create and deploy serverless applications. Its configuration is stored in a serverless.yml file, which describes what will be deployed to AWS.

To deploy a Node application, we can create a simple serverless.yml file:

service: demo # name of the application

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1

functions:
  api:
    handler: index.handler
    url: true

In the configuration above, we define a single AWS Lambda function called api, running NodeJS 18, with a public URL.

Our API handler will be a handler() function returned by index.js (learn more about handlers in the AWS Lambda documentation). Let's create the index.js file:

export async function handler(event) {
  return {
    hello: 'world'
  }
}

Note that we will be using ESM features (like export and import), so let's create a package.json file with "type": "module":

Our simple Node example is ready to be deployed with serverless deploy, but let's add PlanetScale into the mix first!

Connecting to PlanetScale

In your PlanetScale account, start by creating a database in the same region as the AWS application (us-east-1 in our example). Then, click the Connect button and select "Connect with: @planetscale/database". That will let us retrieve the database username and password.

To connect to the database in our code, we will use the PlanetScale serverless driver. Let's install it with NPM:

npm install @planetscale/database

Now that the driver is installed, we can connect to our PlanetScale database with the connect() function:

import { connect } from '@planetscale/database'

const conn = connect({
  // With the serverless driver, the host is always 'aws.connect.psdb.cloud'
  host: 'aws.connect.psdb.cloud',
  username: '<user>',
  password: '<password>'
})

export async function handler(event) {
  const result = await conn.execute('SELECT * FROM records')

  return result.rows
}

Note the following details:

  • We are connecting to the database outside the handler() function. This is to reuse the same connection for all HTTP requests. If we were to connect inside the handler() function, a new connection would be created for each request, which would be inefficient.
  • We are querying the records table. This table doesn't exist yet, we will create it below.
  • We don't want to store the database credentials in the code. We will use environment variables instead.

Let's update our code to use environment variables. For the sake of the example, we will also create the records table on the fly:

import { connect } from '@planetscale/database'

const conn = connect({
  // With the serverless driver, the host is always the same
  host: 'aws.connect.psdb.cloud',
  username: process.env.DATABASE_USERNAME,
  password: process.env.DATABASE_PASSWORD
})

// Create the table if it doesn't exist (just for demo purposes)
// In a real application, we would run database migrations outside the function
await conn.execute('CREATE TABLE IF NOT EXISTS records (id INT PRIMARY KEY auto_increment, name VARCHAR(255))')

export async function handler(event) {
  // Insert a new record
  const queryParameter = event.queryStringParameters?.name ?? 'test'
  await conn.execute('INSERT INTO records (name) VALUES (?)', [queryParameter])

  // Retrieve all records
  const result = await conn.execute('SELECT * FROM records')

  return result.rows
}

We now need to set the DATABASE_USERNAME and DATABASE_PASSWORD environment variables. We can define them in serverless.yml and use AWS SSM to store the database password securely:

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  environment:
    DATABASE_USERNAME: <username-here>
    DATABASE_PASSWORD: ${ssm:/planetscale/db-password}

The database password will be stored in AWS SSM (at no extra cost) so it is not visible in the code. The ${ssm:/planetscale/db-password} variable will retrieve the value from SSM on deployment. The SSM parameter can be created with the AWS CLI via the following command:

aws ssm put-parameter --region us-east-1 --name '/planetscale/db-password' --type SecureString --value 'replace-me'

# replace the `replace-me` string with the database password!

If you don't use the AWS CLI, you can also create the parameter in the AWS Console:

Create SSM parameter

Our application is now ready! Let's deploy it:

When finished, the deploy command will display the URL of our Node application. The URL should look like this: https://<id>.lambda-url.us-east-1.on.aws/. We can open it in the browser or request it with curl:

curl https://<id>.lambda-url.us-east-1.on.aws/

The response should list the records in the records table. A new record will be created every time the URL is requested. We can also provide a name parameter to change the name of the record inserted in the database:

curl https://<id>.lambda-url.us-east-1.on.aws/?name=hello

Stage parameters

Besides the incredible scalability provided by the combination of AWS Lambda and PlanetScale, another benefit we get from this setup is the ability to combine Serverless Framework stages and PlanetScale branches.

We could imagine, for example, a dev stage for development and a prod stage for production. The dev stage would use a development branch in PlanetScale, while the prod stage would use the main production branch.

Using stage parameters, we can set different credentials to use to connect to PlanetScale depending on the stage:

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  environment:
    DATABASE_USERNAME: ${param:dbUser}
    DATABASE_PASSWORD: ${param:dbPassword}

params:
  dev:
    dbUser: <dev-username-here>
    dbPassword: ${ssm:/planetscale/dev/db-password}
  prod:
    dbUser: <prod-username-here>
    dbPassword: ${ssm:/planetscale/prod/db-password}

When deploying, we can specify the stage to deploy via the --stage option:

serverless deploy --stage dev

serverless deploy --stage prod

Each stage (dev and prod) will result in entirely separate infrastructures on AWS, and each one will use its own PlanetScale branch.

That setup makes it easy to test code changes and database schema changes in a development environment that is identical to and isolated from the production environment. Once approved, schema changes can be applied to the production branch with a PlanetScale deploy request, and code changes can be deployed to production via the serverless deploy command.

Next steps

In this article, we learned how to integrate PlanetScale with Node applications built using the Serverless Framework on AWS. This gives us a completely serverless stack with extreme scalability yet simple to set up and maintain.

Now that we have a basic application running we can explore more complex topics, such as:

Feel free to explore the PlanetScale documentation as well as the Serverless Framework documentation to learn more.