Serverless Functions for Website (AWS Lambda)

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
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:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815

Developing Serverless Functions for Website (AWS Lambda)

AWS Lambda — functions that run on event and don't need constantly running server. Pay only for actual execution time: first 1M requests monthly free, then $0.20 per 1M requests. Cold start is the only serious drawback, solved several ways.

When Lambda Fits for Website

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

Doesn't fit: long-lived connections (WebSocket needs separate service), tasks > 15 minutes, high-frequency DB operations without connection pooling.

Project Structure

my-lambda/
├── src/
│   ├── handlers/
│   │   ├── contact-form.ts
│   │   ├── image-resize.ts
│   │   └── webhook.ts
│   ├── services/
│   │   ├── email.ts
│   │   └── storage.ts
│   └── utils/
├── template.yaml          # SAM or serverless.yml
├── package.json
└── tsconfig.json

Example Function: Contact Form Processing

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://your-site.com",
    "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" }) };
  }
};

Deploy via AWS SAM

template.yaml:

AWSTemplateFormatVersion: "2010-09-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: your-site.com
npm run build
sam build
sam deploy --guided  # first deploy
sam deploy           # subsequent

Cold Start and Mitigation

Cold start on Node.js 20 — 200–500 ms. Python — 100–300 ms. After first call function stays "warm" minutes.

Mitigation ways:

  • Provisioned Concurrency — Lambda keeps N instances always warm. Costs ~$0.015 per hour per instance. For critical endpoints with SLA.
  • Reduce bundle size — use esbuild instead webpack, don't include aws-sdk in bundle (already in environment), tree-shaking.
  • SnapStart (Java) — snapshot state after initialization.
  • Warmer — EventBridge calls function every 5 minutes with warmup-payload.
// Initialization outside handler — executes once on cold start
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
};

Working with Database

Standard TCP connection to PostgreSQL/MySQL doesn't fit Lambda — each call creates new connection, at 1000 RPS database chokes.

Solutions:

  • RDS Proxy — connection pool before RDS, Lambda connects to proxy. +$0.015 per vCPU/hour RDS.
  • DynamoDB — no connections, natively serverless. For simple data structures.
  • PlanetScale / Neon — serverless-compatible databases with HTTP API.

Logging and Tracing

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 });
  // ...
});

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

Timeline

One Lambda function with SAM deploy — 1–2 days. Set of 5–7 functions with CI/CD via GitHub Actions and monitoring — 5–7 days.