Node.js
APIs, integrations and serverless workloads with careful async design.
- API architecture
- Async patterns
- Serverless
- Observability
I use AWS as part of real application architecture rather than as a collection of isolated services. My focus is choosing infrastructure based on workload, reliability, security, cost and operational complexity.
Serverless · S3 & DynamoDB · IAM · Cost awareness
How I think about it
I don't start architecture discussions by asking which AWS services we can use. I start with the workload, expected scale, reliability requirements, security needs and cost constraints.
Key experience
Scope
Deep dive
The right AWS architecture for a marketing site, an internal tool and a multi-tenant SaaS are completely different. So I start with questions. What is the traffic shape — steady, spiky or batch? What latency do users need? What happens if this component is down for ten minutes? Who operates it, and what is the budget?
The answers usually point to a small number of services used well, rather than a diagram with every service on it.
Lambda behind API Gateway or an event source is excellent for spiky and event-driven work — file processing, webhooks, scheduled tasks, lightweight APIs — because you pay per execution and don't patch servers.
The trade-offs are real: execution time and payload limits, cold starts that matter for some latency-sensitive endpoints, harder local debugging, and per-request costs that can exceed a small always-on server at sustained high volume. Long-running or stateful work often belongs in containers or queue-driven workers instead.
S3 is the default home for files: user uploads, generated exports, static assets. Buckets stay private; public delivery is the exception and usually goes through CloudFront.
For uploads, the backend issues short-lived presigned URLs so files go straight from the browser to S3 without passing through the application server. Lifecycle rules move or expire old objects, and keys include the tenant so access rules and clean-up stay simple.
DynamoDB rewards designing from access patterns: list the queries the application will run, then choose partition and sort keys so each one is a key lookup or a range query. Partition keys need enough spread to avoid hot partitions.
It's a strong fit for high-scale key-value access, session or event data and predictable query shapes. It's a poor fit when requirements are still moving, when you need ad-hoc reporting, or when the data is deeply relational — which describes many early-stage SaaS products.
For most business applications and SaaS products a relational database is the better default: transactions, joins, constraints, flexible queries and reporting. A managed relational database removes the work of backups, patching and failover. I'd rather start relational and move specific hot paths to specialised stores than force a relational domain into a key-value model.
Decoupling slow work from user requests is one of the highest-value architecture decisions. A queue between the API and its workers absorbs spikes, enables retries and lets each side scale independently. Messages must be safe to process more than once, and failures need a dead-letter destination someone actually looks at.
Every role gets only the permissions its workload needs, scoped to specific resources — not wildcards because they were quicker to write. Workloads use IAM roles and temporary credentials, never long-lived access keys in code. Human access to production is limited and auditable.
Configuration varies by environment; secrets never belong in source control. They live in a managed secret store or encrypted parameters, are injected at runtime, are rotated where possible, and never appear in logs.
Production visibility means structured application logs with request and tenant context, alarms on error rates and queue backlogs, and metrics that reflect the product — failed jobs, processing latency, failed payments — not just CPU. Logs have a cost too, so retention and verbosity are decisions, not defaults.
Cost follows architecture. I estimate it from expected usage before choosing a design, tag resources so spend can be attributed, set budgets and alerts, and remove infrastructure that exists only because someone might need it one day.
Serverless is not automatically cheapest. At sustained volume, a small always-on service can cost less — and data transfer, logging and idle resources often outweigh compute.
A pattern I favour for uploads that need processing — parsing, conversion, extraction: the client asks the API for a presigned URL, uploads directly to S3, the upload triggers asynchronous processing, and the results are stored and surfaced back to the user.
The API never handles the file bytes, processing can retry on its own, and the user isn't waiting on a long request.
Client
requests an upload
API
authorizes, issues presigned URL
S3
receives the file directly
Background processing
event or queue triggered
Results
stored, user notified
For SaaS, the infrastructure questions follow the product's: an API layer, a relational database for core data, S3 for files with tenant-prefixed keys, queues and workers for asynchronous jobs, CloudFront for static assets, and separate environments with CI/CD.
Multi-tenant workloads add noisy-neighbour concerns — one customer's large import shouldn't slow everyone else down — so heavy work goes through queues with per-tenant limits.
In practice
Real products
AWS sits underneath several products I've built, led or am building — in each case chosen around the product's workload rather than the other way round.
Accessibility Technology / SaaS
Large accessibility SaaS on AWS, including AWS Bedrock for AI features, where I lead delivery and production releases.
Enterprise SaaS
File collaboration platform on AWS, where storage and multi-user access were central to the architecture.
SaaS / Portfolio Builder
Portfolio SaaS I'm building as founder, with AWS as part of the architecture.
APIs, integrations and serverless workloads with careful async design.
Predictable API contracts: validation, errors, authorization, idempotency and webhooks.
Applied LLM engineering: structured output, validation, cost and security.
Tenancy, permissions, plans, billing and the realities of running SaaS in production.
Deploy, optimize, and maintain reliable cloud systems using AWS services and practical cloud architecture.
Learn moreDesign and build SaaS products from MVP to production, including architecture, user management, subscriptions, integrations and cloud infrastructure.
Learn moreBuild reliable web platforms, SaaS products, dashboards, APIs, and internal tools with modern full-stack technologies.
Learn moreWhether it's an architecture decision, a delivery problem or something specific to AWS, I can help you find a practical path forward.
What happens next
Share your goal
A few lines about the product, problem, or audit need.
Get a quick read
A practical reply on the best technical path forward.
Move forward
A clear scope, estimate, or concrete next step.