# Serverless Function

> Runs your code per request with no box to pay for: nothing while it idles, a cold start when it has, and 1,000 executions at once.

The Serverless Function runs your code per request, with no box of your own, as AWS Lambda, Google Cloud Functions, and Azure Functions do.

## When to place it

- Place it when traffic is spiky. It unlocks with [Serverless](https://wiki.playquorum.dev/research/serverless.md) in Series A, for 3,500 ◇, and has no placement cost.
- Place it when one endpoint needs its own capacity without a second box.
- Skip it for steady load above about 30% utilization of an equal VM, where it costs more than the VM.
- Skip it for long `job` work. That belongs on a [Worker](https://wiki.playquorum.dev/components/worker.md) behind a [Queue](https://wiki.playquorum.dev/components/queue.md).

## How it works

It takes every request kind and answers it the way an [App Server](https://wiki.playquorum.dev/components/server.md) does, turning it into the backend calls it makes. It runs your Service's Stack, so its runtime decides how fast a request runs and how long a cold start takes. There is no instance type and no size to pick.

It differs from an App Server in three ways:

- **It bills per use.** Nothing stands while it idles. Each request pays a request price plus a price for the GB-seconds its execution ran, and the whole bill lands on the Requests line of the [cloud bill](https://wiki.playquorum.dev/design/09-economy.md#the-cloud-bill). A slow call to the Database makes each execution longer, so the bill rises with the data tier's latency.
- **It scales from zero to a cap.** One execution environment holds one request at a time, so the function serves as many requests a second as 1,000 concurrent executions allow. Past the cap the provider throttles, and the excess is dropped, not queued.
- **It starts cold.** An environment that sat idle is gone, and the next invocation boots a new one. See [cold start](https://wiki.playquorum.dev/glossary/cold-start.md). The Simulation charges it on a share of requests: nearly all of them at a trickle, almost none under steady load.

Because nothing is resident, a function is cheap at low and spiky volume. Above about 30% steady utilization of an equal VM it costs more than the VM, because the VM's Burn does not grow with the work it does.

## How it fails

- **The cap.** A spike above 1,000 concurrent executions is throttled, and the requests are lost.
- **Cold starts after a quiet minute.** A Java function can pay two seconds before its code runs, while Go and Rust pay 50 ms. A trickle of traffic pays it most often.
- **Connections.** Every concurrent execution opens its own database connections. Without a [Connection Pooler](https://wiki.playquorum.dev/components/pooler.md), a spike exhausts Postgres.
- **Duration.** A function stops an execution after 15 minutes. An export (`job`) runs 4 seconds for each GB the Databases hold, so past 225 GB it fails as `timeout`. Long `job` work belongs on a Worker behind a Queue, which has no limit.

### [Instance failure](https://wiki.playquorum.dev/incidents/instance.md)

- **Signs:** The Serverless Function card goes grey and its callout reads "The host under this VM died. It still bills." Requests sent to it are stranded.
- **Do now:** Select the Node and click **Replace**. It costs Cash and comes back cold.
- **Prevent:** Run a second copy behind a [Load Balancer](https://wiki.playquorum.dev/components/lb.md) that skips dead hosts. [Load balancing](https://wiki.playquorum.dev/research/load-balancing.md) and [Health checks](https://wiki.playquorum.dev/research/health-checks.md) unlock them.

### [Zone outage](https://wiki.playquorum.dev/incidents/zone.md)

- **Signs:** Every Node in one zone goes grey at once, the Serverless Function with them.
- **Do now:** Nothing brings the zone back sooner. **Fail over** promotes a **Standby**, and this Component keeps none, so it ends on its own after at most 120 s.
- **Prevent:** Research [Multiple zones](https://wiki.playquorum.dev/research/multi-az.md) and keep a copy of the Component in a second zone.

### [Region outage](https://wiki.playquorum.dev/incidents/region.md)

- **Signs:** One region's board goes grey and the Serverless Function in it goes down.
- **Do now:** Press **Fail over** on the banner. It needs [Multiple zones](https://wiki.playquorum.dev/research/multi-az.md) and a second open region, and starts the Node again in the nearest other region, cold, for the price of a replacement. Otherwise it comes back when the incident ends: 180 sim seconds in the catalog, 60 once the error budget counts.
- **Prevent:** Research [Multiple regions](https://wiki.playquorum.dev/research/multi-region.md), keep a copy in a second region, and add [GeoDNS](https://wiki.playquorum.dev/research/geo-dns.md) to send users there.

## Tips

- Put a [CDN](https://wiki.playquorum.dev/components/cdn.md) or a [Cache](https://wiki.playquorum.dev/components/cache.md) in front, because a function pays for every request that reaches it.
- Aim for a steady base load on App Servers with functions for the peaks: reserved boxes for the floor, per-use capacity for the spike.

## Rules

- Each further copy costs 25% more than the one before.
- Selling it refunds 50% of what its last copy cost.
- It has one size.
- A new copy starts cold and is slow until it warms up.

## Works with

[App Server](https://wiki.playquorum.dev/components/server.md), [Load Balancer](https://wiki.playquorum.dev/components/lb.md), [Connection Pooler](https://wiki.playquorum.dev/components/pooler.md), [Cache](https://wiki.playquorum.dev/components/cache.md), [Queue](https://wiki.playquorum.dev/components/queue.md), [Worker](https://wiki.playquorum.dev/components/worker.md), [CDN](https://wiki.playquorum.dev/components/cdn.md), [Vector Index](https://wiki.playquorum.dev/components/vec.md)

## Facts

Serverless Function
- **Code:** fn
- **Real product:** AWS Lambda
- **Group:** Compute
- **Unlocked by:** [Serverless](https://wiki.playquorum.dev/research/serverless.md)
- **Era:** [Series A](https://wiki.playquorum.dev/eras/series-a.md)
- **Place:** $0.00 first copy
- **Burn:** $0.00/s
- **Sizes:** 1
- **Overhead:** 1 ms
- **Takes:** Every kind
- **Sends:** Read query, Write query, Auth call, Search query, Object put, Task, Object get, Transaction, Charge, Scan, Inference, Push message, Customer call, Timeline write
- **Cold start:** Yes

## See also

- [Serverless](https://wiki.playquorum.dev/research/serverless.md)
- [Components](https://wiki.playquorum.dev/components.md)

Source: https://wiki.playquorum.dev/components/fn
