diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fe27aa60..8c188db08 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 4.6.0
+- Enforce a maximum value of 5000 ms for the `http2SessionIdleTime` option [#642](https://github.com/fauna/faunadb-js/pull/642)
+- Add checks to `http2SessionIdleTime` so that sane defaults are used in case an invalid value is configured
+- Add the missing Native.ROLES type [#638](https://github.com/fauna/faunadb-js/pull/638)
+
 ## 4.5.4
 - Disable ability to configure a client and the query method from returning metrics when calling query - fixing bug introduced in 4.5.3 that breaks backward compatibility. Continue supporting queryWithMetrics. [#633](https://github.com/fauna/faunadb-js/pull/633).
 
diff --git a/README.md b/README.md
index 561bdccd8..cba417934 100644
--- a/README.md
+++ b/README.md
@@ -155,7 +155,9 @@ time, and transaction retires consumed by your query:
   } // usage data
 }
 ```
+
 Metrics returned in the response will be of `number` data type.
+
 #### Pagination Helpers
 
 This driver contains helpers to provide a simpler API for consuming paged
@@ -280,14 +282,17 @@ have been resolved, the client will keep the session open for a period of time
 (500ms by default) to be reused for any new requests.
 
 The `http2SessionIdleTime` parameter may be used to control how long the HTTP/2
-session remains open while the connection is idle. To save on the overhead of
-closing and re-opening the session, set `http2SessionIdleTime` to a longer time
---- or even `Infinity`, to keep the session alive indefinitely.
+session remains open while the query connection is idle. To save on the overhead of
+closing and re-opening the session, set `http2SessionIdleTime` to a longer time.
+The default value is 500ms and the maximum value is 5000ms.
 
-While an HTTP/2 session is alive, the client will hold the Node.js event loop
+Note that `http2SessionIdleTime` has no effect on a stream connection: a stream
+is a long-lived connection that is intended to be held open indefinitely.
+
+While an HTTP/2 session is alive, the client holds the Node.js event loop
 open; this prevents the process from terminating. Call `Client#close` to manually
 close the session and allow the process to terminate. This is particularly
-important if `http2SessionIdleTime` is long or `Infinity`:
+important if `http2SessionIdleTime` is long:
 
 ```javascript
 // sample.js (run it with "node sample.js" command)
@@ -296,21 +301,18 @@ const { Client, query: Q } = require('faunadb')
 async function main() {
   const client = new Client({
     secret: 'YOUR_FAUNADB_SECRET',
-    http2SessionIdleTime: Infinity,
-    //                    ^^^ Infinity or non-negative integer
+    http2SessionIdleTime: 1000, // Must be a non-negative integer
   })
   const output = await client.query(Q.Add(1, 1))
 
   console.log(output)
 
   client.close()
-  //     ^^^ If it's not called then the process won't terminate
 }
 
 main().catch(console.error)
 ```
 
-
 ## Known issues
 
 ### Using with Cloudflare Workers
diff --git a/package.json b/package.json
index 92bf44bea..7282fe4d0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "faunadb",
-  "version": "4.5.4",
+  "version": "4.6.0",
   "apiVersion": "4",
   "description": "FaunaDB Javascript driver for Node.JS and Browsers",
   "homepage": "https://fauna.com",
diff --git a/src/Client.js b/src/Client.js
index 0fdcdd486..4b6b02925 100644
--- a/src/Client.js
+++ b/src/Client.js
@@ -158,9 +158,10 @@ var values = require('./values')
  *   Sets the maximum amount of time (in milliseconds) for query execution on the server
  * @param {?number} options.http2SessionIdleTime
  *   Sets the maximum amount of time (in milliseconds) an HTTP2 session may live
- *   when there's no activity. Must either be a non-negative integer, or Infinity to allow the
- *   HTTP2 session to live indefinitely (use `Client#close` to manually terminate the client).
- *   Only applicable for NodeJS environment (when http2 module is used). Default is 500ms;
+ *   when there's no activity. Must be a non-negative integer, with a maximum value of 5000.
+ *   If an invalid value is passed a default of 500 ms is applied. If a value 
+ *   exceeding 5000 ms is passed (e.g. Infinity) the maximum of 5000 ms is applied.
+ *   Only applicable for NodeJS environment (when http2 module is used).
  *   can also be configured via the FAUNADB_HTTP2_SESSION_IDLE_TIME environment variable
  *   which has the highest priority and overrides the option passed into the Client constructor.
  * @param {?boolean} options.checkNewVersion
@@ -169,7 +170,11 @@ var values = require('./values')
  *   Disabled by default. Controls whether or not query metrics are returned.
  */
 function Client(options) {
-  var http2SessionIdleTime = getHttp2SessionIdleTime()
+  const http2SessionIdleTime = getHttp2SessionIdleTime(
+    options ? options.http2SessionIdleTime : undefined
+  )
+
+  if (options) options.http2SessionIdleTime = http2SessionIdleTime
 
   options = util.applyDefaults(options, {
     domain: 'db.fauna.com',
@@ -182,14 +187,10 @@ function Client(options) {
     headers: {},
     fetch: undefined,
     queryTimeout: null,
-    http2SessionIdleTime: http2SessionIdleTime.value,
+    http2SessionIdleTime,
     checkNewVersion: false,
   })
 
-  if (http2SessionIdleTime.shouldOverride) {
-    options.http2SessionIdleTime = http2SessionIdleTime.value
-  }
-
   this._observer = options.observer
   this._http = new http.HttpClient(options)
   this.stream = stream.StreamAPI(this)
@@ -384,17 +385,29 @@ Client.prototype._handleRequestResult = function(response, result, options) {
   errors.FaunaHTTPError.raiseForStatusCode(result)
 }
 
-function getHttp2SessionIdleTime() {
-  var fromEnv = util.getEnvVariable('FAUNADB_HTTP2_SESSION_IDLE_TIME')
-  var parsed =
-    // Allow either "Infinity" or parsable integer string.
-    fromEnv === 'Infinity' ? Infinity : parseInt(fromEnv, 10)
-  var useEnvVar = !isNaN(parsed)
+function getHttp2SessionIdleTime(configuredIdleTime) {
+  const maxIdleTime = 5000
+  const defaultIdleTime = 500
+  const envIdleTime = util.getEnvVariable('FAUNADB_HTTP2_SESSION_IDLE_TIME')
 
-  return {
-    shouldOverride: useEnvVar,
-    value: useEnvVar ? parsed : 500,
+  var value = defaultIdleTime
+  // attemp to set the idle time to the env value and then the configured value
+  const values = [envIdleTime, configuredIdleTime]
+  for (const rawValue of values) {
+    const parsedValue = rawValue === 'Infinity'
+      ? Number.MAX_SAFE_INTEGER
+      : parseInt(rawValue, 10)
+    const isNegative = parsedValue < 0
+    const isGreaterThanMax = parsedValue > maxIdleTime
+    // if we didn't get infinity or a positive integer move to the next value
+    if (isNegative || !parsedValue) continue
+    // if we did get something valid constrain it to the ceiling
+    value = parsedValue
+    if (isGreaterThanMax) value = maxIdleTime
+    break
   }
+
+  return value
 }
 
 module.exports = Client
diff --git a/test/client.test.js b/test/client.test.js
index 5c6c31d85..c81f7e214 100644
--- a/test/client.test.js
+++ b/test/client.test.js
@@ -9,14 +9,20 @@ var json = require('../src/_json')
 var client
 
 describe('Client', () => {
+  const env = process.env
+
   beforeAll(() => {
     // Hideous way to ensure that the client is initialized.
     client = util.client()
-
     return client.query(query.CreateCollection({ name: 'my_collection' }))
   })
 
+  beforeEach(() => {
+    process.env = { ...env }
+  })
+
   afterEach(() => {
+    process.env = env
     util.clearBrowserSimulation()
   })
 
@@ -65,7 +71,6 @@ describe('Client', () => {
       toEqual(['metrics', 'value'])
   })
 
-
   test('paginates', () => {
     return createDocument().then(function(document) {
       return client.paginate(document.ref).each(function(page) {
@@ -176,7 +181,7 @@ describe('Client', () => {
 
   test('Client#close call on Http2Adapter-based Client', async () => {
     const client = util.getClient({
-      http2SessionIdleTime: Infinity,
+      http2SessionIdleTime: 5000,
     })
 
     await client.ping()
@@ -412,6 +417,115 @@ describe('Client', () => {
       requiredKeys.every(key => driverEnvHeader.includes(key))
     ).toBeDefined()
   })
+
+  test('http2SessionIdleTime env overrides client config', async () => {
+    var client
+    var internalIdleTime
+    const maxIdleTime = 5000
+    const defaultIdleTime = 500
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = '999'
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(999)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = maxIdleTime + 1
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(maxIdleTime)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = 'Infinity'
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(maxIdleTime)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = 'Cat'
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(2500)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = 'Cat'
+    client = util.getClient({
+      http2SessionIdleTime: "Cat",
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = '-999'
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(2500)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = '-999'
+    client = util.getClient({
+      http2SessionIdleTime: -999,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = '-999'
+    client = util.getClient({
+      http2SessionIdleTime: "Infinity",
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(maxIdleTime)
+  })
+
+  test('http2SessionIdleTime respects the max and default', async () => {
+    var client
+    var internalIdleTime
+    const maxIdleTime = 5000
+    const defaultIdleTime = 500
+    process.env.FAUNADB_HTTP2_SESSION_IDLE_TIME = undefined
+
+    client = util.getClient({
+      http2SessionIdleTime: 'Infinity',
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(maxIdleTime)
+
+    client = util.getClient({
+      http2SessionIdleTime: maxIdleTime + 1,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(maxIdleTime)
+
+    client = util.getClient({})
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+
+    client = util.getClient({ http2SessionIdleTime: null })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+
+    client = util.getClient({
+      http2SessionIdleTime: 'Cat',
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+
+    client = util.getClient({
+      http2SessionIdleTime: 2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(2500)
+
+    client = util.getClient({
+      http2SessionIdleTime: -2500,
+    })
+    internalIdleTime = client._http._adapter._http2SessionIdleTime
+    expect(internalIdleTime).toBe(defaultIdleTime)
+  })
 })
 
 function assertObserverStats(metrics, name) {
diff --git a/test/stream.test.js b/test/stream.test.js
index d19e508a0..e5d2d657a 100644
--- a/test/stream.test.js
+++ b/test/stream.test.js
@@ -273,6 +273,48 @@ describe('StreamAPI', () => {
         })
         .start()
     })
+
+    test.each([50, 500, 5000])('stays open beyond the value set for http2SessionIdleTime', async (idleTime) => {
+      const padding = 100
+      let seen_event = false
+      const client = util.getClient({
+        secret: key.secret,
+        http2SessionIdleTime: idleTime,
+      })
+      const oldTimestamp = doc.ts
+
+      const getNumberOfSessions = () => Object.keys(client._http._adapter._sessionMap).length
+
+      stream = client.stream
+      .document(doc.ref)
+      .on('version', (event) => {
+        seen_event = true
+        expect(event.action).toEqual("update")
+        expect(event.document.ts).toBeGreaterThan(oldTimestamp)
+      })
+
+      stream.start()
+
+      await util.delay(idleTime + padding)
+      expect(getNumberOfSessions()).toBe(1)
+
+      // this will create a new session as it is not a stream
+      const { ts: newTimestamp } = await client.query(q.Update(doc.ref, {}))
+      expect(newTimestamp).toBeGreaterThan(oldTimestamp)
+
+      await util.delay(idleTime + padding)
+      expect(getNumberOfSessions()).toBeGreaterThanOrEqual(1)
+      expect(seen_event).toBe(true)
+
+      seen_event = false
+      await util.delay(idleTime + padding)
+      expect(getNumberOfSessions()).toBeGreaterThanOrEqual(1)
+      expect(seen_event).toBe(false)
+
+      stream.close()
+      await util.delay(idleTime + padding)
+      expect(getNumberOfSessions()).toBe(0)
+    }, 30000);
   })
 
   describe('document', () => {