Configuring a Lambda function to stream responses
You can configure your Lambda function URLs to stream response payloads back to clients. Response streaming can benefit latency sensitive applications by improving time to first byte (TTFB) performance. This is because you can send partial responses back to the client as they become available. Additionally, you can use response streaming to build functions that return larger payloads. Response stream payloads have a soft limit of 20 MB as compared to the 6 MB limit for buffered responses. Streaming a response also means that your function doesn’t need to fit the entire response in memory. For very large responses, this can reduce the amount of memory you need to configure for your function.
The speed at which Lambda streams your responses depends on the response size. The streaming rate for the first 6MB of your function’s response is uncapped. For responses larger than 6MB, the remainder of the response is subject to a bandwidth cap. For more information on streaming bandwidth, see Bandwidth limits for response streaming.
Streaming responses incurs a cost. For more information, see Amazon Lambda Pricing
Currently, Lambda supports response streaming only on Node.js 14.x
,
Node.js 16.x
, and Node.js 18.x
managed runtimes. You can also use a
custom runtime with a custom Runtime API integration to stream responses or use the Lambda Web Adapter
Note
When testing your function through the Lambda console, you'll always see responses as buffered.
Writing response streaming-enabled functions
Writing the handler for response streaming functions is different than typical handler patterns. When writing streaming functions, be sure to do the following:
Wrap your function with the
awslambda.streamifyResponse()
decorator that the native Node.js runtimes provide.End the stream gracefully to ensure that all data processing is complete.
Configuring a handler function to stream responses
To indicate to the runtime that Lambda should stream your function's responses, you must
wrap your function with the streamifyResponse()
decorator. This tells the
runtime to use the proper logic path for streaming responses and enables the function to
stream responses.
The streamifyResponse()
decorator accepts a function that accepts the following parameters:
event
– Provides information about the function URL's invocation event, such as the HTTP method, query parameters, and the request body.responseStream
– Provides a writable stream.context
– Provides methods and properties with information about the invocation, function, and execution environment.
The responseStream
object is a Node.js writableStream
pipeline()
method.
Example response streaming-enabled handler
const pipeline = require("util").promisify(require("stream").pipeline); const { Readable } = require('stream'); exports.echo = awslambda.streamifyResponse(async (event, responseStream, _context) => { // As an example, convert event to a readable stream. const requestStream = Readable.from(Buffer.from(JSON.stringify(event))); await pipeline(requestStream, responseStream); });
While responseStream
offers the write()
method to write to the
stream, we recommend that you use pipeline()
pipeline()
ensures that the writable stream is not overwhelmed by a faster readable stream.
Ending the stream
Make sure that you properly end the stream before the handler returns. The
pipeline()
method handles this automatically.
For other use cases, call the responseStream.end()
method to properly end a
stream. This method signals that no more data should be written to the stream. This method
isn't required if you write to the stream with pipeline()
or
pipe()
.
Example ending a stream with pipeline()
const pipeline = require("util").promisify(require("stream").pipeline); exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { await pipeline(requestStream, responseStream); });
Example ending a stream without pipeline()
exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { responseStream.write("Hello "); responseStream.write("world "); responseStream.write("from "); responseStream.write("Lambda!"); responseStream.end(); });
Invoking a response streaming enabled function using Lambda function URLs
Note
You must invoke your function using a function URL to stream the responses.
You can invoke response streaming enabled functions by changing the invoke mode of your function's URL. The invoke mode determines which API operation Lambda uses to invoke your function. The available invoke modes are:
-
BUFFERED
– This is the default option. Lambda invokes your function using theInvoke
API operation. Invocation results are available when the payload is complete. The maximum payload size is 6 MB. -
RESPONSE_STREAM
– Enables your function to stream payload results as they become available. Lambda invokes your function using theInvokeWithResponseStream
API operation. The maximum response payload size is 20 MB. However, you can request a quota increase.
You can still invoke your function without response streaming by directly calling the
Invoke
API operation. However, Lambda streams all response payloads for
invocations that come through the function's URL until you change the invoke mode to
BUFFERED
.
To set the invoke mode of a function URL (console)
-
Open the Functions page
of the Lambda console. -
Choose the name of the function that you want to set the invoke mode for.
-
Choose the Configuration tab, and then choose Function URL.
-
Choose Edit, then choose Additional settings.
-
Under Invoke mode, choose your desired invoke mode.
-
Choose Save.
To set the invoke mode of a function's URL (Amazon CLI)
aws lambda update-function-url-config --function-name
my-function
--invoke-mode RESPONSE_STREAM
To set the invoke mode of a function's URL (Amazon CloudFormation)
MyFunctionUrl: Type: AWS::Lambda::Url Properties: AuthType: AWS_IAM InvokeMode: RESPONSE_STREAM
For more information about configuring function URLs, see Lambda function URLs.
Bandwidth limits for response streaming
The first 6MB of your function’s response payload has uncapped bandwidth. After this initial burst, Lambda streams your response at a maximum rate of 2MBps. If your function responses never exceed 6MB, then this bandwidth limit never applies.
Note
Bandwidth limits only apply to your function’s response payload, and not to network access by your function.
The rate of uncapped bandwidth varies depending on a number of factors, including your function’s processing speed. You can normally expect a rate higher than 2MBps for the first 6MB of your function’s response. If your function is streaming a response to a destination outside of Amazon, the streaming rate also depends on the speed of the external internet connection.