Building a SaaS Booking Platform with 106 Lambda Functions
The Challenge
Building a modern booking platform means handling a lot of moving parts: appointment scheduling, staff availability, customer management, payments, notifications, calendar sync, analytics, and compliance. Most teams reach for a monolithic framework — Django, Rails, or Spring Boot — deployed on EC2 or ECS.
We went fully serverless. Every feature is a Lambda function. Every infrastructure component is managed by AWS. The result: zero servers to patch, automatic scaling, and an infrastructure cost that scales linearly with actual usage.
Why 106 Lambda Functions?
The number sounds extreme until you break it down. Each Lambda handles exactly one API operation — one HTTP method on one endpoint. This isn't accidental complexity; it's a deliberate architectural decision with real benefits:
Minimal cold starts. Each function package is small — just the code for that specific operation plus shared layers. Cold starts stay under 500ms even with VPC attachment.
Precise IAM permissions. The appointment-creation Lambda can write to the appointments table. It cannot read billing data. It cannot access customer exports. Least-privilege is enforced at the function level, not through application-level checks.
Independent deployments. Updating the notification logic doesn't require redeploying the billing system. Each function can be tested and deployed in isolation.
Cost efficiency. You pay only for the milliseconds each function runs. No idle EC2 instances. No over-provisioned containers.
The Architecture
The platform is organized into five layers:
Entry Layer — CloudFront serves the React SPA from S3 and routes API calls to API Gateway. Every request passes through a JWT Authorizer Lambda before reaching business logic.
Core — 106 Lambda functions in a VPC private subnet, organized across 20+ service modules: Auth, Appointments, Availability, Staff, Services, Customers, Business, Locations, Billing, Calendar, Campaigns, Forms, Reviews, Waitlist, Analytics, GDPR, Dashboard, Admin, and System.
Data Layer — RDS PostgreSQL in the private subnet for relational data, S3 for photos and assets, SQS FIFO queues for notification processing.
Notification Layer — Asynchronous messaging through SQS with processors that dispatch to SES (email) and WhatsApp. Includes scheduled reminders at 2 hours and 24 hours before appointments.
Operations — Secrets Manager for credentials, EventBridge for scheduled tasks, CloudWatch for monitoring all 106 functions, SNS for alerting.
Notifications Done Right
Notifications in a booking platform are critical — a missed reminder means a no-show, which costs the business money. We built a multi-channel notification system:
- When an appointment is created, a message goes into the SQS FIFO queue
- The notification processor Lambda picks it up with exactly-once delivery
- Based on customer preferences, it dispatches via SES (email) or WhatsApp
- EventBridge triggers reminder Lambdas at scheduled intervals before the appointment
- Failed notifications land in a dead-letter queue for investigation — nothing gets silently dropped
FIFO queues ensure a customer never receives the same confirmation twice. The DLQ ensures no notification is lost.
Stripe Integration
Full payment lifecycle handled serverlessly:
- Checkout Sessions — create Stripe checkout for subscription signup
- Customer Portal — self-service billing management
- Webhook Processing — Lambda processes Stripe events (payment succeeded, subscription cancelled, trial expiring)
- Trial Management — EventBridge triggers daily checks for expiring trials
All Stripe secrets are stored in Secrets Manager — never in environment variables or code.
Google Calendar Sync
Two-way calendar integration:
- Business owners connect their Google Calendar via OAuth
- New appointments automatically appear in their calendar
- Changes sync bidirectionally — cancel in the platform, it disappears from Google Calendar
- Dedicated Lambdas handle the OAuth flow: connect, callback, sync, and disconnect
Infrastructure as Code
Seven CDK stacks define the entire platform — from VPC networking to CloudWatch alarms. Every resource is version-controlled, reproducible, and deployable with a single command.
The entire VPC is defined in CDK — subnets, security groups, VPC endpoints, and NAT Gateway — all reproducible across environments.
What We Learned
Lambda layers save deployment time. Shared dependencies (database connectors, JWT utilities, notification formatters) live in Lambda layers. Updating a layer updates all 106 functions at once without redeploying each one.
VPC endpoints are essential for serverless. Without them, Lambdas in a private subnet can't reach S3, Secrets Manager, or SQS. Gateway endpoints (S3) are free; interface endpoints cost a few dollars per month but eliminate the need for a NAT Gateway in non-production environments.
FIFO SQS with content-based deduplication is ideal for notifications. Standard queues risk duplicate delivery. FIFO with deduplication guarantees exactly-once processing with zero application-level dedup logic.
Multi-tenant architecture should be designed from day one. Retrofitting tenant isolation into a running system is painful. We built it into the database schema, API authorization, and data access patterns from the start.
This platform was designed and built by NG Solutions. Need a serverless SaaS platform? Get in touch.