Function runtime
Instance lifecycle, concurrency, streaming, filesystem, networking, and shutdown behavior for Easel Functions.
The function runtime provides the execution environment for server-side application code.
This page describes instance lifecycle, concurrency, reuse, streaming, filesystem behavior, networking, and shutdown semantics.
Runtime environment
Easel Functions run application code produced by supported frameworks or application-defined handlers.
A runtime environment includes:
- The application bundle
- Runtime dependencies
- Configured environment variables
- Allocated CPU and memory
- Temporary filesystem space
- Network access
- Request and observability integrations
Supported runtime versions are listed in Function configuration.
Instance lifecycle
A function instance moves through a lifecycle similar to:
Easel may create, reuse, suspend, or terminate instances based on traffic and platform conditions.
The application must not depend on a specific instance remaining available.
Initialization
Initialization happens before an instance begins handling application traffic.
Typical initialization work includes:
- Loading application modules
- Initializing framework code
- Creating database clients
- Reading configuration
- Preparing reusable application state
Module-level initialization can reduce repeated work across requests:
Initialization code must remain reasonably fast. Large dependency graphs, expensive synchronous work, and unnecessary network requests increase startup latency.
Instance reuse
An initialized instance may handle multiple requests over its lifetime.
Reuse allows applications to preserve:
- Loaded modules
- Database connection pools
- HTTP clients
- Parsed configuration
- Read-only lookup data
- In-memory caches used only as optional optimizations
Reuse is not guaranteed.
Code must continue working when an instance starts with no previous in-memory state.
A warm Fluid instance may handle more than one request during a single platform
wake, but only while enough wake time remains for the route’s maxDuration.
Customer maxDuration bounds each request (including streaming and
post-response work). It is not the AWS session Timeout; that is a platform
setting that keeps the wake open long enough to multiplex eligible requests.
The platform aborts a request that makes no progress well before the full
duration budget: headers must start within 60 seconds, and body chunks must
arrive no more than 30 seconds apart (see Function limits).
The per-request wait tracks maxDuration rather than the longer wake Timeout.
In-function concurrency
An instance may process overlapping requests.
This differs from a model in which each instance handles exactly one request at a time.
Concurrency is especially useful for workloads that spend significant time waiting on:
- Databases
- External APIs
- Object storage
- Network streams
- Other asynchronous services
Concurrency safety
Do not place request-specific state in shared mutable variables.
Avoid:
Instead, keep request state local:
Libraries used as shared clients must support concurrent requests.
CPU and asynchronous work
Concurrency does not create unlimited CPU.
CPU-intensive JavaScript or native work can delay other requests handled by the same instance.
Examples include:
- Large JSON transformations
- Image or video processing
- Compression
- Cryptographic operations
- Synchronous filesystem access
- Large template compilation
- Machine-learning inference
Move unusually expensive tasks to an appropriate worker or service when they interfere with request latency.
Request lifecycle
An invocation begins when Easel assigns a request to the function runtime.
It ends when:
- Application execution completes
- The response and registered post-response work complete
- The application fails
- The client disconnect causes execution to terminate, where applicable
- The maximum duration is reached
- The platform terminates the instance
Billing and duration measurement follow the function invocation rather than only the time until the first response byte.
Streaming responses
A function can return a streaming response when supported by the runtime.
Easel forwards response headers as soon as they are available, then forwards body chunks as the runtime produces them.
The invocation remains active while the response stream is open and until
registered post-response work finishes. Streaming and waitUntil / after()
work count toward the route’s maximum duration (default 30s, max 800s).
Applications must:
- Handle cancellation where supported
- Close streams reliably
- Avoid retaining unbounded buffers
- Respect the maximum duration
- Send periodic data only when appropriate for the protocol
Some paths that need a complete body for CDN or ISR admit still buffer before caching. Client delivery for ordinary dynamic responses streams.
Client disconnection
A client can disconnect before the function finishes.
Applications must not assume that a successfully started request will retain an active client connection until completion.
Use abort signals when supported:
Whether execution continues after a client disconnect may depend on the runtime, framework, and response state.
Do not use client-connected requests as a substitute for durable job processing.
Work after the response
Framework integrations may support post-response APIs.
Registered work:
- Runs within the original invocation
- Counts toward duration
- Uses the function’s CPU and memory
- Can be interrupted if the invocation ends
- Does not provide durable retries by itself
Use this capability for short, non-critical work such as:
- Best-effort analytics
- Log enrichment
- Small cache updates
- Non-critical notifications
Do not use it for:
- Financial transactions
- Durable workflow steps
- Long-running imports
- Tasks requiring retries
- Jobs that must complete exactly once
Filesystem
The function filesystem is ephemeral.
Applications can use temporary storage during an invocation where supported, but files are not guaranteed to remain available:
- Across instances
- Across deployments
- After an instance shuts down
- For any specific retention period
Do not use the local filesystem for durable uploads, application databases, or persistent user data.
Use object storage or another durable service.
Read-only application files
Files packaged into the application bundle can be read at runtime where supported.
Avoid modifying packaged application files.
Temporary files
Temporary files may be useful for:
- Parsing uploads
- Generating intermediate output
- Working with libraries that require file paths
- Buffering bounded data
Delete temporary files when possible and remain within storage limits.
Networking
Functions can make outbound network requests to databases, APIs, and other services.
Application latency depends on the network distance between the function region (US East) and its dependencies.
Prefer persistent, reusable clients where supported.
Connections and pooling
An active instance can reuse outbound connections across requests.
Examples include:
- Database pools
- HTTP keep-alive connections
- TLS sessions
- SDK clients
Create reusable clients outside the request handler:
Client libraries must tolerate:
- Concurrent requests
- Idle connection closure
- Instance shutdown
- Network interruption
- Reconnection
Do not assume that a connection remains open for the lifetime of the deployment.
Incoming connections
Functions handle HTTP requests through Easel’s request interface.
Long-lived incoming WebSocket connections are not supported.
Streaming HTTP and Server-Sent Events are separate from WebSockets and remain subject to function duration and connection limits.
Signals and shutdown
Easel may notify the runtime before termination where supported, but applications must not depend on receiving enough time to complete important work.
Shutdown cleanup must be best effort.
Examples include:
- Flushing buffered telemetry
- Closing clients
- Releasing temporary resources
- Stopping internal timers
Durable state must be committed before the response or through a durable external system.
Timers and background loops
Do not start unbounded background loops from a request handler.
Avoid:
The instance may stop at any time, and repeated initialization can create multiple overlapping loops.
Use a scheduled job or durable task system for recurring work.
Short timers used during an active invocation are acceptable when they complete within the invocation lifecycle.
Environment variables
Environment variables are available to application code according to the deployment environment.
Do not mutate process.env as a way to share request state.
Treat secret variables as sensitive and avoid writing them to logs.
Time and locale
Do not assume that the runtime’s system timezone matches the user or project location.
Store and process timestamps in UTC unless application requirements specify otherwise.
Format dates and times explicitly using the appropriate user locale and timezone.
Error handling
Unhandled errors fail the invocation and may return a platform or framework error response.
Applications must:
- Catch expected failures
- Return appropriate HTTP status codes
- Avoid exposing stack traces or secrets
- Include request IDs in support workflows
- Use structured application logs
Example:
Retries
Do not assume an HTTP invocation will be retried automatically.
Clients, proxies, queues, or framework integrations may retry some requests independently.
Application mutations must use idempotency keys when duplicate execution would be harmful.
Runtime observability
Runtime telemetry can include:
- Initialization duration
- Invocation duration
- Active requests
- Memory usage
- CPU usage
- Errors
- Region
- Instance identifiers
- Downstream spans
Instance identifiers are diagnostic and must not be used for application routing or durable state.
See Observability and Function observability.