Serverless Functions for Your Website: AWS Lambda

Contact Form Processing with AWS Lambda

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1026
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

Contact Form Processing with AWS Lambda

Contact form on a React site with 2000+ submissions per day started failing: response came after 30 seconds, emails were lost. The old monolithic EC2 instance couldn't handle the spikes. We replaced it with AWS Lambda — response time dropped to 300 ms, cost per form submission — fractions of a cent. Serverless architecture eliminates server management: you focus on the code, and AWS scales the load. However, cold start and database operations require careful design. We'll cover typical scenarios, show code, and provide ready-made solutions. To evaluate your project, contact our certified AWS engineers with 12+ years of experience and 80+ serverless projects delivered.

Lambda vs EC2: When to Use Which

Lambda is efficient for asynchronous and episodic tasks. Here's a comparison with a classic EC2 server:

Criteria AWS Lambda AWS EC2
Server management Not required Full management
Scaling Automatic Manual / Autoscaling
Cold start 100–500 ms None
Price Per execution Per uptime
Time limit 15 minutes Unlimited

Suitable for: contact form processing, on-demand PDF/image generation, webhooks from payment systems and CRM, image resizing on upload, task schedulers (cron via EventBridge), API proxies for third-party services.

Not suitable for: long-lived connections (WebSocket requires a separate service), tasks exceeding 15 minutes, high-frequency DB operations without connection pooling. In such cases, Lambda becomes not only more expensive but also slower: at 5000 req/s, EC2 with autoscaling costs less than Provisioned Concurrency.

Why Lambda Is More Cost-Effective

From a cost perspective, Lambda wins under uneven load. On EC2, you pay for a running server 24/7, even if it processes requests once per hour. Lambda charges per invocation — savings on idle time can reach 90%. The official AWS documentation gives an example: a site with 10,000 requests per day on EC2 t3.micro costs ~$8/month, while Lambda costs $0.05 for the same workload — a 99% reduction. Additionally, you avoid configuring autoscaling, patching the OS, and monitoring. Our clients save up to 70% on infrastructure by moving to Lambda.

How Lambda Processes a Form: Code Example

A contact form on a React site sends a POST request to API Gateway, which triggers a Lambda function. The function validates data with Zod and sends an email via SES. Code:

import { APIGatewayProxyHandler } from "aws-lambda"; import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses"; import { z } from "zod"; const ses = new SESClient({ region: "eu-west-1" }); const ContactSchema = z.object({ name: z.string().min(2).max(100), email: z.string().email(), message: z.string().min(10).max(2000), }); export const handler: APIGatewayProxyHandler = async (event) => { const headers = { "Access-Control-Allow-Origin": "https://www.example.org", "Content-Type": "application/json", }; try { const body = JSON.parse(event.body || "{}"); const data = ContactSchema.parse(body); await ses.send(new SendEmailCommand({ Source: "[email protected]", Destination: { ToAddresses: ["[email protected]"] }, Message: { Subject: { Data: `New message from ${data.name}` }, Body: { Text: { Data: `From: ${data.name} <${data.email}>\n\n${data.message}` } } } })); return { statusCode: 200, headers, body: JSON.stringify({ ok: true }) }; } catch (error) { if (error instanceof z.ZodError) { return { statusCode: 400, headers, body: JSON.stringify({ errors: error.errors }) }; } console.error(error); return { statusCode: 500, headers, body: JSON.stringify({ error: "Internal error" }) }; } }; 

Optimizing Lambda Performance

How to Reduce Cold Start?

Cold start is the initialization latency after a long idle period. On Node.js 20 it's 200–500 ms, on Python 100–300 ms. If sub-second response time is critical, use one of these methods:

Method Description Additional cost
Provisioned Concurrency N pre-warmed instances $0.015 per instance/hour
esbuild + tree-shaking Reduce bundle size Free
SnapStart (Java) Snapshot after initialization Free
Ping requests EventBridge every 5 minutes Negligible

Example of initializing clients outside the handler (executed once):

const dbClient = new DynamoDBClient({ region: "eu-west-1" }); const sesClient = new SESClient({ region: "eu-west-1" }); export const handler = async (event) => { // handler uses already initialized clients }; 

Common Developer Mistakes

  • Overly large bundle: including all dependencies without tree-shaking increases cold start by 200–500 ms.
  • Creating clients inside the handler: each invocation creates a new DB connection — leads to N+1 problem.
  • Ignoring timeout limits: if the function runs longer than timeout (max 15 min), it fails.
  • Lack of error handling: uncaught exceptions lead to retries and additional costs.

How to Connect Lambda to a Database?

Standard TCP connection to PostgreSQL/MySQL in Lambda creates a new connection per invocation — at 1000 RPS, the database chokes. Solutions:

Solution Features Price
RDS Proxy Connection pool in front of RDS +$0.015 per vCPU/hour
DynamoDB Native serverless, no connections Per request
PlanetScale / Neon Serverless DB with HTTP API Pay per use

For a high number of concurrent invocations, RDS Proxy can become a bottleneck — in such cases, migrate to DynamoDB or shard the database.

Deployment and Monitoring

Development and Deployment Process

  1. Design: define triggers, IAM roles, timeouts, and memory.
  2. Development: write the function in TypeScript with validation and error handling.
  3. Local testing: run with SAM CLI or Docker with API Gateway emulation.
  4. Build: use esbuild for bundling (tree-shaking, minification).
  5. Deploy: via AWS SAM (template.yaml) — first sam deploy --guided, then sam deploy.
  6. Monitoring: set up CloudWatch dashboards, alerts for errors and execution time.

We use AWS Serverless Application Model (SAM) documentation for infrastructure as code. Example template.yaml:

AWSTemplateFormatVersion: "2010-10-09" Transform: AWS::Serverless-2016-10-31 Globals: Function: Runtime: nodejs20.x Timeout: 10 MemorySize: 256 Environment: Variables: NODE_ENV: production Resources: ContactFormFunction: Type: AWS::Serverless::Function Properties: Handler: dist/handlers/contact-form.handler Events: Api: Type: HttpApi Properties: Path: /contact Method: POST Policies: - SESCrudPolicy: IdentityName: example.org 

Commands:

npm run build sam build sam deploy --guided sam deploy 

Logging and Tracing

AWS Lambda Powertools is the official library for structured logging, tracing via X-Ray, and metrics via CloudWatch EMF.

import { Logger } from "@aws-lambda-powertools/logger"; import { Tracer } from "@aws-lambda-powertools/tracer"; const logger = new Logger({ serviceName: "contact-form" }); const tracer = new Tracer({ serviceName: "contact-form" }); export const handler = tracer.captureLambdaHandler(async (event) => { logger.addContext(context); logger.info("Processing contact form", { email: event.body?.email }); // ... }); 

Our Services

What's Included in Our Work

  • Architectural design: choose triggers, balance cold start
  • Develop functions in TypeScript with validation and error handling
  • Set up CI/CD via GitHub Actions: build, tests, deploy
  • API documentation and infrastructure description
  • Monitoring: CloudWatch dashboards, alerts for errors and execution time
  • Team training: code review, maintenance guide

Timeline

A single Lambda function with SAM deployment — 1–2 days. A set of 5–7 functions with CI/CD and monitoring — 5–7 days. Our engineers have 12+ years of AWS experience and have delivered 80+ serverless projects. Exact timelines depend on integrations. Get a consultation on the solution architecture — we'll prepare a detailed turnkey proposal.