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:
- 1Function upload — You package your code and upload it to the platform
- 2Invocation — A trigger fires (HTTP request, timer, event)
- 3Container allocation — The platform allocates a container with your runtime
- 4Execution — Your function runs with the provided inputs
- 5Response — The output is returned to the caller
- 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
| Model | Provisioning | Scaling | Best For |
|---|---|---|---|
| FaaS | None | Automatic | Event-driven, HTTP endpoints |
| Containers | Some (Dockerfile) | Manual/auto | Long-running services |
| PaaS | Minimal | Platform-managed | Full-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.comComposing 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.