close
Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FastAPI Lambda with and without SnapStart

A website-performance API running on AWS Lambda. It is built with FastAPI and uses DuckDB to query website request logs stored as Parquet files in S3. Given a date range and an optional page, it returns request count, median and p95 response time, error count and error rate.

Loading DuckDB and FastAPI at startup makes cold starts slow, so this project measures what Lambda SnapStart does about it. The same API is deployed twice, once with SnapStart and once without, and the two are compared under identical conditions.

Article.md walks through the implementation and the results.

One AWS account containing two parallel paths: a user calls two API Gateway REST APIs, one without SnapStart and one with it, each invoking its own Lambda function, and both functions query the same website-requests Parquet files in S3 using DuckDB

Both functions deploy the same ZIP at 1024 MB. Only two things differ:

Handler SnapStart
web-perf-without-snapstart app.lambda_handler off
web-perf-with-snapstart app_snapstart.lambda_handler on published versions

Prerequisites

Every command below is bash and assumes Linux.

  • Python 3.12 with venv
  • Node.js 22 or newer. The CDK CLI is a Node package, and even a Python CDK app spawns node through jsii, so without it cdk synth fails with FileNotFoundError: [Errno 2] No such file or directory: 'node'. Distro packages are often too old; jsii warns on Node 20 and below, so install from NodeSource or nvm
  • Docker, running, with your user in the docker group. The bundler builds the Linux DuckDB wheel and bakes in the signed httpfs and aws extensions, so the functions never download extensions at startup
  • AWS credentials, the CDK CLI (npm install -g aws-cdk), and a bootstrapped CDK environment

On Debian or Ubuntu, once Node is installed:

sudo apt install python3.12 python3.12-venv docker.io
sudo usermod -aG docker "$USER"   # log out and back in for this to apply

Setup

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r cdk/requirements.txt -r tests/requirements.txt

Keep the virtualenv active for everything below. cdk.json runs python app.py, so cdk deploy fails with ModuleNotFoundError: No module named 'aws_cdk' if it is not.

Deploy

cd cdk

cdk bootstrap   # once per account and Region
cdk deploy

cd ..

The stack name defaults to python-snapstart-comparison-cdk. Override it with cdk deploy -c stackName=my-stack-name.

The SnapStart version stays Pending while Lambda initializes it and builds the snapshot, so this deploy is slower than a normal one.

Upload sample data

Generate four Parquet files holding 250,000 synthetic requests, then sync them to the bucket the stack created:

python scripts/generate_sample_data.py \
  --output .tmp/website-data \
  --rows 250000 \
  --files 4

BUCKET=$(aws cloudformation describe-stacks \
  --stack-name python-snapstart-comparison-cdk \
  --query "Stacks[0].Outputs[?OutputKey=='WebsiteDataBucketName'].OutputValue | [0]" \
  --output text)

aws s3 sync .tmp/website-data "s3://$BUCKET/website-requests/"

Call it

Both API URLs are in the stack outputs and already include the prod stage:

GET .../prod/health
GET .../prod/analytics/website?from_date=2026-08-01&to_date=2026-08-12&page=/search

Dates and the page are bound as SQL parameters. The S3 URI comes from the function's environment, so a caller cannot point DuckDB at another bucket.

Run the tests

python -m pytest

They write temporary local Parquet files and query them with the same class Lambda uses, so no AWS credentials are needed.

Layout

  • src/app.py — FastAPI app, DuckDB connection, S3 auth and the SQL. No SnapStart code
  • src/app_snapstart.py — imports app, registers the after-restore hook, re-exports the handler
  • cdk/ — bucket, both functions, versions, aliases, REST APIs, roles, log groups and outputs
  • scripts/generate_sample_data.py — Parquet generator
  • tests/ — query, validation, adapter, SnapStart hook and CDK assertions

Cleanup

cd cdk
cdk destroy

The bucket has a RETAIN policy, so empty and delete it yourself when you no longer need the data.

Every published SnapStart version keeps a cached snapshot that is billed for at least three hours, so delete versions you are done with.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages