Back to Blog
Guide8 min read2026-05-01

Function as a Service (FaaS): Complete Guide for Developers

Function as a Service (FaaS) is the foundation of modern serverless architecture — this guide explains how it works, when to use it, and how to deploy your first function.

What Is Function as a Service?

Function as a Service (FaaS) is a cloud execution model where individual functions — small, focused units of code — are deployed and executed on-demand without managing servers. You write a function, upload it to a platform, and the platform handles provisioning, scaling, and billing.

FaaS is the technical foundation of what most people call "serverless." The serverless umbrella also includes managed databases and storage, but FaaS is the compute layer that makes it possible to run backend logic without a standing server.

The FaaS Execution Model

Understanding how FaaS platforms execute code helps you write better functions:

  1. 1Function upload — You package your code and upload it to the platform
  2. 2Invocation — A trigger fires (HTTP request, timer, event)
  3. 3Container allocation — The platform allocates a container with your runtime
  4. 4Execution — Your function runs with the provided inputs
  5. 5Response — The output is returned to the caller
  6. 6Container recycling — The container may be kept warm or destroyed

The container may persist briefly between invocations (warm start) or be created fresh (cold start). This distinction has performance implications covered in our cold start guide.

FaaS Runtimes and Language Support

FaaS platforms vary in the runtimes they support. PandaStack's edge functions, powered by Apache OpenWhisk, support Node.js and Python — the two most common languages for web backend work.

Node.js function:

// transform.js — format currency values in an array
const main = (params) => {
  const { values, currency = 'USD', locale = 'en-US' } = params;

  if (!Array.isArray(values)) {
    return { statusCode: 400, body: JSON.stringify({ error: 'values must be an array' }) };
  }

  const formatter = new Intl.NumberFormat(locale, { style: 'currency', currency });
  const formatted = values.map(v => formatter.format(v));

  return {
    statusCode: 200,
    body: JSON.stringify({ formatted })
  };
};

module.exports = { main };

Python function:

# transform.py — transform and filter a dataset
import json

def main(params):
    items = params.get('items', [])
    min_value = params.get('min_value', 0)

    if not isinstance(items, list):
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'items must be a list'})
        }

    filtered = [item for item in items if item.get('value', 0) >= min_value]
    total = sum(item.get('value', 0) for item in filtered)

    return {
        'statusCode': 200,
        'body': json.dumps({'filtered': filtered, 'total': total, 'count': len(filtered)})
    }

FaaS vs Containers vs PaaS

ModelProvisioningScalingBest For
FaaSNoneAutomaticEvent-driven, HTTP endpoints
ContainersSome (Dockerfile)Manual/autoLong-running services
PaaSMinimalPlatform-managedFull-stack applications

PandaStack supports all three models. Use FaaS (edge functions) for lightweight HTTP logic, containers for your main application services, and PandaStack's managed databases for your data layer.

Building a FaaS-Backed API

Here is a realistic pattern: a FaaS function that validates an email, checks a database, and returns a result.

// checkEmail.js
const dns = require('dns').promises;

const isValidFormat = (email) => /^[^s@]+@[^s@]+.[^s@]+$/.test(email);

const main = async (params) => {
  const { email } = params;

  if (!email) {
    return { statusCode: 400, body: JSON.stringify({ error: 'email required' }) };
  }

  if (!isValidFormat(email)) {
    return { statusCode: 200, body: JSON.stringify({ valid: false, reason: 'invalid_format' }) };
  }

  const domain = email.split('@')[1];
  try {
    await dns.resolveMx(domain);
    return { statusCode: 200, body: JSON.stringify({ valid: true, domain }) };
  } catch {
    return { statusCode: 200, body: JSON.stringify({ valid: false, reason: 'no_mx_record' }) };
  }
};

module.exports = { main };

Deploying FaaS Functions on PandaStack

# Install the PandaStack CLI
npm install -g @pandastack/cli

# Authenticate
panda login

# Deploy a Node.js function
panda functions deploy ./checkEmail.js --name check-email --runtime nodejs

# Deploy a Python function
panda functions deploy ./transform.py --name transform-data --runtime python

# Invoke and test
panda functions invoke check-email --param email test@example.com

Composing FaaS Functions

Complex workflows often require chaining functions. One function can call another via HTTP:

// orchestrator.js
const https = require('https');

const invoke = (fnUrl, payload) => new Promise((resolve, reject) => {
  const body = JSON.stringify(payload);
  const req = https.request(fnUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Content-Length': body.length }
  }, (res) => {
    let data = '';
    res.on('data', chunk => data += chunk);
    res.on('end', () => resolve(JSON.parse(data)));
  });
  req.on('error', reject);
  req.write(body);
  req.end();
});

const main = async (params) => {
  const validated = await invoke(process.env.VALIDATE_FN_URL, { email: params.email });
  if (!validated.valid) return { statusCode: 400, body: JSON.stringify(validated) };

  const result = await invoke(process.env.PROCESS_FN_URL, { email: params.email });
  return { statusCode: 200, body: JSON.stringify(result) };
};

module.exports = { main };

Conclusion

FaaS is the cleanest way to ship backend logic without operational overhead. Define the function, deploy it, and call it over HTTP. PandaStack makes this straightforward with CLI deployment and a unified dashboard at dashboard.pandastack.io. Read the full documentation at docs.pandastack.io.

Ready to deploy?

Start free on PandaStack — no credit card required.

Start free on PandaStack

More in Guide

Browse all Guide articles →

See also