Function runtime
Instance lifecycle, concurrency, streaming, filesystem, networking, and shutdown behavior for Easel Functions.
Easel Functions run your server code on Node.js with the CPU, memory, and Node.js version set in Function configuration. Write your code so it works on a fresh instance, on a reused instance, and alongside other requests on the same instance.
Instance lifecycle
Easel creates, reuses, suspends, and stops instances based on traffic. Your application can't depend on any instance staying available.
Initialization
Module-level code runs once per instance, before it handles traffic. Use it for work you don't want to repeat on every request, such as creating clients:
Keep initialization fast. Large dependency graphs, expensive synchronous work, and network calls at startup add latency to the first request on each instance.
Reuse
A warm instance keeps loaded modules, connection pools, clients, and in-memory caches between requests. Reuse isn't guaranteed, so treat that state as an optimization: your code must still work when an instance starts empty.
A warm instance takes another request only while enough time remains for that
route's maxDuration. maxDuration bounds each request, including streaming
and post-response work. Easel also aborts a request early when it stalls before
sending headers or between body chunks; see
Function limits.
Concurrency
One instance can process overlapping requests. This helps most when requests spend time waiting on databases, APIs, or object storage.
Don't put request-specific state in shared mutable variables. Avoid:
Keep request state local instead:
Shared clients must support concurrent use. Don't mutate process.env to pass
request state.
Concurrency doesn't add CPU. CPU-heavy work, such as large JSON transforms, image processing, or synchronous filesystem access, delays every other request on the same instance. Move it to a worker or service when it hurts latency, or choose a larger CPU tier in Function configuration.
Request lifecycle
An invocation starts when Easel assigns a request to an instance. It ends when your code finishes and the response and any post-response work complete, when your code throws, when the route reaches its maximum duration, or when Easel stops the instance. Duration and billing cover the whole invocation, not only the time to the first byte.
Don't count on Easel retrying a failed invocation. Clients and proxies might retry on their own, so use idempotency keys for mutations that would be harmful to run twice.
Streaming responses
Return a streaming response when your framework supports it:
Easel forwards headers as soon as they're ready, then forwards body chunks as your code produces them. The invocation stays active while the stream is open, and streaming counts toward the route's maximum duration. Close streams reliably and don't buffer unbounded data.
Responses that need a complete body before the CDN can cache them, such as ISR pages, are buffered before caching. Ordinary dynamic responses stream to the client. Streaming doesn't make a response cacheable; see Caching.
Client disconnection
A client can disconnect before your function finishes. Pass request.signal to
work that supports cancellation:
Whether execution continues after a disconnect depends on the framework and how far the response has progressed, so don't rely on a connected request for work that must finish.
Work after the response
waitUntil and after() keep work running inside the same invocation after
the response is sent. See Background work for
what fits there and when to use a durable job system.
Filesystem
The filesystem is ephemeral. Files you write can disappear between requests, across instances, after a deployment, or when an instance stops. Don't store uploads, databases, or user data on local disk; use object storage or another durable service.
You can read files packaged with your deployment, but don't modify them. Temporary files are fine for parsing uploads, intermediate output, or libraries that need a file path. Delete them when you're done.
Networking
Functions can make outbound requests to databases, APIs, and other services. Latency depends on the distance from the function region (US East) to those services; see Function regions.
Create clients outside the handler so an instance reuses connection pools, keep-alive connections, and TLS sessions across requests:
Clients must tolerate idle connections closing, network interruptions, and instance shutdown, and reconnect when needed.
Incoming WebSocket connections aren't supported. Streaming HTTP and Server-Sent Events work, within the route's maximum duration.
Shutdown and timers
Easel may signal the runtime before stopping an instance, but you won't always get enough time to finish. Keep shutdown cleanup, such as flushing telemetry or closing clients, best effort. Commit durable state before you respond or through a durable external system.
Don't start unbounded loops from a request handler:
The instance can stop at any time, and every new instance starts another loop. Use a scheduled job for recurring work. Short timers that finish within the invocation are fine.