From 0f354adcc98c7527f31069148eb1e94c6135ef05 Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Fri, 1 Apr 2022 14:20:26 -0700 Subject: [PATCH 01/13] feat: add keep-alive timeout params for next-start --- packages/next/server/lib/start-server.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/next/server/lib/start-server.ts b/packages/next/server/lib/start-server.ts index 2c0dbfa8c7692..1ec71b957477a 100644 --- a/packages/next/server/lib/start-server.ts +++ b/packages/next/server/lib/start-server.ts @@ -5,6 +5,8 @@ import next from '../next' interface StartServerOptions extends NextServerOptions { allowRetry?: boolean + keepAliveTimeout?: number + headersTimeout?: number } export function startServer(opts: StartServerOptions) { @@ -14,6 +16,14 @@ export function startServer(opts: StartServerOptions) { return requestHandler(req, res) }) + if (opts.keepAliveTimeout) { + server.keepAliveTimeout = opts.keepAliveTimeout + } + + if (opts.headersTimeout) { + server.headersTimeout = opts.headersTimeout + } + return new Promise((resolve, reject) => { let port = opts.port let retryCount = 0 From 52974890d9ea75f9dbc7b85361acfb1806068b9b Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Fri, 1 Apr 2022 14:21:16 -0700 Subject: [PATCH 02/13] feat: add keep-alive timeout args to next-cli's start --- packages/next/cli/next-start.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index 09ad0f5b85732..aa605ff91ef8c 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -14,6 +14,8 @@ const nextStart: cliCommand = (argv) => { '--help': Boolean, '--port': Number, '--hostname': String, + '--keepAliveTimeout': Number, + '--headersTimeout': Number, // Aliases '-h': '--help', @@ -44,6 +46,8 @@ const nextStart: cliCommand = (argv) => { Options --port, -p A port number on which to start the application --hostname, -H Hostname on which to start the application (default: 0.0.0.0) + --keepAliveTimeout Max milliseconds to wait before closing inactive connections + --headersTimeout Max milliseconds to wait for headers to finish, before closing inactive connections --help, -h Displays this message `) process.exit(0) @@ -58,10 +62,20 @@ const nextStart: cliCommand = (argv) => { port = 0 } + const keepAliveTimeout = args['--keepAliveTimeout'] + ? parseInt(args['--keepAliveTimeout']) + : undefined + + const headersTimeout = args['--headersTimeout'] + ? parseInt(args['--headersTimeout']) + : undefined + startServer({ dir, hostname: host, port, + keepAliveTimeout, + headersTimeout, }) .then(async (app) => { const appUrl = `http://${app.hostname}:${app.port}` From e539c92628340d00b84c691bd225e0de4f77be7a Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Fri, 1 Apr 2022 14:21:31 -0700 Subject: [PATCH 03/13] docs: add docs for keep-alive timeouts --- docs/api-reference/cli.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index 20b36920d7bf3..e8e5c73534ae2 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -106,6 +106,22 @@ PORT=4000 npx next start > Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized. +### Working with Load-balancer Timeouts + +When deploying Next.js behind an upstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying http-server with [keep-alive timeouts](https://nodejs.org/api/http.html#http_server_keepalivetimeout) that are _smaller_ than the upstream proxies' timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the upstream proxies. This results in the upstream proxies throwing intermittent 5xx errors whenever they attempt to reuse a connection that Node.js has already terminated. + +To configure the timeout values for the production Next.js server, pass `--keepAliveTimeout` (in milliseconds) to `next start`, like so: + +```bash +npx next start --keepAliveTimeout 70000 +``` + +In some earlier versions of Node.js, there is [a regression that requires that `headersTimeout` is set to a value greater than the `keepAliveTimeout` value](https://github.com/nodejs/node/issues/27363). To configure [`headersTimeout`](https://nodejs.org/api/http.html#serverheaderstimeout) for the production Next.js server, pass `--headersTimeout` (in milliseconds) to `next start`, like so: + +```bash +npx next start --keepAliveTimeout 70000 --headersTimeout 75000 +``` + ## Lint `next lint` runs ESLint for all files in the `pages`, `components`, and `lib` directories. It also From b5f0613667253e2fff7a3cad437dd901a03b5bf3 Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Tue, 5 Apr 2022 14:37:32 -0700 Subject: [PATCH 04/13] docs: fix grammar & typos --- docs/api-reference/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index e8e5c73534ae2..549c1f3dff204 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -108,7 +108,7 @@ PORT=4000 npx next start ### Working with Load-balancer Timeouts -When deploying Next.js behind an upstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying http-server with [keep-alive timeouts](https://nodejs.org/api/http.html#http_server_keepalivetimeout) that are _smaller_ than the upstream proxies' timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the upstream proxies. This results in the upstream proxies throwing intermittent 5xx errors whenever they attempt to reuse a connection that Node.js has already terminated. +When deploying Next.js behind a downstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying http-server with [keep-alive timeouts](https://nodejs.org/api/http.html#http_server_keepalivetimeout) that are _larger_ than the downstream proxies' timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the downstream proxies. This results in the downstream proxies throwing intermittent 5xx errors whenever they attempt to reuse a connection that Node.js has already terminated. To configure the timeout values for the production Next.js server, pass `--keepAliveTimeout` (in milliseconds) to `next start`, like so: From 9f0f0bbe975ce729721893c3049f6fa3c1d8e95c Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Tue, 5 Apr 2022 17:25:29 -0700 Subject: [PATCH 05/13] refactor: handle NaN for args --- packages/next/cli/next-start.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index aa605ff91ef8c..dd80229b46762 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -62,14 +62,28 @@ const nextStart: cliCommand = (argv) => { port = 0 } - const keepAliveTimeout = args['--keepAliveTimeout'] + let keepAliveTimeout = args['--keepAliveTimeout'] ? parseInt(args['--keepAliveTimeout']) : undefined - const headersTimeout = args['--headersTimeout'] + let headersTimeout = args['--headersTimeout'] ? parseInt(args['--headersTimeout']) : undefined + if (Number.isNaN(keepAliveTimeout)) { + keepAliveTimeout = undefined + printAndExit( + 'Invalid type for --keepAliveTimeout; provide an integer in milliseconds' + ) + } + + if (Number.isNaN(headersTimeout)) { + headersTimeout = undefined + printAndExit( + 'Invalid type for --headersTimeout; provide an integer in milliseconds' + ) + } + startServer({ dir, hostname: host, From 1531494e4b7ac99347808bcc8cdb73a8e6cc50ae Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Tue, 5 Apr 2022 17:25:58 -0700 Subject: [PATCH 06/13] test: add tests for timeout args --- test/integration/cli/test/index.test.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index de5951fbcfef3..4d3e1c78820e3 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -394,6 +394,30 @@ describe('CLI Usage', () => { 'Invalid project directory provided, no such directory' ) }) + + test('should validate keepAliveTimeout argument', async () => { + const output = await runNextCommand( + ['start', dir, '--keepAliveTimeout', 'seventy-five-thousand'], + { + stderr: true, + } + ) + expect(output.stderr).toEqual( + 'Invalid type for --keepAliveTimeout; provide an integer in milliseconds' + ) + }) + + test('should validate headersTimeout argument', async () => { + const output = await runNextCommand( + ['start', dir, '--headersTimeout', 'seventy-five-thousand'], + { + stderr: true, + } + ) + expect(output.stderr).toEqual( + 'Invalid type for --headersTimeout; provide an integer in milliseconds' + ) + }) }) describe('export', () => { From 0450d78287208099196a52fcede1d51c9da3e69d Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Sun, 17 Apr 2022 09:54:55 -0700 Subject: [PATCH 07/13] revert: remove headersTimeout option --- docs/api-reference/cli.md | 6 ------ packages/next/cli/next-start.ts | 14 -------------- packages/next/server/lib/start-server.ts | 5 ----- test/integration/cli/test/index.test.js | 12 ------------ 4 files changed, 37 deletions(-) diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index 549c1f3dff204..b88531285955b 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -116,12 +116,6 @@ To configure the timeout values for the production Next.js server, pass `--keepA npx next start --keepAliveTimeout 70000 ``` -In some earlier versions of Node.js, there is [a regression that requires that `headersTimeout` is set to a value greater than the `keepAliveTimeout` value](https://github.com/nodejs/node/issues/27363). To configure [`headersTimeout`](https://nodejs.org/api/http.html#serverheaderstimeout) for the production Next.js server, pass `--headersTimeout` (in milliseconds) to `next start`, like so: - -```bash -npx next start --keepAliveTimeout 70000 --headersTimeout 75000 -``` - ## Lint `next lint` runs ESLint for all files in the `pages`, `components`, and `lib` directories. It also diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index dd80229b46762..303d876d56bd1 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -15,7 +15,6 @@ const nextStart: cliCommand = (argv) => { '--port': Number, '--hostname': String, '--keepAliveTimeout': Number, - '--headersTimeout': Number, // Aliases '-h': '--help', @@ -47,7 +46,6 @@ const nextStart: cliCommand = (argv) => { --port, -p A port number on which to start the application --hostname, -H Hostname on which to start the application (default: 0.0.0.0) --keepAliveTimeout Max milliseconds to wait before closing inactive connections - --headersTimeout Max milliseconds to wait for headers to finish, before closing inactive connections --help, -h Displays this message `) process.exit(0) @@ -66,10 +64,6 @@ const nextStart: cliCommand = (argv) => { ? parseInt(args['--keepAliveTimeout']) : undefined - let headersTimeout = args['--headersTimeout'] - ? parseInt(args['--headersTimeout']) - : undefined - if (Number.isNaN(keepAliveTimeout)) { keepAliveTimeout = undefined printAndExit( @@ -77,19 +71,11 @@ const nextStart: cliCommand = (argv) => { ) } - if (Number.isNaN(headersTimeout)) { - headersTimeout = undefined - printAndExit( - 'Invalid type for --headersTimeout; provide an integer in milliseconds' - ) - } - startServer({ dir, hostname: host, port, keepAliveTimeout, - headersTimeout, }) .then(async (app) => { const appUrl = `http://${app.hostname}:${app.port}` diff --git a/packages/next/server/lib/start-server.ts b/packages/next/server/lib/start-server.ts index 1ec71b957477a..f01432504f06a 100644 --- a/packages/next/server/lib/start-server.ts +++ b/packages/next/server/lib/start-server.ts @@ -6,7 +6,6 @@ import next from '../next' interface StartServerOptions extends NextServerOptions { allowRetry?: boolean keepAliveTimeout?: number - headersTimeout?: number } export function startServer(opts: StartServerOptions) { @@ -20,10 +19,6 @@ export function startServer(opts: StartServerOptions) { server.keepAliveTimeout = opts.keepAliveTimeout } - if (opts.headersTimeout) { - server.headersTimeout = opts.headersTimeout - } - return new Promise((resolve, reject) => { let port = opts.port let retryCount = 0 diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 4d3e1c78820e3..5fa95e0726691 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -406,18 +406,6 @@ describe('CLI Usage', () => { 'Invalid type for --keepAliveTimeout; provide an integer in milliseconds' ) }) - - test('should validate headersTimeout argument', async () => { - const output = await runNextCommand( - ['start', dir, '--headersTimeout', 'seventy-five-thousand'], - { - stderr: true, - } - ) - expect(output.stderr).toEqual( - 'Invalid type for --headersTimeout; provide an integer in milliseconds' - ) - }) }) describe('export', () => { From f9387eee0a19c9c50f6d46dc75a79015bd2980ef Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Sun, 17 Apr 2022 12:02:58 -0700 Subject: [PATCH 08/13] fix: remove input validation for keepAliveTimeout arg --- packages/next/cli/next-start.ts | 11 +---------- test/integration/cli/test/index.test.js | 12 ------------ 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index 303d876d56bd1..31fc1e304212a 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -60,16 +60,7 @@ const nextStart: cliCommand = (argv) => { port = 0 } - let keepAliveTimeout = args['--keepAliveTimeout'] - ? parseInt(args['--keepAliveTimeout']) - : undefined - - if (Number.isNaN(keepAliveTimeout)) { - keepAliveTimeout = undefined - printAndExit( - 'Invalid type for --keepAliveTimeout; provide an integer in milliseconds' - ) - } + const keepAliveTimeout: number | undefined = args['--keepAliveTimeout'] startServer({ dir, diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 5fa95e0726691..de5951fbcfef3 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -394,18 +394,6 @@ describe('CLI Usage', () => { 'Invalid project directory provided, no such directory' ) }) - - test('should validate keepAliveTimeout argument', async () => { - const output = await runNextCommand( - ['start', dir, '--keepAliveTimeout', 'seventy-five-thousand'], - { - stderr: true, - } - ) - expect(output.stderr).toEqual( - 'Invalid type for --keepAliveTimeout; provide an integer in milliseconds' - ) - }) }) describe('export', () => { From 48396b9c42ff1bcee8c4f305cdb889021d030b62 Mon Sep 17 00:00:00 2001 From: Mikis Woodwinter Date: Sun, 17 Apr 2022 12:04:27 -0700 Subject: [PATCH 09/13] feat: add input-range validation for keepAliveTimeout arg --- packages/next/cli/next-start.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index 31fc1e304212a..6182eaa8ac4c5 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -60,7 +60,16 @@ const nextStart: cliCommand = (argv) => { port = 0 } - const keepAliveTimeout: number | undefined = args['--keepAliveTimeout'] + const keepAliveTimeoutArg: number | undefined = args['--keepAliveTimeout'] + let keepAliveTimeout: number | undefined + + if (keepAliveTimeoutArg) { + keepAliveTimeout = Math.ceil(keepAliveTimeoutArg) + keepAliveTimeout = Number.isFinite(keepAliveTimeoutArg) + ? keepAliveTimeoutArg + : undefined + keepAliveTimeout = keepAliveTimeoutArg < 0 ? 0 : undefined + } startServer({ dir, From fee16906484018d431434afdd423867fe6c4e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Wed, 15 Jun 2022 10:38:36 +0200 Subject: [PATCH 10/13] Error and tests for range validation --- packages/next/cli/next-start.ts | 22 +++++++----- test/integration/cli/test/index.test.js | 48 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index 6182eaa8ac4c5..aa14aba68e094 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -61,16 +61,22 @@ const nextStart: cliCommand = (argv) => { } const keepAliveTimeoutArg: number | undefined = args['--keepAliveTimeout'] - let keepAliveTimeout: number | undefined - - if (keepAliveTimeoutArg) { - keepAliveTimeout = Math.ceil(keepAliveTimeoutArg) - keepAliveTimeout = Number.isFinite(keepAliveTimeoutArg) - ? keepAliveTimeoutArg - : undefined - keepAliveTimeout = keepAliveTimeoutArg < 0 ? 0 : undefined + if ( + typeof keepAliveTimeoutArg !== 'undefined' && + (Number.isNaN(keepAliveTimeoutArg) || + !Number.isFinite(keepAliveTimeoutArg) || + keepAliveTimeoutArg < 0) + ) { + printAndExit( + 'Invalid keep alive timeout provided, expected a non negative number', + 1 + ) } + const keepAliveTimeout = keepAliveTimeoutArg + ? Math.ceil(keepAliveTimeoutArg) + : undefined + startServer({ dir, hostname: host, diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 0b44cc527a1c2..04f4bea61ec51 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -394,6 +394,54 @@ describe('CLI Usage', () => { 'Invalid project directory provided, no such directory' ) }) + + test('--keepAliveTimeout string arg', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', 'string'], + { + stderr: true, + } + ) + expect(stderr).toContain( + 'Invalid keep alive timeout provided, expected a non negative number' + ) + }) + + test('--keepAliveTimeout negative number', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout=-100'], + { + stderr: true, + } + ) + expect(stderr).toContain( + 'Invalid keep alive timeout provided, expected a non negative number' + ) + }) + + test('--keepAliveTimeout Infinity', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', 'Infinity'], + { + stderr: true, + } + ) + expect(stderr).toContain( + 'Invalid keep alive timeout provided, expected a non negative number' + ) + }) + + test('--keepAliveTimeout happy path', async () => { + const { stderr } = await runNextCommand( + ['start', '--keepAliveTimeout', '100'], + { + stderr: true, + } + ) + expect(stderr).not.toContain( + 'Invalid keep alive timeout provided, expected a non negative number' + ) + }) }) describe('export', () => { From a791c76649fc02853b630ac2011296fcf0cddf0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Wed, 15 Jun 2022 14:28:39 +0200 Subject: [PATCH 11/13] Make sure timeout actually changes --- test/unit/cli.test.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/unit/cli.test.ts diff --git a/test/unit/cli.test.ts b/test/unit/cli.test.ts new file mode 100644 index 0000000000000..5317d68bf250e --- /dev/null +++ b/test/unit/cli.test.ts @@ -0,0 +1,34 @@ +import { nextStart } from 'next/dist/cli/next-start' +import httpMock, { Server } from 'http' + +// Prevents bin from running +jest.mock('next/dist/bin/next', () => ({})) +jest.mock('next/dist/lib/get-project-dir', () => ({ getProjectDir: () => '' })) + +jest.mock('http') + +describe('start', () => { + test('--keepAliveTimeout changes server.keepAliveTimeout when passed', () => { + const server = { + on: () => {}, + listen: () => {}, + } as any as Server + ;(httpMock as any).createServer.mockReturnValue(server) + + expect(server.keepAliveTimeout).toBe(undefined) + nextStart(['--keepAliveTimeout', '1234']) + expect(server.keepAliveTimeout).toBe(1234) + }) + + test("--keepAliveTimeout doesn't change server.keepAliveTimeout when not passed", () => { + const server = { + on: () => {}, + listen: () => {}, + } as any as Server + ;(httpMock as any).createServer.mockReturnValue(server) + + expect(server.keepAliveTimeout).toBe(undefined) + nextStart([]) + expect(server.keepAliveTimeout).toBe(undefined) + }) +}) From d528bfe9251c8409f608fb5c9c99651f4f6be9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Wed, 15 Jun 2022 14:42:34 +0200 Subject: [PATCH 12/13] Fix error messsage --- packages/next/cli/next-start.ts | 2 +- test/integration/cli/test/index.test.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/next/cli/next-start.ts b/packages/next/cli/next-start.ts index aa14aba68e094..a640c9e44459d 100755 --- a/packages/next/cli/next-start.ts +++ b/packages/next/cli/next-start.ts @@ -68,7 +68,7 @@ const nextStart: cliCommand = (argv) => { keepAliveTimeoutArg < 0) ) { printAndExit( - 'Invalid keep alive timeout provided, expected a non negative number', + `Invalid --keepAliveTimeout, expected a non negative number but received "${keepAliveTimeoutArg}"`, 1 ) } diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index 04f4bea61ec51..91dc644acf9db 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -403,7 +403,7 @@ describe('CLI Usage', () => { } ) expect(stderr).toContain( - 'Invalid keep alive timeout provided, expected a non negative number' + 'Invalid --keepAliveTimeout, expected a non negative number but received "NaN"' ) }) @@ -415,7 +415,7 @@ describe('CLI Usage', () => { } ) expect(stderr).toContain( - 'Invalid keep alive timeout provided, expected a non negative number' + 'Invalid --keepAliveTimeout, expected a non negative number but received "-100"' ) }) @@ -427,7 +427,7 @@ describe('CLI Usage', () => { } ) expect(stderr).toContain( - 'Invalid keep alive timeout provided, expected a non negative number' + 'Invalid --keepAliveTimeout, expected a non negative number but received "Infinity"' ) }) From 1e00f0e42b8dedd2a54f46b47e29a7f5f71e85ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Fri, 24 Jun 2022 14:03:22 +0200 Subject: [PATCH 13/13] Apply suggestions from code review Co-authored-by: Steven --- docs/api-reference/cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md index 1f1ffd9d3e27e..a1baeacccf5b6 100644 --- a/docs/api-reference/cli.md +++ b/docs/api-reference/cli.md @@ -108,9 +108,9 @@ PORT=4000 npx next start > Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized. -### Working with Load-balancer Timeouts +### Keep Alive Timeout -When deploying Next.js behind a downstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying http-server with [keep-alive timeouts](https://nodejs.org/api/http.html#http_server_keepalivetimeout) that are _larger_ than the downstream proxies' timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the downstream proxies. This results in the downstream proxies throwing intermittent 5xx errors whenever they attempt to reuse a connection that Node.js has already terminated. +When deploying Next.js behind a downstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying HTTP server with [keep-alive timeouts](https://nodejs.org/api/http.html#http_server_keepalivetimeout) that are _larger_ than the downstream proxy's timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the downstream proxy. This results in a proxy error whenever it attempts to reuse a connection that Node.js has already terminated. To configure the timeout values for the production Next.js server, pass `--keepAliveTimeout` (in milliseconds) to `next start`, like so: