diff --git a/Cargo.toml b/Cargo.toml
index 867e9c0d..8c3294cc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,7 @@
 [workspace]
 resolver = "2"
 members = [
+    "json-impl",
     "lambda-http",
     "lambda-integration-tests",
     "lambda-runtime-api-client",
diff --git a/README.md b/README.md
index 31ba399b..66f29c26 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ If you'd like to manually create your first function, the code below shows you a
 
 ```rust,no_run
 use lambda_runtime::{service_fn, LambdaEvent, Error};
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 
 #[tokio::main]
 async fn main() -> Result<(), Error> {
@@ -375,7 +375,7 @@ To serialize and deserialize events and responses, we suggest using the [`serde`
 
 ```rust,no_run
 use serde::{Serialize, Deserialize};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 use std::error::Error;
 
 #[derive(Serialize, Deserialize)]
diff --git a/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs b/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs
index 2a70dce3..e7f9414f 100644
--- a/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs
+++ b/examples/advanced-sqs-multiple-functions-shared-data/producer/src/main.rs
@@ -1,6 +1,6 @@
 use lambda_runtime::{service_fn, tracing, Error, LambdaEvent};
 use pizza_lib::Pizza;
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 
 struct SQSManager {
     client: aws_sdk_sqs::Client,
diff --git a/examples/basic-error-handling/src/main.rs b/examples/basic-error-handling/src/main.rs
index 3bc76936..6886ef15 100644
--- a/examples/basic-error-handling/src/main.rs
+++ b/examples/basic-error-handling/src/main.rs
@@ -1,7 +1,7 @@
 /// See https://github.com/awslabs/aws-lambda-rust-runtime for more info on Rust runtime for AWS Lambda
 use lambda_runtime::{service_fn, tracing, Error, LambdaEvent};
 use serde::{Deserialize, Serialize};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 use std::fs::File;
 
 /// A simple Lambda request structure with just one field
diff --git a/examples/basic-streaming-response/src/main.rs b/examples/basic-streaming-response/src/main.rs
index 8533c8e3..938b6ba6 100644
--- a/examples/basic-streaming-response/src/main.rs
+++ b/examples/basic-streaming-response/src/main.rs
@@ -3,7 +3,7 @@ use lambda_runtime::{
     streaming::{channel, Body, Response},
     tracing, Error, LambdaEvent,
 };
-use serde_json::Value;
+use aws_lambda_json_impl::Value;
 use std::{thread, time::Duration};
 
 async fn func(_event: LambdaEvent<Value>) -> Result<Response<Body>, Error> {
diff --git a/examples/http-axum-apigw-authorizer/src/main.rs b/examples/http-axum-apigw-authorizer/src/main.rs
index 513a6cd8..7a254e88 100644
--- a/examples/http-axum-apigw-authorizer/src/main.rs
+++ b/examples/http-axum-apigw-authorizer/src/main.rs
@@ -7,7 +7,7 @@ use axum::{
     Router,
 };
 use lambda_http::{run, tracing, Error, RequestExt};
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 use std::{collections::HashMap, env::set_var};
 
 struct AuthorizerField(String);
diff --git a/examples/http-axum-middleware/src/main.rs b/examples/http-axum-middleware/src/main.rs
index b1e92811..b9f8672d 100644
--- a/examples/http-axum-middleware/src/main.rs
+++ b/examples/http-axum-middleware/src/main.rs
@@ -12,7 +12,7 @@
 use axum::{response::Json, routing::post, Router};
 use lambda_http::request::RequestContext::ApiGatewayV1;
 use lambda_http::{run, tracing, Error};
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 
 // Sample middleware that logs the request id
 async fn mw_sample(req: axum::extract::Request, next: axum::middleware::Next) -> impl axum::response::IntoResponse {
diff --git a/examples/http-axum/src/main.rs b/examples/http-axum/src/main.rs
index dcd5d154..df8f7a70 100644
--- a/examples/http-axum/src/main.rs
+++ b/examples/http-axum/src/main.rs
@@ -16,7 +16,7 @@ use axum::{
 };
 use lambda_http::{run, tracing, Error};
 use serde::{Deserialize, Serialize};
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 use std::env::set_var;
 
 #[derive(Deserialize, Serialize)]
diff --git a/examples/lambda-rds-iam-auth/src/main.rs b/examples/lambda-rds-iam-auth/src/main.rs
index 32cf3580..4e523591 100644
--- a/examples/lambda-rds-iam-auth/src/main.rs
+++ b/examples/lambda-rds-iam-auth/src/main.rs
@@ -5,7 +5,7 @@ use aws_sigv4::{
     sign::v4,
 };
 use lambda_runtime::{run, service_fn, Error, LambdaEvent};
-use serde_json::{json, Value};
+use aws_lambda_json_impl::{json, Value};
 use sqlx::postgres::PgConnectOptions;
 use std::env;
 use std::time::{Duration, SystemTime};
diff --git a/json-impl/Cargo.toml b/json-impl/Cargo.toml
new file mode 100644
index 00000000..56ee590d
--- /dev/null
+++ b/json-impl/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "aws_lambda_json_impl"
+version = "0.15.1"
+description = "AWS Lambda JSON adapter switch between serde_json and simd_json"
+authors = [
+  "Martin Bartmett <martin.j.bartmett@gmail.com>",
+]
+license = "MIT"
+homepage = "https://github.com/awslabs/aws-lambda-rust-runtime"
+repository = "https://github.com/awslabs/aws-lambda-rust-runtime"
+readme = "README.md"
+keywords = ["lambda", "aws", "amazon", "events", "S3", "json"]
+categories = ["api-bindings", "encoding", "web-programming"]
+edition = "2021"
+
+[features]
+default = [ ]
+simd = [ "simd-json/ordered-float", "value-trait/ordered-float" ]
+
+[dependencies]
+serde_json = { version = "^1", features = ["raw_value"] }
+#simd-json = { version = "^0", optional = true }
+simd-json = { git = "https://github.com/simd-lite/simd-json.git", branch = "main", optional = true }
+value-trait = { version = "^0", optional = true }
+bytes = { workspace = true }
+serde = { version = "^1", no-default-features = true }
diff --git a/json-impl/src/lib.rs b/json-impl/src/lib.rs
new file mode 100644
index 00000000..bc3e09c2
--- /dev/null
+++ b/json-impl/src/lib.rs
@@ -0,0 +1,93 @@
+// Using serde_json as the JSON handler
+#[cfg(not(feature = "simd"))]
+pub use serde::*;
+// Using simd_json as the JSON handler
+#[cfg(feature = "simd")]
+pub use simd::*;
+
+// Implementations
+
+#[cfg(not(feature = "simd"))]
+mod serde {
+    use bytes::Bytes;
+    use serde::de::DeserializeOwned;
+    pub use serde_json::{
+        self, error::Error as JsonError, from_reader, from_slice, from_str, from_value, json, to_string,
+        to_string_pretty, to_value, to_writer, value::RawValue, Deserializer as JsonDeserializer, Value,
+        to_vec,
+    };
+    pub fn from_bytes<T>(b: Bytes) -> serde_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        from_slice(&b)
+    }
+
+    pub fn from_string<T>(s: String) -> serde_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        from_str(s.as_str())
+    }
+    
+    pub fn from_vec<T>(v: Vec<u8>) -> serde_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        from_slice(&v)
+    }
+}
+
+#[cfg(feature = "simd")]
+mod simd {
+    use bytes::Bytes;
+    use serde::de::DeserializeOwned;
+    pub use simd_json::{
+        self,
+        json,
+        owned::Value,
+        serde::{
+            from_owned_value as from_value,
+            from_reader,
+            from_str,   //THIS requires a mutable string slice AND is unsafe
+            from_slice, //THIS requires a mutable slice!
+            to_owned_value as to_value,
+            to_string,
+            to_string_pretty,
+            to_writer,
+            to_vec,
+        },
+        tape::Value as RawValue, //THIS is gonna be the fun one!
+        Deserializer as JsonDeserializer,
+        Error as JsonError,
+    };
+    pub use value_trait::prelude::*;
+
+    pub fn from_bytes<T>(b: Bytes) -> simd_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        match b.try_into_mut() {
+            Ok(mut b) => from_slice(&mut b),
+            Err(b) => {
+                let mut v = b.to_vec();
+                from_slice(&mut v)
+            }
+        }
+    }
+
+    pub fn from_string<T>(mut s: String) -> simd_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        unsafe{ from_str(s.as_mut_str()) }
+    }
+
+    pub fn from_vec<T>(mut v: Vec<u8>) -> simd_json::Result<T>
+    where
+    T: DeserializeOwned,
+    {
+        from_slice(&mut v)
+    }
+}
+
diff --git a/lambda-events/Cargo.toml b/lambda-events/Cargo.toml
index d9774104..c387f9ce 100644
--- a/lambda-events/Cargo.toml
+++ b/lambda-events/Cargo.toml
@@ -29,11 +29,14 @@ query_map = { version = "^0.7", features = [
 ], optional = true }
 serde = { version = "^1", features = ["derive"] }
 serde_with = { version = "^3", features = ["json"], optional = true }
-serde_json = "^1"
+aws_lambda_json_impl = { path = "../json-impl" }
 serde_dynamo = { version = "^4.1", optional = true }
 
 [features]
 default = [
+
+#  "simd_json",
+
   "activemq",
   "alb",
   "apigw",
@@ -123,3 +126,4 @@ sqs = ["serde_with"]
 streams = []
 documentdb = []
 eventbridge = ["chrono", "serde_with"]
+simd_json = [ "aws_lambda_json_impl/simd" ]
diff --git a/lambda-events/src/custom_serde/codebuild_time.rs b/lambda-events/src/custom_serde/codebuild_time.rs
index 07bd0a5c..81105017 100644
--- a/lambda-events/src/custom_serde/codebuild_time.rs
+++ b/lambda-events/src/custom_serde/codebuild_time.rs
@@ -78,14 +78,14 @@ mod tests {
             #[serde(with = "str_time")]
             pub date: TestTime,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "date": "Sep 1, 2017 4:12:29 PM"
         });
 
         let expected = NaiveDateTime::parse_from_str("Sep 1, 2017 4:12:29 PM", CODEBUILD_TIME_FORMAT)
             .unwrap()
             .and_utc();
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.date);
     }
 
@@ -96,14 +96,14 @@ mod tests {
             #[serde(with = "optional_time")]
             pub date: Option<TestTime>,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "date": "Sep 1, 2017 4:12:29 PM"
         });
 
         let expected = NaiveDateTime::parse_from_str("Sep 1, 2017 4:12:29 PM", CODEBUILD_TIME_FORMAT)
             .unwrap()
             .and_utc();
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(Some(expected), decoded.date);
     }
 }
diff --git a/lambda-events/src/custom_serde/headers.rs b/lambda-events/src/custom_serde/headers.rs
index 44884649..5cbbcbf5 100644
--- a/lambda-events/src/custom_serde/headers.rs
+++ b/lambda-events/src/custom_serde/headers.rs
@@ -145,13 +145,13 @@ mod tests {
             #[serde(deserialize_with = "deserialize_headers", default)]
             pub headers: HeaderMap,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "not_headers": {}
         });
 
         let expected = HeaderMap::new();
 
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.headers);
     }
 
@@ -163,16 +163,16 @@ mod tests {
             #[serde(serialize_with = "serialize_multi_value_headers")]
             headers: HeaderMap,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "headers": {
                 "Accept": ["*/*"]
             }
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(&"*/*", decoded.headers.get("Accept").unwrap());
 
-        let recoded = serde_json::to_value(decoded).unwrap();
-        let decoded: Test = serde_json::from_value(recoded).unwrap();
+        let recoded = aws_lambda_json_impl::to_value(decoded).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(recoded).unwrap();
         assert_eq!(&"*/*", decoded.headers.get("Accept").unwrap());
     }
 
@@ -183,9 +183,9 @@ mod tests {
             #[serde(deserialize_with = "deserialize_headers")]
             headers: HeaderMap,
         }
-        let data = serde_json::json!({ "headers": null });
+        let data = aws_lambda_json_impl::json!({ "headers": null });
 
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert!(decoded.headers.is_empty());
     }
 
@@ -203,7 +203,7 @@ mod tests {
 
         let content_disposition =
             "inline; filename=\"Schillers schönste Szenenanweisungen -Kabale und Liebe.mp4.avif\"";
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "headers": {
                 "Content-Disposition": content_disposition
             },
@@ -211,15 +211,15 @@ mod tests {
                 "Content-Disposition": content_disposition
             }
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(content_disposition, decoded.headers.get("Content-Disposition").unwrap());
         assert_eq!(
             content_disposition,
             decoded.multi_value_headers.get("Content-Disposition").unwrap()
         );
 
-        let recoded = serde_json::to_value(decoded).unwrap();
-        let decoded: Test = serde_json::from_value(recoded).unwrap();
+        let recoded = aws_lambda_json_impl::to_value(decoded).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(recoded).unwrap();
         assert_eq!(content_disposition, decoded.headers.get("Content-Disposition").unwrap());
         assert_eq!(
             content_disposition,
diff --git a/lambda-events/src/custom_serde/http_method.rs b/lambda-events/src/custom_serde/http_method.rs
index 42a94dd7..cdf5b16e 100644
--- a/lambda-events/src/custom_serde/http_method.rs
+++ b/lambda-events/src/custom_serde/http_method.rs
@@ -67,13 +67,13 @@ mod tests {
             #[serde(with = "crate::custom_serde::http_method")]
             pub method: http::Method,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "method": "DELETE"
         });
-        let decoded: Test = serde_json::from_value(data.clone()).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data.clone()).unwrap();
         assert_eq!(http::Method::DELETE, decoded.method);
 
-        let recoded = serde_json::to_value(decoded).unwrap();
+        let recoded = aws_lambda_json_impl::to_value(decoded).unwrap();
         assert_eq!(data, recoded);
     }
 
@@ -86,21 +86,21 @@ mod tests {
             #[serde(default)]
             pub method: Option<http::Method>,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "method": "DELETE"
         });
-        let decoded: Test = serde_json::from_value(data.clone()).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data.clone()).unwrap();
         assert_eq!(Some(http::Method::DELETE), decoded.method);
 
-        let recoded = serde_json::to_value(decoded).unwrap();
+        let recoded = aws_lambda_json_impl::to_value(decoded).unwrap();
         assert_eq!(data, recoded);
 
-        let data = serde_json::json!({ "method": null });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let data = aws_lambda_json_impl::json!({ "method": null });
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(None, decoded.method);
 
-        let data = serde_json::json!({});
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let data = aws_lambda_json_impl::json!({});
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(None, decoded.method);
     }
 }
diff --git a/lambda-events/src/custom_serde/mod.rs b/lambda-events/src/custom_serde/mod.rs
index 729dee3d..98ed8a81 100644
--- a/lambda-events/src/custom_serde/mod.rs
+++ b/lambda-events/src/custom_serde/mod.rs
@@ -107,10 +107,10 @@ mod test {
             #[serde(deserialize_with = "deserialize_base64")]
             v: Vec<u8>,
         }
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": "SGVsbG8gV29ybGQ=",
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(String::from_utf8(decoded.v).unwrap(), "Hello World".to_string());
     }
 
@@ -124,7 +124,7 @@ mod test {
         let instance = Test {
             v: "Hello World".as_bytes().to_vec(),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, r#"{"v":"SGVsbG8gV29ybGQ="}"#.to_string());
     }
 
@@ -135,16 +135,16 @@ mod test {
             #[serde(deserialize_with = "deserialize_lambda_map")]
             v: HashMap<String, String>,
         }
-        let input = serde_json::json!({
+        let input = aws_lambda_json_impl::json!({
           "v": {},
         });
-        let decoded: Test = serde_json::from_value(input).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap();
         assert_eq!(HashMap::new(), decoded.v);
 
-        let input = serde_json::json!({
+        let input = aws_lambda_json_impl::json!({
           "v": null,
         });
-        let decoded: Test = serde_json::from_value(input).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap();
         assert_eq!(HashMap::new(), decoded.v);
     }
 
@@ -156,19 +156,20 @@ mod test {
             #[serde(deserialize_with = "deserialize_lambda_dynamodb_item")]
             v: serde_dynamo::Item,
         }
-        let input = serde_json::json!({
+        let input = aws_lambda_json_impl::json!({
           "v": {},
         });
-        let decoded: Test = serde_json::from_value(input).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap();
         assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v);
 
-        let input = serde_json::json!({
+        let input = aws_lambda_json_impl::json!({
           "v": null,
         });
-        let decoded: Test = serde_json::from_value(input).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(input).unwrap();
         assert_eq!(serde_dynamo::Item::from(HashMap::new()), decoded.v);
     }
 
+    #[cfg(not(feature = "simd_json"))]
     #[test]
     fn test_deserialize_nullish_boolean() {
         #[derive(Deserialize)]
@@ -178,19 +179,48 @@ mod test {
         }
 
         let test = r#"{"v": null}"#;
-        let decoded: Test = serde_json::from_str(test).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap();
         assert!(!decoded.v);
 
         let test = r#"{}"#;
-        let decoded: Test = serde_json::from_str(test).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap();
         assert!(!decoded.v);
 
         let test = r#"{"v": true}"#;
-        let decoded: Test = serde_json::from_str(test).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap();
         assert!(decoded.v);
 
         let test = r#"{"v": false}"#;
-        let decoded: Test = serde_json::from_str(test).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_str(test).unwrap();
+        assert!(!decoded.v);
+    }
+    #[cfg(feature = "simd_json")]
+    #[test]
+    fn test_deserialize_nullish_boolean() {
+        //
+        // Let's have some fun! This is how to do SAFE from_str with simd_json
+        //
+
+        #[derive(Deserialize)]
+        struct Test {
+            #[serde(default, deserialize_with = "deserialize_nullish_boolean")]
+            v: bool,
+        }
+
+        let test = r#"{"v": null}"#.to_owned();
+        let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap();
+        assert!(!decoded.v);
+
+        let test = r#"{}"#.to_owned();
+        let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap();
+        assert!(!decoded.v);
+
+        let test = r#"{"v": true}"#.to_owned();
+        let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap();
+        assert!(decoded.v);
+
+        let test = r#"{"v": false}"#.to_owned();
+        let decoded: Test = aws_lambda_json_impl::from_string(test).unwrap();
         assert!(!decoded.v);
     }
 }
diff --git a/lambda-events/src/encodings/http.rs b/lambda-events/src/encodings/http.rs
index 56cce76a..523c124d 100644
--- a/lambda-events/src/encodings/http.rs
+++ b/lambda-events/src/encodings/http.rs
@@ -304,21 +304,21 @@ mod tests {
     fn serialize_text() {
         let mut map = HashMap::new();
         map.insert("foo", Body::from("bar"));
-        assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":"bar"}"#);
+        assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":"bar"}"#);
     }
 
     #[test]
     fn serialize_binary() {
         let mut map = HashMap::new();
         map.insert("foo", Body::from("bar".as_bytes()));
-        assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":"YmFy"}"#);
+        assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":"YmFy"}"#);
     }
 
     #[test]
     fn serialize_empty() {
         let mut map = HashMap::new();
         map.insert("foo", Body::Empty);
-        assert_eq!(serde_json::to_string(&map).unwrap(), r#"{"foo":null}"#);
+        assert_eq!(aws_lambda_json_impl::to_string(&map).unwrap(), r#"{"foo":null}"#);
     }
 
     #[test]
diff --git a/lambda-events/src/encodings/time.rs b/lambda-events/src/encodings/time.rs
index d4903360..24856416 100644
--- a/lambda-events/src/encodings/time.rs
+++ b/lambda-events/src/encodings/time.rs
@@ -215,6 +215,10 @@ where
 #[cfg(test)]
 #[allow(deprecated)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
     use chrono::TimeZone;
 
@@ -228,19 +232,20 @@ mod test {
         let expected = Utc.ymd(2017, 10, 5).and_hms_nano(15, 33, 44, 302_000_000);
 
         // Test parsing strings.
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": "1507217624302",
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
         // Test parsing ints.
-        let decoded: Test = serde_json::from_slice(r#"{"v":1507217624302}"#.as_bytes()).unwrap();
+        let mut test = r#"{"v":1507217624302}"#.as_bytes().to_vec();
+        let decoded: Test = aws_lambda_json_impl::from_slice(test.as_mut_slice()).unwrap();
         assert_eq!(expected, decoded.v,);
         // Test parsing floats.
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": 1507217624302.0,
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
     }
 
@@ -254,7 +259,7 @@ mod test {
         let instance = Test {
             v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99_888_777),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":"427683600099"}"#));
     }
 
@@ -270,21 +275,21 @@ mod test {
         let instance = Test {
             v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 99),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":"427683600"}"#));
 
         // Make sure milliseconds are included.
         let instance = Test {
             v: Utc.ymd(1983, 7, 22).and_hms_nano(1, 0, 0, 2_000_000),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":"427683600.002"}"#));
 
         // Make sure leap seconds are included.
         let instance = Test {
             v: Utc.ymd(1983, 7, 22).and_hms_nano(23, 59, 59, 1_999_999_999),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":"427766400.999"}"#));
     }
 
@@ -298,16 +303,16 @@ mod test {
 
         let expected = TimeDelta::try_seconds(36).unwrap();
 
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": 36,
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
 
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": 36.1,
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
     }
 
@@ -321,7 +326,7 @@ mod test {
         let instance = Test {
             v: TimeDelta::try_seconds(36).unwrap(),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":36}"#));
     }
 
@@ -335,16 +340,16 @@ mod test {
 
         let expected = TimeDelta::try_minutes(36).unwrap();
 
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": 36,
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
 
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "v": 36.1,
         });
-        let decoded: Test = serde_json::from_value(data).unwrap();
+        let decoded: Test = aws_lambda_json_impl::from_value(data).unwrap();
         assert_eq!(expected, decoded.v,);
     }
 
@@ -358,7 +363,7 @@ mod test {
         let instance = Test {
             v: TimeDelta::try_minutes(36).unwrap(),
         };
-        let encoded = serde_json::to_string(&instance).unwrap();
+        let encoded = aws_lambda_json_impl::to_string(&instance).unwrap();
         assert_eq!(encoded, String::from(r#"{"v":36}"#));
     }
 }
diff --git a/lambda-events/src/event/activemq/mod.rs b/lambda-events/src/event/activemq/mod.rs
index 89cfda1c..de2b0752 100644
--- a/lambda-events/src/event/activemq/mod.rs
+++ b/lambda-events/src/event/activemq/mod.rs
@@ -52,15 +52,19 @@ pub struct ActiveMqDestination {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
     use super::*;
 
     #[test]
     #[cfg(feature = "activemq")]
     fn example_activemq_event() {
-        let data = include_bytes!("../../fixtures/example-activemq-event.json");
-        let parsed: ActiveMqEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ActiveMqEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let data = include_bytes!("../../fixtures/example-activemq-event.json").to_vec();
+        let mut data = data.to_vec();
+        let parsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ActiveMqEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/alb/mod.rs b/lambda-events/src/event/alb/mod.rs
index 3b4ce9d5..67644a5a 100644
--- a/lambda-events/src/event/alb/mod.rs
+++ b/lambda-events/src/event/alb/mod.rs
@@ -69,35 +69,40 @@ pub struct AlbTargetGroupResponse {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "alb")]
     fn example_alb_lambda_target_request_headers_only() {
-        let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-headers-only.json");
-        let parsed: AlbTargetGroupRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AlbTargetGroupRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-request-headers-only.json").to_vec();
+        let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "alb")]
     fn example_alb_lambda_target_request_multivalue_headers() {
-        let data = include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json");
-        let parsed: AlbTargetGroupRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AlbTargetGroupRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-alb-lambda-target-request-multivalue-headers.json").to_vec();
+        let parsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AlbTargetGroupRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "alb")]
     fn example_alb_lambda_target_response() {
-        let data = include_bytes!("../../fixtures/example-alb-lambda-target-response.json");
-        let parsed: AlbTargetGroupResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AlbTargetGroupResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-alb-lambda-target-response.json").to_vec();
+        let parsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AlbTargetGroupResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs
index e0aa1e8c..7e907200 100644
--- a/lambda-events/src/event/apigw/mod.rs
+++ b/lambda-events/src/event/apigw/mod.rs
@@ -6,10 +6,10 @@ use crate::{
     encodings::Body,
     iam::IamPolicyStatement,
 };
+use aws_lambda_json_impl::Value;
 use http::{HeaderMap, Method};
 use query_map::QueryMap;
 use serde::{de::DeserializeOwned, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
-use serde_json::Value;
 use std::collections::HashMap;
 
 /// `ApiGatewayProxyRequest` contains data coming from the API Gateway proxy
@@ -779,213 +779,235 @@ pub fn serialize_authorizer_fields<S: Serializer>(
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
     use super::*;
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_request_type_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json");
-        let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request-type-request.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_request_type_request_websocket() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json");
-        let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-websocket-request.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerRequestTypeRequest =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerRequestTypeRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json");
-        let parsed: ApiGatewayCustomAuthorizerRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-request.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_response() {
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json");
-        let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_response_with_single_value_action() {
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json");
-        let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-action.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_custom_auth_response_with_single_value_resource() {
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json");
-        let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-single-value-resource.json")
+                .to_vec();
+        let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-request.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-request.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_response() {
-        let data = include_bytes!("../../fixtures/example-apigw-response.json");
-        let parsed: ApiGatewayProxyResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-response.json").to_vec();
+        let parsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayProxyResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_request_multi_value_parameters() {
-        let data = include_bytes!("../../fixtures/example-apigw-request-multi-value-parameters.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
-        assert_eq!(parsed, reparsed);
+        let mut data = include_bytes!("../../fixtures/example-apigw-request-multi-value-parameters.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let output = aws_lambda_json_impl::to_string(&parsed).unwrap();
 
         assert!(output.contains(r#""multiValueQueryStringParameters":{"name":["me","me2"]}"#));
         assert!(output.contains(r#""queryStringParameters":{"name":"me"}"#));
         assert!(output.contains(r#""headername":["headerValue","headerValue2"]"#));
         assert!(output.contains(r#""headername":"headerValue2""#));
+
+        let mut output = output.into_bytes();
+        let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
+        assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_restapi_openapi_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-restapi-openapi-request.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-restapi-openapi-request.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_request_iam() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-request-iam.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-iam.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_request_jwt_authorizer() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-request-jwt-authorizer.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-jwt-authorizer.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_request_lambda_authorizer() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-request-lambda-authorizer.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-lambda-authorizer.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_request_multi_value_parameters() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
-        assert_eq!(parsed, reparsed);
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-multi-value-parameters.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let output = aws_lambda_json_impl::to_string(&parsed).unwrap();
 
         assert!(output.contains(r#""header2":"value1,value2""#));
         assert!(output.contains(r#""queryStringParameters":{"Parameter1":"value1,value2"}"#));
+
+        let mut output = output.into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
+        assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_request_no_authorizer() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_websocket_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-websocket-request.json");
-        let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request.json").to_vec();
+        let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayWebsocketProxyRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_console_test_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-console-test-request.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-console-test-request.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_websocket_request_without_method() {
-        let data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json");
-        let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-without-method.json").to_vec();
+        let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayWebsocketProxyRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_websocket_request_disconnect_route() {
-        let data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json");
-        let parsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayWebsocketProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-websocket-request-disconnect-route.json").to_vec();
+        let parsed: ApiGatewayWebsocketProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayWebsocketProxyRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_custom_authorizer_v1_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v1-request.json");
-        let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2httpRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v1-request.json").to_vec();
+        let parsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2httpRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
         assert_eq!("REQUEST", parsed.kind.unwrap());
         assert_eq!(Method::GET, parsed.http_method);
@@ -994,51 +1016,64 @@ mod test {
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_custom_authorizer_v2_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json");
-        let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request.json").to_vec();
+        let parsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_custom_authorizer_v2_request_without_cookies() {
-        let data = include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json");
-        let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-cookies.json")
+                .to_vec();
+        let parsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_v2_custom_authorizer_v2_request_without_identity_source() {
-        let data =
-            include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json");
-        let parsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayV2CustomAuthorizerV2Request = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-apigw-v2-custom-authorizer-v2-request-without-identity-source.json")
+                .to_vec();
+        let parsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayV2CustomAuthorizerV2Request =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_console_request() {
-        let data = include_bytes!("../../fixtures/example-apigw-console-request.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayProxyRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-console-request.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "apigw")]
     fn example_apigw_request_authorizer_fields() {
-        let data = include_bytes!("../../fixtures/example-apigw-request.json");
-        let parsed: ApiGatewayProxyRequest = serde_json::from_slice(data).unwrap();
+        #[cfg(feature = "simd_json")]
+        use aws_lambda_json_impl::simd_json::base::ValueAsScalar;
+
+        let mut data = include_bytes!("../../fixtures/example-apigw-request.json").to_vec();
+        let parsed: ApiGatewayProxyRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         let fields = parsed.request_context.authorizer.fields;
+
         assert_eq!(Some("admin"), fields.get("principalId").unwrap().as_str());
         assert_eq!(Some(1), fields.get("clientId").unwrap().as_u64());
         assert_eq!(Some("Exata"), fields.get("clientName").unwrap().as_str());
@@ -1049,10 +1084,11 @@ mod test {
     fn example_apigw_custom_auth_response_with_statement_condition() {
         use crate::iam::IamPolicyEffect;
 
-        let data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json");
-        let parsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ApiGatewayCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-apigw-custom-auth-response-with-condition.json").to_vec();
+        let parsed: ApiGatewayCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ApiGatewayCustomAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
 
         let statement = parsed.policy_document.statement.first().unwrap();
diff --git a/lambda-events/src/event/appsync/mod.rs b/lambda-events/src/event/appsync/mod.rs
index 63f9ac74..52eaee26 100644
--- a/lambda-events/src/event/appsync/mod.rs
+++ b/lambda-events/src/event/appsync/mod.rs
@@ -1,5 +1,5 @@
+use aws_lambda_json_impl::Value;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 use crate::custom_serde::deserialize_lambda_map;
@@ -119,45 +119,50 @@ where
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "appsync")]
     fn example_appsync_identity_cognito() {
-        let data = include_bytes!("../../fixtures/example-appsync-identity-cognito.json");
-        let parsed: AppSyncCognitoIdentity = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AppSyncCognitoIdentity = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-appsync-identity-cognito.json").to_vec();
+        let parsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AppSyncCognitoIdentity = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "appsync")]
     fn example_appsync_identity_iam() {
-        let data = include_bytes!("../../fixtures/example-appsync-identity-iam.json");
-        let parsed: AppSyncIamIdentity = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AppSyncIamIdentity = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-appsync-identity-iam.json").to_vec();
+        let parsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AppSyncIamIdentity = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "appsync")]
     fn example_appsync_lambda_auth_request() {
-        let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-request.json");
-        let parsed: AppSyncLambdaAuthorizerRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AppSyncLambdaAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-appsync-lambda-auth-request.json").to_vec();
+        let parsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AppSyncLambdaAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "appsync")]
     fn example_appsync_lambda_auth_response() {
-        let data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json");
-        let parsed: AppSyncLambdaAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AppSyncLambdaAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-appsync-lambda-auth-response.json").to_vec();
+        let parsed: AppSyncLambdaAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AppSyncLambdaAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/autoscaling/mod.rs b/lambda-events/src/event/autoscaling/mod.rs
index 601e8774..b354aa5a 100644
--- a/lambda-events/src/event/autoscaling/mod.rs
+++ b/lambda-events/src/event/autoscaling/mod.rs
@@ -1,6 +1,6 @@
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 use crate::custom_serde::deserialize_lambda_map;
@@ -45,65 +45,69 @@ where
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_launch_successful() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-successful.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-launch-successful.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_launch_unsuccessful() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-launch-unsuccessful.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-launch-unsuccessful.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_lifecycle_action() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-lifecycle-action.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-lifecycle-action.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_terminate_action() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-action.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-action.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_terminate_successful() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-successful.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-successful.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "autoscaling")]
     fn example_autoscaling_event_terminate_unsuccessful() {
-        let data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-unsuccessful.json");
-        let parsed: AutoScalingEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AutoScalingEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-autoscaling-event-terminate-unsuccessful.json").to_vec();
+        let parsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AutoScalingEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/bedrock_agent_runtime/mod.rs b/lambda-events/src/event/bedrock_agent_runtime/mod.rs
index c1425b85..2c19b2d6 100644
--- a/lambda-events/src/event/bedrock_agent_runtime/mod.rs
+++ b/lambda-events/src/event/bedrock_agent_runtime/mod.rs
@@ -82,34 +82,39 @@ pub struct Agent {
 
 #[cfg(test)]
 mod tests {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
 
     use crate::event::bedrock_agent_runtime::AgentEvent;
 
     #[test]
     #[cfg(feature = "bedrock_agent_runtime")]
     fn example_bedrock_agent_runtime_event() {
-        let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event.json");
-        let parsed: AgentEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event.json").to_vec();
+        let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
     #[test]
     #[cfg(feature = "bedrock_agent_runtime")]
     fn example_bedrock_agent_runtime_event_without_parameters() {
-        let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json");
-        let parsed: AgentEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-parameters.json").to_vec();
+        let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
     #[test]
     #[cfg(feature = "bedrock_agent_runtime")]
     fn example_bedrock_agent_runtime_event_without_request_body() {
-        let data = include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json");
-        let parsed: AgentEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AgentEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-bedrock-agent-runtime-event-without-request-body.json").to_vec();
+        let parsed: AgentEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AgentEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/clientvpn/mod.rs b/lambda-events/src/event/clientvpn/mod.rs
index 163abe72..9a1eda6a 100644
--- a/lambda-events/src/event/clientvpn/mod.rs
+++ b/lambda-events/src/event/clientvpn/mod.rs
@@ -47,15 +47,20 @@ pub struct ClientVpnConnectionHandlerResponse {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "clientvpn")]
     fn example_clientvpn_connectionhandler_request() {
-        let data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json");
-        let parsed: ClientVpnConnectionHandlerRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ClientVpnConnectionHandlerRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-clientvpn-connectionhandler-request.json").to_vec();
+        let parsed: ClientVpnConnectionHandlerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ClientVpnConnectionHandlerRequest =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cloudformation/mod.rs b/lambda-events/src/event/cloudformation/mod.rs
index 44156b97..97184806 100644
--- a/lambda-events/src/event/cloudformation/mod.rs
+++ b/lambda-events/src/event/cloudformation/mod.rs
@@ -1,5 +1,5 @@
+use aws_lambda_json_impl::Value;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 pub mod provider;
@@ -100,6 +100,10 @@ pub enum CloudFormationCustomResourceResponseStatus {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use std::collections::HashMap;
 
     use super::{CloudFormationCustomResourceRequest::*, *};
@@ -116,55 +120,60 @@ mod test {
 
     #[test]
     fn example_cloudformation_custom_resource_create_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-create-request.json").to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Create(_) => (),
             _ => panic!("expected Create request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_cloudformation_custom_resource_update_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-update-request.json").to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Update(_) => (),
             _ => panic!("expected Update request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_cloudformation_custom_resource_delete_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-delete-request.json").to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Delete(_) => (),
             _ => panic!("expected Delete request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_cloudformation_custom_resource_response() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json");
-        let parsed: CloudFormationCustomResourceResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CloudFormationCustomResourceResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-response.json").to_vec();
+        let parsed: CloudFormationCustomResourceResponse =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CloudFormationCustomResourceResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cloudformation/provider.rs b/lambda-events/src/event/cloudformation/provider.rs
index a1594eb4..a5bd2107 100644
--- a/lambda-events/src/event/cloudformation/provider.rs
+++ b/lambda-events/src/event/cloudformation/provider.rs
@@ -4,8 +4,8 @@
 //!
 //! See https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html for details.
 
+use aws_lambda_json_impl::Value;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 
 #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
 #[serde(tag = "RequestType")]
@@ -88,6 +88,10 @@ where
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use std::collections::HashMap;
 
     use super::{CloudFormationCustomResourceRequest::*, *};
@@ -104,55 +108,64 @@ mod test {
 
     #[test]
     fn example_create_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-create-request.json")
+                .to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Create(_) => (),
             _ => panic!("expected Create request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_update_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-update-request.json")
+                .to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Update(_) => (),
             _ => panic!("expected Update request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_delete_request() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json");
-        let parsed: TestRequest = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-delete-request.json")
+                .to_vec();
+        let parsed: TestRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         match parsed {
             Delete(_) => (),
             _ => panic!("expected Delete request"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: TestRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: TestRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_response() {
-        let data = include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json");
-        let parsed: CloudFormationCustomResourceResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CloudFormationCustomResourceResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudformation-custom-resource-provider-response.json").to_vec();
+        let parsed: CloudFormationCustomResourceResponse =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CloudFormationCustomResourceResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cloudwatch_alarms/mod.rs b/lambda-events/src/event/cloudwatch_alarms/mod.rs
index 01174566..1e6b220d 100644
--- a/lambda-events/src/event/cloudwatch_alarms/mod.rs
+++ b/lambda-events/src/event/cloudwatch_alarms/mod.rs
@@ -1,12 +1,12 @@
 use std::collections::HashMap;
 
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{
     de::{DeserializeOwned, Visitor},
     ser::Error as SerError,
     Deserialize, Serialize,
 };
-use serde_json::Value;
 
 /// `CloudWatchAlarm` is the generic outer structure of an event triggered by a CloudWatch Alarm.
 /// You probably want to use `CloudWatchMetricAlarm` or `CloudWatchCompositeAlarm` if you know which kind of alarm your function is receiving.
@@ -220,9 +220,9 @@ impl Serialize for CloudWatchAlarmStateReasonData {
         S: serde::Serializer,
     {
         let r = match self {
-            Self::Metric(m) => serde_json::to_string(m),
-            Self::Composite(m) => serde_json::to_string(m),
-            Self::Generic(m) => serde_json::to_string(m),
+            Self::Metric(m) => aws_lambda_json_impl::to_string(m),
+            Self::Composite(m) => aws_lambda_json_impl::to_string(m),
+            Self::Generic(m) => aws_lambda_json_impl::to_string(m),
         };
         let s = r.map_err(|e| SerError::custom(format!("failed to serialize struct as string {}", e)))?;
 
@@ -243,10 +243,15 @@ impl<'de> Visitor<'de> for ReasonDataVisitor {
     where
         E: serde::de::Error,
     {
-        if let Ok(metric) = serde_json::from_str::<CloudWatchAlarmStateReasonDataMetric>(v) {
+        let mut v_mut = v.to_owned().into_bytes();
+        if let Ok(metric) =
+            aws_lambda_json_impl::from_slice::<CloudWatchAlarmStateReasonDataMetric>(v_mut.as_mut_slice())
+        {
             return Ok(CloudWatchAlarmStateReasonData::Metric(metric));
         }
-        if let Ok(aggregate) = serde_json::from_str::<ClodWatchAlarmStateReasonDataComposite>(v) {
+        if let Ok(aggregate) =
+            aws_lambda_json_impl::from_slice::<ClodWatchAlarmStateReasonDataComposite>(v_mut.as_mut_slice())
+        {
             return Ok(CloudWatchAlarmStateReasonData::Composite(aggregate));
         }
         Ok(CloudWatchAlarmStateReasonData::Generic(Value::String(v.to_owned())))
@@ -255,13 +260,17 @@ impl<'de> Visitor<'de> for ReasonDataVisitor {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "cloudwatch_alarms")]
     fn example_cloudwatch_alarm_metric() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-metric.json");
-        let parsed: CloudWatchMetricAlarm = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-metric.json").to_vec();
+        let parsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         let state = parsed.alarm_data.previous_state.clone().unwrap();
         let data = state.reason_data.unwrap();
         match &data {
@@ -272,16 +281,16 @@ mod test {
             _ => panic!("unexpected reason data {data:?}"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CloudWatchMetricAlarm = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CloudWatchMetricAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cloudwatch_alarms")]
     fn example_cloudwatch_alarm_composite() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite.json");
-        let parsed: CloudWatchCompositeAlarm = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite.json").to_vec();
+        let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         let state = parsed.alarm_data.state.clone().unwrap();
         let data = state.reason_data.unwrap();
@@ -296,16 +305,17 @@ mod test {
             _ => panic!("unexpected reason data {data:?}"),
         }
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CloudWatchCompositeAlarm = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cloudwatch_alarms")]
     fn example_cloudwatch_alarm_composite_with_suppressor_alarm() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json");
-        let parsed: CloudWatchCompositeAlarm = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudwatch-alarm-composite-with-suppressor-alarm.json").to_vec();
+        let parsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         let state = parsed.alarm_data.state.clone().unwrap();
         assert_eq!("WaitPeriod", state.actions_suppressed_by.unwrap());
         assert_eq!(
@@ -313,8 +323,8 @@ mod test {
             state.actions_suppressed_reason.unwrap()
         );
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CloudWatchCompositeAlarm = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CloudWatchCompositeAlarm = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs
index fc332306..45c65474 100644
--- a/lambda-events/src/event/cloudwatch_events/cloudtrail.rs
+++ b/lambda-events/src/event/cloudwatch_events/cloudtrail.rs
@@ -1,6 +1,6 @@
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{Deserialize, Serialize};
-use serde_json::Value;
 
 #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
 #[serde(rename_all = "camelCase")]
@@ -83,33 +83,37 @@ pub struct UserIdentity {
 
 #[cfg(test)]
 mod tests {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::AWSAPICall;
 
     #[test]
     #[cfg(feature = "cloudwatch_events")]
     fn example_cloudwatch_cloudtrail_unknown_assumed_role() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json");
-        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json").to_vec();
+        let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
     #[test]
     #[cfg(feature = "cloudwatch_events")]
     fn example_cloudwatch_cloudtrail_unknown_federate() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json");
-        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json").to_vec();
+        let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
     #[test]
     #[cfg(feature = "cloudwatch_events")]
     fn example_cloudwatch_cloudtrail_assumed_role() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json");
-        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json").to_vec();
+        let parsed: AWSAPICall = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: AWSAPICall = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cloudwatch_events/mod.rs b/lambda-events/src/event/cloudwatch_events/mod.rs
index 6384406e..dd88e313 100644
--- a/lambda-events/src/event/cloudwatch_events/mod.rs
+++ b/lambda-events/src/event/cloudwatch_events/mod.rs
@@ -1,6 +1,6 @@
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 
 pub mod cloudtrail;
 pub mod codedeploy;
diff --git a/lambda-events/src/event/cloudwatch_events/signin.rs b/lambda-events/src/event/cloudwatch_events/signin.rs
index 1cd73e6e..82090e0f 100644
--- a/lambda-events/src/event/cloudwatch_events/signin.rs
+++ b/lambda-events/src/event/cloudwatch_events/signin.rs
@@ -1,5 +1,5 @@
+use aws_lambda_json_impl::Value;
 use serde::{Deserialize, Serialize};
-use serde_json::Value;
 
 #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
 #[serde(rename_all = "camelCase")]
diff --git a/lambda-events/src/event/cloudwatch_logs/mod.rs b/lambda-events/src/event/cloudwatch_logs/mod.rs
index 0c9ad4a8..73c22343 100644
--- a/lambda-events/src/event/cloudwatch_logs/mod.rs
+++ b/lambda-events/src/event/cloudwatch_logs/mod.rs
@@ -80,8 +80,7 @@ impl<'de> Deserialize<'de> for AwsLogs {
                             })?;
 
                             let bytes = flate2::read::GzDecoder::new(&bytes[..]);
-                            let mut de = serde_json::Deserializer::from_reader(BufReader::new(bytes));
-                            data = Some(LogData::deserialize(&mut de).map_err(Error::custom)?);
+                            data = aws_lambda_json_impl::from_reader(BufReader::new(bytes)).map_err(Error::custom)?;
                         }
                         _ => return Err(Error::unknown_field(key, FIELDS)),
                     }
@@ -105,7 +104,7 @@ impl Serialize for AwsLogs {
         let base = base64::write::EncoderWriter::new(Vec::new(), &base64::engine::general_purpose::STANDARD_NO_PAD);
         let mut gzip = flate2::write::GzEncoder::new(base, flate2::Compression::default());
 
-        serde_json::to_writer(&mut gzip, &self.data).map_err(SeError::custom)?;
+        aws_lambda_json_impl::to_writer(&mut gzip, &self.data).map_err(SeError::custom)?;
         let mut base = gzip.finish().map_err(SeError::custom)?;
         let data = base.finish().map_err(SeError::custom)?;
         let string = std::str::from_utf8(data.as_slice()).map_err(SeError::custom)?;
@@ -118,6 +117,10 @@ impl Serialize for AwsLogs {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
@@ -127,8 +130,8 @@ mod test {
     "awslogs": {
         "data": "H4sIAFETomIAA12Ry27bMBBF9/4KQuiyqsQ36Z2DqEGBGC0sdRUHAS0NExV6uCJVNw3y76Fkx03CFTH3cubwztMChRO14Jy5h+JxD9ESRZerYnW3zvJ8dZVFn4+W/tDBMImYUMaFVDrF5FVs+vuroR/3k56Yg0sa0+4qk0D50MddX8Ev98aa+wFMO3lJinWS0gTT5ObT9arI8uJWM2uUkMCpZIxiorGRtsQMiOXCgHxt5MadK4d67+u++1o3HgYXWt7M4my4nhmOw+7Kph+rg/HlQwBwM1M0W2//c2V/oPPvmzydb7OpriZqygQhFItUa6GlUkymgrNUS5EKpQhRfMpGCEzC/xgWjCpNOBMn8nM3X4fcvWmn2DDnhGNFWXiffvCdtjON3mQ/vm8KtIHfY3j6rVoiEdaxsxZizLSJd4KRWGFrYwIKqBSVMtZu/eU4mCmoJWLii2KodVt/UTcNVOiNJEMdbf0a2n54RHn9DwKYJmh9EYrmLzoJPx2EwfJY33bRmfb5mOjiefECiB5LsVgCAAA="
     }
-}"#;
-        let event: LogsEvent = serde_json::from_str(json).expect("failed to deserialize");
+}"#.to_owned();
+        let event: LogsEvent = aws_lambda_json_impl::from_string(json).expect("failed to deserialize");
 
         let data = event.clone().aws_logs.data;
         assert_eq!("DATA_MESSAGE", data.message_type);
@@ -145,18 +148,19 @@ mod test {
         assert_eq!(1552518348220, data.log_events[0].timestamp);
         assert_eq!("REPORT RequestId: 6234bffe-149a-b642-81ff-2e8e376d8aff\tDuration: 46.84 ms\tBilled Duration: 47 ms \tMemory Size: 192 MB\tMax Memory Used: 72 MB\t\n", data.log_events[0].message);
 
-        let new_json: String = serde_json::to_string_pretty(&event).unwrap();
-        let new_event: LogsEvent = serde_json::from_str(&new_json).expect("failed to deserialize");
+        let mut new_json = aws_lambda_json_impl::to_string_pretty(&event).unwrap().into_bytes();
+        let new_event: LogsEvent =
+            aws_lambda_json_impl::from_slice(new_json.as_mut_slice()).expect("failed to deserialize");
         assert_eq!(new_event, event);
     }
 
     #[test]
     #[cfg(feature = "cloudwatch_logs")]
     fn example_cloudwatch_logs_event() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch_logs-event.json");
-        let parsed: LogsEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: LogsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cloudwatch_logs-event.json").to_vec();
+        let parsed: LogsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: LogsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/code_commit/mod.rs b/lambda-events/src/event/code_commit/mod.rs
index 7d5edfaa..29ad37da 100644
--- a/lambda-events/src/event/code_commit/mod.rs
+++ b/lambda-events/src/event/code_commit/mod.rs
@@ -67,15 +67,19 @@ pub struct CodeCommitReference {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "code_commit")]
     fn example_code_commit_event() {
-        let data = include_bytes!("../../fixtures/example-code_commit-event.json");
-        let parsed: CodeCommitEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeCommitEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-code_commit-event.json").to_vec();
+        let parsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeCommitEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/codebuild/mod.rs b/lambda-events/src/event/codebuild/mod.rs
index d4970f5a..8ec86456 100644
--- a/lambda-events/src/event/codebuild/mod.rs
+++ b/lambda-events/src/event/codebuild/mod.rs
@@ -2,9 +2,9 @@ use crate::{
     custom_serde::{codebuild_time, CodeBuildNumber},
     encodings::{MinuteDuration, SecondDuration},
 };
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 
 pub type CodeBuildPhaseStatus = String;
 
@@ -212,25 +212,29 @@ pub type CodeBuildTime = DateTime<Utc>;
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "codebuild")]
     fn example_codebuild_phase_change() {
-        let data = include_bytes!("../../fixtures/example-codebuild-phase-change.json");
-        let parsed: CodeBuildEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeBuildEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codebuild-phase-change.json").to_vec();
+        let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "codebuild")]
     fn example_codebuild_state_change() {
-        let data = include_bytes!("../../fixtures/example-codebuild-state-change.json");
-        let parsed: CodeBuildEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeBuildEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codebuild-state-change.json").to_vec();
+        let parsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeBuildEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/codedeploy/mod.rs b/lambda-events/src/event/codedeploy/mod.rs
index d51bf8aa..cffd5939 100644
--- a/lambda-events/src/event/codedeploy/mod.rs
+++ b/lambda-events/src/event/codedeploy/mod.rs
@@ -74,39 +74,43 @@ pub struct CodeDeployLifecycleEvent {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "codedeploy")]
     fn example_codedeploy_lifecycle_event() {
-        let data = include_bytes!("../../fixtures/example-codedeploy-lifecycle-event.json");
-        let parsed: CodeDeployLifecycleEvent = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codedeploy-lifecycle-event.json").to_vec();
+        let parsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert_eq!(parsed.deployment_id, "d-deploymentId".to_string());
         assert_eq!(parsed.lifecycle_event_hook_execution_id, "eyJlbmNyeXB0ZWREYXRhIjoiY3VHU2NjdkJXUTJQUENVd2dkYUNGRVg0dWlpME9UWVdHTVhZcDRXVW5LYUVKc21EaUFPMkNLNXMwMWFrNDlYVStlbXdRb29xS3NJTUNVQ3RYRGFZSXc1VTFwUllvMDhmMzdlbDZFeDVVdjZrNFc0eU5waGh6YTRvdkNWcmVveVR6OWdERlM2SmlIYW1TZz09IiwiaXZQYXJhbWV0ZXJTcGVjIjoiTm1ZNFR6RzZxQVhHamhhLyIsIm1hdGVyaWFsU2V0U2VyaWFsIjoxfQ==".to_string());
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeDeployLifecycleEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeDeployLifecycleEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "codedeploy")]
     fn example_codedeploy_deployment_event() {
-        let data = include_bytes!("../../fixtures/example-codedeploy-deployment-event.json");
-        let parsed: CodeDeployEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeDeployEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codedeploy-deployment-event.json").to_vec();
+        let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "codedeploy")]
     fn example_codedeploy_instance_event() {
-        let data = include_bytes!("../../fixtures/example-codedeploy-instance-event.json");
-        let parsed: CodeDeployEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodeDeployEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codedeploy-instance-event.json").to_vec();
+        let parsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodeDeployEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs
index 22db26b1..618809fa 100644
--- a/lambda-events/src/event/codepipeline_cloudwatch/mod.rs
+++ b/lambda-events/src/event/codepipeline_cloudwatch/mod.rs
@@ -79,35 +79,40 @@ pub struct CodePipelineEventDetailType {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "codepipeline_cloudwatch")]
     fn example_codepipeline_action_execution_stage_change_event() {
-        let data = include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json");
-        let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-codepipeline-action-execution-stage-change-event.json").to_vec();
+        let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "codepipeline_cloudwatch")]
     fn example_codepipeline_execution_stage_change_event() {
-        let data = include_bytes!("../../fixtures/example-codepipeline-execution-stage-change-event.json");
-        let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codepipeline-execution-stage-change-event.json").to_vec();
+        let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "codepipeline_cloudwatch")]
     fn example_codepipeline_execution_state_change_event() {
-        let data = include_bytes!("../../fixtures/example-codepipeline-execution-state-change-event.json");
-        let parsed: CodePipelineCloudWatchEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodePipelineCloudWatchEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codepipeline-execution-state-change-event.json").to_vec();
+        let parsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodePipelineCloudWatchEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/codepipeline_job/mod.rs b/lambda-events/src/event/codepipeline_job/mod.rs
index 888e77b7..644c8b8d 100644
--- a/lambda-events/src/event/codepipeline_job/mod.rs
+++ b/lambda-events/src/event/codepipeline_job/mod.rs
@@ -115,15 +115,19 @@ pub struct CodePipelineArtifactCredentials {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "codepipeline_job")]
     fn example_codepipeline_job_event() {
-        let data = include_bytes!("../../fixtures/example-codepipeline_job-event.json");
-        let parsed: CodePipelineJobEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CodePipelineJobEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-codepipeline_job-event.json").to_vec();
+        let parsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CodePipelineJobEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/cognito/mod.rs b/lambda-events/src/event/cognito/mod.rs
index a0ebd8d9..aae7dd9e 100644
--- a/lambda-events/src/event/cognito/mod.rs
+++ b/lambda-events/src/event/cognito/mod.rs
@@ -1,5 +1,5 @@
+use aws_lambda_json_impl::Value;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 use crate::custom_serde::{deserialize_lambda_map, deserialize_nullish_boolean};
@@ -630,233 +630,279 @@ pub struct CognitoEventUserPoolsCustomMessageResponse {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event() {
-        let data = include_bytes!("../../fixtures/example-cognito-event.json");
-        let parsed: CognitoEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event.json").to_vec();
+        let parsed: CognitoEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_create_auth_challenge() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json");
-        let parsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge.json").to_vec();
+        let parsed: CognitoEventUserPoolsCreateAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsCreateAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_create_auth_challenge_user_not_found() {
-        let data =
-            include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json");
-        let parsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-create-auth-challenge-user-not-found.json")
+                .to_vec();
+        let parsed: CognitoEventUserPoolsCreateAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(parsed.request.user_not_found);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsCreateAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsCreateAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_custommessage() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json");
-        let parsed: CognitoEventUserPoolsCustomMessage = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsCustomMessage = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-custommessage.json").to_vec();
+        let parsed: CognitoEventUserPoolsCustomMessage = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsCustomMessage =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_define_auth_challenge() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json");
-        let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge.json").to_vec();
+        let parsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_define_auth_challenge_optional_response_fields() {
-        let data = include_bytes!(
+        let mut data = include_bytes!(
             "../../fixtures/example-cognito-event-userpools-define-auth-challenge-optional-response-fields.json"
-        );
-        let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap();
+        )
+        .to_vec();
+        let parsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(!parsed.response.fail_authentication);
         assert!(!parsed.response.issue_tokens);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_define_auth_challenge_user_not_found() {
-        let data =
-            include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json");
-        let parsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-define-auth-challenge-user-not-found.json")
+                .to_vec();
+        let parsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(parsed.request.user_not_found);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsDefineAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsDefineAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_migrateuser() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json");
-        let parsed: CognitoEventUserPoolsMigrateUser = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsMigrateUser = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-migrateuser.json").to_vec();
+        let parsed: CognitoEventUserPoolsMigrateUser = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsMigrateUser =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_postauthentication() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json");
-        let parsed: CognitoEventUserPoolsPostAuthentication = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPostAuthentication = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-postauthentication.json").to_vec();
+        let parsed: CognitoEventUserPoolsPostAuthentication =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPostAuthentication =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_postconfirmation() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json");
-        let parsed: CognitoEventUserPoolsPostConfirmation = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPostConfirmation = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-postconfirmation.json").to_vec();
+        let parsed: CognitoEventUserPoolsPostConfirmation =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPostConfirmation =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_preauthentication() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json");
-        let parsed: CognitoEventUserPoolsPreAuthentication = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreAuthentication = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-preauthentication.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreAuthentication =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreAuthentication =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_presignup() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-presignup.json");
-        let parsed: CognitoEventUserPoolsPreSignup = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreSignup = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-presignup.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreSignup = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_pretokengen_incoming() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json");
-        let parsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-incoming.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreTokenGen =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_pretokengen_v2_incoming() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json");
-        let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2-incoming.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreTokenGenV2 =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_pretokengen() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json");
-        let parsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreTokenGen = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreTokenGen = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreTokenGen =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_v2_pretokengen() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json");
-        let parsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsPreTokenGenV2 = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-cognito-event-userpools-pretokengen-v2.json").to_vec();
+        let parsed: CognitoEventUserPoolsPreTokenGenV2 = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsPreTokenGenV2 =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_verify_auth_challenge() {
-        let data = include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json");
-        let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge.json").to_vec();
+        let parsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_verify_auth_challenge_optional_answer_correct() {
-        let data = include_bytes!(
+        let mut data = include_bytes!(
             "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-optional-answer-correct.json"
-        );
-        let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap();
+        )
+        .to_vec();
+        let parsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(!parsed.response.answer_correct);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_verify_auth_challenge_null_answer_correct() {
-        let data = include_bytes!(
+        let mut data = include_bytes!(
             "../../fixtures/example-cognito-event-userpools-verify-auth-challenge-null-answer-correct.json"
-        );
-        let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap();
+        )
+        .to_vec();
+        let parsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(!parsed.response.answer_correct);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "cognito")]
     fn example_cognito_event_userpools_verify_auth_challenge_user_not_found() {
-        let data =
-            include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json");
-        let parsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cognito-event-userpools-verify-auth-challenge-user-not-found.json")
+                .to_vec();
+        let parsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert!(parsed.request.user_not_found);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: CognitoEventUserPoolsVerifyAuthChallenge =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
@@ -893,9 +939,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsPreSignupTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -906,9 +953,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsPreAuthenticationTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -922,9 +970,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsPostConfirmationTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -935,9 +984,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsPostAuthenticationTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -948,9 +998,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsDefineAuthChallengeTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -962,9 +1013,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsCreateAuthChallengeTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -975,9 +1027,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsVerifyAuthChallengeTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -994,9 +1047,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsPreTokenGenTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -1007,9 +1061,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsMigrateUserTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
@@ -1028,9 +1083,10 @@ mod trigger_source_tests {
         possible_triggers.into_iter().for_each(|trigger| {
             let header = gen_header(trigger);
             let parsed: CognitoEventUserPoolsHeader<CognitoEventUserPoolsCustomMessageTriggerSource> =
-                serde_json::from_str(&header).unwrap();
-            let output: String = serde_json::to_string(&parsed).unwrap();
-            let reparsed: CognitoEventUserPoolsHeader<_> = serde_json::from_slice(output.as_bytes()).unwrap();
+                aws_lambda_json_impl::from_string(header).unwrap();
+            let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+            let reparsed: CognitoEventUserPoolsHeader<_> =
+                aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
             assert_eq!(parsed, reparsed);
         });
     }
diff --git a/lambda-events/src/event/config/mod.rs b/lambda-events/src/event/config/mod.rs
index 7c06e13b..10ea4f3d 100644
--- a/lambda-events/src/event/config/mod.rs
+++ b/lambda-events/src/event/config/mod.rs
@@ -38,15 +38,19 @@ pub struct ConfigEvent {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "config")]
     fn example_config_event() {
-        let data = include_bytes!("../../fixtures/example-config-event.json");
-        let parsed: ConfigEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ConfigEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-config-event.json").to_vec();
+        let parsed: ConfigEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ConfigEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/connect/mod.rs b/lambda-events/src/event/connect/mod.rs
index 04f26eb5..91e8e3be 100644
--- a/lambda-events/src/event/connect/mod.rs
+++ b/lambda-events/src/event/connect/mod.rs
@@ -92,25 +92,29 @@ pub type ConnectResponse = HashMap<String, String>;
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "connect")]
     fn example_connect_event() {
-        let data = include_bytes!("../../fixtures/example-connect-event.json");
-        let parsed: ConnectEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ConnectEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-connect-event.json").to_vec();
+        let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "connect")]
     fn example_connect_event_without_queue() {
-        let data = include_bytes!("../../fixtures/example-connect-event-without-queue.json");
-        let parsed: ConnectEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: ConnectEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-connect-event-without-queue.json").to_vec();
+        let parsed: ConnectEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: ConnectEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/documentdb/events/commom_types.rs b/lambda-events/src/event/documentdb/events/commom_types.rs
index 5d1bdc19..2488d333 100644
--- a/lambda-events/src/event/documentdb/events/commom_types.rs
+++ b/lambda-events/src/event/documentdb/events/commom_types.rs
@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 
+use aws_lambda_json_impl::Value;
 use serde::{Deserialize, Serialize};
-use serde_json::Value;
 
 pub type AnyDocument = HashMap<String, Value>;
 
diff --git a/lambda-events/src/event/documentdb/mod.rs b/lambda-events/src/event/documentdb/mod.rs
index 67f7c9ad..a973f984 100644
--- a/lambda-events/src/event/documentdb/mod.rs
+++ b/lambda-events/src/event/documentdb/mod.rs
@@ -38,14 +38,19 @@ pub struct DocumentDbEvent {
 #[cfg(test)]
 #[cfg(feature = "documentdb")]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     pub type Event = DocumentDbEvent;
 
     fn test_example(data: &[u8]) {
-        let parsed: Event = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: Event = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = data.to_vec();
+        let parsed: Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
 
         assert_eq!(parsed, reparsed);
     }
diff --git a/lambda-events/src/event/dynamodb/attributes.rs b/lambda-events/src/event/dynamodb/attributes.rs
index e1a42c83..6bae4f80 100644
--- a/lambda-events/src/event/dynamodb/attributes.rs
+++ b/lambda-events/src/event/dynamodb/attributes.rs
@@ -8,59 +8,59 @@ mod test {
 
     #[test]
     fn test_null_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "NULL": true
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::Null(true) => {}
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_string_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "S": "value"
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::S(ref s) => assert_eq!("value", s.as_str()),
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_number_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "N": "123.45"
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::N(ref n) => assert_eq!("123.45", n.as_str()),
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_binary_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "B": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk"
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::B(ref b) => {
                 let expected = base64::engine::general_purpose::STANDARD
@@ -71,33 +71,33 @@ mod test {
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_boolean_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "BOOL": true
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::Bool(b) => assert!(b),
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_string_set_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "SS": ["Giraffe", "Hippo" ,"Zebra"]
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::Ss(ref s) => {
                 let expected = vec!["Giraffe", "Hippo", "Zebra"];
@@ -106,17 +106,17 @@ mod test {
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_number_set_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "NS": ["42.2", "-19", "7.5", "3.14"]
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::Ns(ref s) => {
                 let expected = vec!["42.2", "-19", "7.5", "3.14"];
@@ -125,17 +125,17 @@ mod test {
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_binary_set_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "BS": ["U3Vubnk=", "UmFpbnk=", "U25vd3k="]
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::Bs(ref s) => {
                 let expected = vec!["U3Vubnk=", "UmFpbnk=", "U25vd3k="]
@@ -147,17 +147,17 @@ mod test {
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_attribute_list_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "L": [ {"S": "Cookies"} , {"S": "Coffee"}, {"N": "3.14159"}]
         });
 
-        let attr: AttributeValue = serde_json::from_value(value.clone()).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value.clone()).unwrap();
         match attr {
             AttributeValue::L(ref s) => {
                 let expected = vec![
@@ -170,17 +170,17 @@ mod test {
             other => panic!("unexpected value {:?}", other),
         }
 
-        let reparsed = serde_json::to_value(attr).unwrap();
+        let reparsed = aws_lambda_json_impl::to_value(attr).unwrap();
         assert_eq!(value, reparsed);
     }
 
     #[test]
     fn test_attribute_map_attribute() {
-        let value = serde_json::json!({
+        let value = aws_lambda_json_impl::json!({
             "M": {"Name": {"S": "Joe"}, "Age": {"N": "35"}}
         });
 
-        let attr: AttributeValue = serde_json::from_value(value).unwrap();
+        let attr: AttributeValue = aws_lambda_json_impl::from_value(value).unwrap();
         match attr {
             AttributeValue::M(s) => {
                 let mut expected = HashMap::new();
diff --git a/lambda-events/src/event/dynamodb/mod.rs b/lambda-events/src/event/dynamodb/mod.rs
index 2a3d7558..834ef44a 100644
--- a/lambda-events/src/event/dynamodb/mod.rs
+++ b/lambda-events/src/event/dynamodb/mod.rs
@@ -253,16 +253,20 @@ pub struct StreamRecord {
 #[cfg(test)]
 #[allow(deprecated)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
     use chrono::TimeZone;
 
     #[test]
     #[cfg(feature = "dynamodb")]
     fn example_dynamodb_event() {
-        let data = include_bytes!("../../fixtures/example-dynamodb-event.json");
-        let mut parsed: Event = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: Event = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-dynamodb-event.json").to_vec();
+        let mut parsed: Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
 
         let event = parsed.records.pop().unwrap();
@@ -273,10 +277,11 @@ mod test {
     #[test]
     #[cfg(feature = "dynamodb")]
     fn example_dynamodb_event_with_optional_fields() {
-        let data = include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json");
-        let parsed: EventRecord = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: EventRecord = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-dynamodb-event-record-with-optional-fields.json").to_vec();
+        let parsed: EventRecord = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: EventRecord = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
         let date = Utc.timestamp_micros(0).unwrap(); // 1970-01-01T00:00:00Z
         assert_eq!(date, reparsed.change.approximate_creation_date_time);
diff --git a/lambda-events/src/event/ecr_scan/mod.rs b/lambda-events/src/event/ecr_scan/mod.rs
index 5502e81a..0cb02937 100644
--- a/lambda-events/src/event/ecr_scan/mod.rs
+++ b/lambda-events/src/event/ecr_scan/mod.rs
@@ -65,25 +65,30 @@ pub struct EcrScanEventFindingSeverityCounts {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "ecr_scan")]
     fn example_ecr_image_scan_event() {
-        let data = include_bytes!("../../fixtures/example-ecr-image-scan-event.json");
-        let parsed: EcrScanEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: EcrScanEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-ecr-image-scan-event.json").to_vec();
+        let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "ecr_scan")]
     fn example_ecr_image_scan_event_with_missing_severities() {
-        let data = include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json");
-        let parsed: EcrScanEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: EcrScanEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-ecr-image-scan-event-with-missing-severities.json").to_vec();
+        let parsed: EcrScanEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: EcrScanEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/eventbridge/mod.rs b/lambda-events/src/event/eventbridge/mod.rs
index 7756e0e4..3287d3db 100644
--- a/lambda-events/src/event/eventbridge/mod.rs
+++ b/lambda-events/src/event/eventbridge/mod.rs
@@ -1,6 +1,6 @@
+use aws_lambda_json_impl::Value;
 use chrono::{DateTime, Utc};
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 
 /// Parse EventBridge events.
 /// Deserialize the event detail into a structure that's `DeserializeOwned`.
@@ -35,6 +35,10 @@ where
 #[cfg(test)]
 #[cfg(feature = "eventbridge")]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
@@ -47,27 +51,28 @@ mod test {
         }
 
         // Example from https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instance-state-changes.html
-        let data = include_bytes!("../../fixtures/example-eventbridge-event-obj.json");
-        let parsed: EventBridgeEvent<Ec2StateChange> = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-eventbridge-event-obj.json").to_vec();
+        let parsed: EventBridgeEvent<Ec2StateChange> = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert_eq!("i-abcd1111", parsed.detail.instance_id);
         assert_eq!("pending", parsed.detail.state);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: EventBridgeEvent<Ec2StateChange> = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: EventBridgeEvent<Ec2StateChange> =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     fn example_eventbridge_schedule_event() {
-        let data = include_bytes!("../../fixtures/example-eventbridge-schedule.json");
-        let parsed: EventBridgeEvent = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-eventbridge-schedule.json").to_vec();
+        let parsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert_eq!("aws.events", parsed.source);
         assert_eq!("Scheduled Event", parsed.detail_type);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: EventBridgeEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: EventBridgeEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/firehose/mod.rs b/lambda-events/src/event/firehose/mod.rs
index 6a0a13fd..c557e598 100644
--- a/lambda-events/src/event/firehose/mod.rs
+++ b/lambda-events/src/event/firehose/mod.rs
@@ -74,15 +74,19 @@ pub struct KinesisFirehoseRecordMetadata {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "firehose")]
     fn example_firehose_event() {
-        let data = include_bytes!("../../fixtures/example-firehose-event.json");
-        let parsed: KinesisFirehoseEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: KinesisFirehoseEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-firehose-event.json").to_vec();
+        let parsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: KinesisFirehoseEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/iam/mod.rs b/lambda-events/src/event/iam/mod.rs
index 36f59c7b..76b11606 100644
--- a/lambda-events/src/event/iam/mod.rs
+++ b/lambda-events/src/event/iam/mod.rs
@@ -129,7 +129,7 @@ mod tests {
 
     #[test]
     fn test_deserialize_string_condition() {
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "condition": {
                 "StringEquals": {
                     "iam:RegisterSecurityKey": "Activate",
@@ -144,7 +144,7 @@ mod tests {
             condition: Option<IamPolicyCondition>,
         }
 
-        let test: Test = serde_json::from_value(data).unwrap();
+        let test: Test = aws_lambda_json_impl::from_value(data).unwrap();
         let condition = test.condition.unwrap();
         assert_eq!(1, condition.len());
 
@@ -154,7 +154,7 @@ mod tests {
 
     #[test]
     fn test_deserialize_slide_condition() {
-        let data = serde_json::json!({
+        let data = aws_lambda_json_impl::json!({
             "condition": {"StringLike": {"s3:prefix": ["janedoe/*"]}}
         });
 
@@ -164,7 +164,7 @@ mod tests {
             condition: Option<IamPolicyCondition>,
         }
 
-        let test: Test = serde_json::from_value(data).unwrap();
+        let test: Test = aws_lambda_json_impl::from_value(data).unwrap();
         let condition = test.condition.unwrap();
         assert_eq!(1, condition.len());
 
@@ -179,11 +179,11 @@ mod tests {
             resource: vec!["some:resource".into()],
             condition: None,
         };
-        let policy_ser = serde_json::to_value(policy).unwrap();
+        let policy_ser = aws_lambda_json_impl::to_value(policy).unwrap();
 
         assert_eq!(
             policy_ser,
-            serde_json::json!({
+            aws_lambda_json_impl::json!({
                 "Action": ["some:action"],
                 "Effect": "Allow",
                 "Resource": ["some:resource"]
diff --git a/lambda-events/src/event/iot/mod.rs b/lambda-events/src/event/iot/mod.rs
index 3835b515..9c9b41e7 100644
--- a/lambda-events/src/event/iot/mod.rs
+++ b/lambda-events/src/event/iot/mod.rs
@@ -72,25 +72,30 @@ pub struct IoTCoreCustomAuthorizerResponse {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "iot")]
     fn example_iot_custom_auth_request() {
-        let data = include_bytes!("../../fixtures/example-iot-custom-auth-request.json");
-        let parsed: IoTCoreCustomAuthorizerRequest = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: IoTCoreCustomAuthorizerRequest = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-iot-custom-auth-request.json").to_vec();
+        let parsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: IoTCoreCustomAuthorizerRequest = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "iot")]
     fn example_iot_custom_auth_response() {
-        let data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json");
-        let parsed: IoTCoreCustomAuthorizerResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: IoTCoreCustomAuthorizerResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-iot-custom-auth-response.json").to_vec();
+        let parsed: IoTCoreCustomAuthorizerResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: IoTCoreCustomAuthorizerResponse =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/iot_1_click/mod.rs b/lambda-events/src/event/iot_1_click/mod.rs
index bf010b50..e7965316 100644
--- a/lambda-events/src/event/iot_1_click/mod.rs
+++ b/lambda-events/src/event/iot_1_click/mod.rs
@@ -58,15 +58,19 @@ pub struct IoTOneClickPlacementInfo {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "iot_1_click")]
     fn example_iot_1_click_event() {
-        let data = include_bytes!("../../fixtures/example-iot_1_click-event.json");
-        let parsed: IoTOneClickEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: IoTOneClickEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-iot_1_click-event.json").to_vec();
+        let parsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: IoTOneClickEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/iot_button/mod.rs b/lambda-events/src/event/iot_button/mod.rs
index 2d2e4627..5c80e386 100644
--- a/lambda-events/src/event/iot_button/mod.rs
+++ b/lambda-events/src/event/iot_button/mod.rs
@@ -13,15 +13,19 @@ pub struct IoTButtonEvent {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "iot_button")]
     fn example_iot_button_event() {
-        let data = include_bytes!("../../fixtures/example-iot_button-event.json");
-        let parsed: IoTButtonEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: IoTButtonEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-iot_button-event.json").to_vec();
+        let parsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: IoTButtonEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/kafka/mod.rs b/lambda-events/src/event/kafka/mod.rs
index 27a1e921..b3dc2138 100644
--- a/lambda-events/src/event/kafka/mod.rs
+++ b/lambda-events/src/event/kafka/mod.rs
@@ -33,15 +33,19 @@ pub struct KafkaRecord {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "kafka")]
     fn example_kafka_event() {
-        let data = include_bytes!("../../fixtures/example-kafka-event.json");
-        let parsed: KafkaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: KafkaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-kafka-event.json").to_vec();
+        let parsed: KafkaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: KafkaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/kinesis/event.rs b/lambda-events/src/event/kinesis/event.rs
index fac80e07..080039e8 100644
--- a/lambda-events/src/event/kinesis/event.rs
+++ b/lambda-events/src/event/kinesis/event.rs
@@ -84,29 +84,33 @@ pub enum KinesisEncryptionType {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "kinesis")]
     fn example_kinesis_event() {
-        let data = include_bytes!("../../fixtures/example-kinesis-event.json");
-        let parsed: KinesisEvent = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-kinesis-event.json").to_vec();
+        let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         assert_eq!(KinesisEncryptionType::None, parsed.records[0].kinesis.encryption_type);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: KinesisEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "kinesis")]
     fn example_kinesis_event_encrypted() {
-        let data = include_bytes!("../../fixtures/example-kinesis-event-encrypted.json");
-        let parsed: KinesisEvent = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-kinesis-event-encrypted.json").to_vec();
+        let parsed: KinesisEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         assert_eq!(KinesisEncryptionType::Kms, parsed.records[0].kinesis.encryption_type);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: KinesisEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: KinesisEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/lex/mod.rs b/lambda-events/src/event/lex/mod.rs
index d8f9403c..7f5e0901 100644
--- a/lambda-events/src/event/lex/mod.rs
+++ b/lambda-events/src/event/lex/mod.rs
@@ -106,25 +106,29 @@ pub struct Attachment {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "lex")]
     fn example_lex_event() {
-        let data = include_bytes!("../../fixtures/example-lex-event.json");
-        let parsed: LexEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-lex-event.json").to_vec();
+        let parsed: LexEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "lex")]
     fn example_lex_response() {
-        let data = include_bytes!("../../fixtures/example-lex-response.json");
-        let parsed: LexEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-lex-response.json").to_vec();
+        let parsed: LexEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: LexEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/rabbitmq/mod.rs b/lambda-events/src/event/rabbitmq/mod.rs
index 23327276..aea63631 100644
--- a/lambda-events/src/event/rabbitmq/mod.rs
+++ b/lambda-events/src/event/rabbitmq/mod.rs
@@ -1,5 +1,5 @@
+use aws_lambda_json_impl::Value;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 use crate::custom_serde::deserialize_lambda_map;
@@ -60,15 +60,19 @@ where
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "rabbitmq")]
     fn example_rabbitmq_event() {
-        let data = include_bytes!("../../fixtures/example-rabbitmq-event.json");
-        let parsed: RabbitMqEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: RabbitMqEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-rabbitmq-event.json").to_vec();
+        let parsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: RabbitMqEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/s3/event.rs b/lambda-events/src/event/s3/event.rs
index e062c7d2..1aaff157 100644
--- a/lambda-events/src/event/s3/event.rs
+++ b/lambda-events/src/event/s3/event.rs
@@ -90,25 +90,29 @@ pub struct S3Object {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_s3_event() {
-        let data = include_bytes!("../../fixtures/example-s3-event.json");
-        let parsed: S3Event = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3Event = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-s3-event.json").to_vec();
+        let parsed: S3Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_s3_event_with_decoded() {
-        let data = include_bytes!("../../fixtures/example-s3-event-with-decoded.json");
-        let parsed: S3Event = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3Event = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-s3-event-with-decoded.json").to_vec();
+        let parsed: S3Event = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3Event = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/s3/object_lambda.rs b/lambda-events/src/event/s3/object_lambda.rs
index 2abcc797..04a83c4c 100644
--- a/lambda-events/src/event/s3/object_lambda.rs
+++ b/lambda-events/src/event/s3/object_lambda.rs
@@ -1,6 +1,6 @@
+use aws_lambda_json_impl::Value;
 use http::HeaderMap;
 use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use serde_json::Value;
 use std::collections::HashMap;
 
 use crate::custom_serde::{deserialize_headers, serialize_headers};
@@ -117,55 +117,61 @@ pub struct SessionIssuer {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_object_lambda_event_get_object_assumed_role() {
-        let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json");
-        let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-assumed-role.json").to_vec();
+        let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_object_lambda_event_get_object_iam() {
-        let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json");
-        let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-get-object-iam.json").to_vec();
+        let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_object_lambda_event_head_object_iam() {
-        let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json");
-        let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-head-object-iam.json").to_vec();
+        let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_object_lambda_event_list_objects_iam() {
-        let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json");
-        let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-iam.json").to_vec();
+        let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "s3")]
     fn example_object_lambda_event_list_objects_v2_iam() {
-        let data = include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json");
-        let parsed: S3ObjectLambdaEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: S3ObjectLambdaEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-s3-object-lambda-event-list-objects-v2-iam.json").to_vec();
+        let parsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: S3ObjectLambdaEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/secretsmanager/mod.rs b/lambda-events/src/event/secretsmanager/mod.rs
index 3ed8d238..9a28abec 100644
--- a/lambda-events/src/event/secretsmanager/mod.rs
+++ b/lambda-events/src/event/secretsmanager/mod.rs
@@ -10,15 +10,20 @@ pub struct SecretsManagerSecretRotationEvent {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "secretsmanager")]
     fn example_secretsmanager_secret_rotation_event() {
-        let data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json");
-        let parsed: SecretsManagerSecretRotationEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SecretsManagerSecretRotationEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-secretsmanager-secret-rotation-event.json").to_vec();
+        let parsed: SecretsManagerSecretRotationEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SecretsManagerSecretRotationEvent =
+            aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/ses/mod.rs b/lambda-events/src/event/ses/mod.rs
index 2a60957a..f98f149d 100644
--- a/lambda-events/src/event/ses/mod.rs
+++ b/lambda-events/src/event/ses/mod.rs
@@ -120,35 +120,39 @@ pub struct SimpleEmailDisposition {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "ses")]
     fn example_ses_lambda_event() {
-        let data = include_bytes!("../../fixtures/example-ses-lambda-event.json");
-        let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-ses-lambda-event.json").to_vec();
+        let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "ses")]
     fn example_ses_s3_event() {
-        let data = include_bytes!("../../fixtures/example-ses-s3-event.json");
-        let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-ses-s3-event.json").to_vec();
+        let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "ses")]
     fn example_ses_sns_event() {
-        let data = include_bytes!("../../fixtures/example-ses-sns-event.json");
-        let parsed: SimpleEmailEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SimpleEmailEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-ses-sns-event.json").to_vec();
+        let parsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SimpleEmailEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/sns/mod.rs b/lambda-events/src/event/sns/mod.rs
index 0fda569d..36bc2e6b 100644
--- a/lambda-events/src/event/sns/mod.rs
+++ b/lambda-events/src/event/sns/mod.rs
@@ -248,41 +248,54 @@ pub struct CloudWatchDimension {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "sns")]
     fn my_example_sns_event() {
-        let data = include_bytes!("../../fixtures/example-sns-event.json");
-        let parsed: SnsEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sns-event.json").to_vec();
+        let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "sns")]
     fn my_example_sns_event_pascal_case() {
-        let data = include_bytes!("../../fixtures/example-sns-event-pascal-case.json");
-        let parsed: SnsEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sns-event-pascal-case.json").to_vec();
+        let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "sns")]
     fn my_example_sns_event_cloudwatch_single_metric() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json");
-        let parsed: SnsEvent = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec();
+        
+        let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         assert_eq!(1, parsed.records.len());
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
 
+        //
+        // Without this, the test fails when using simd_json - precisely because simd_json needs a
+        // MUTABLE reference and it WILL modify the slice!
+        //
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-single-metric.json").to_vec();
+        
         let parsed: SnsEventObj<CloudWatchAlarmPayload> =
-            serde_json::from_slice(data).expect("failed to parse CloudWatch Alarm payload");
+            aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to parse CloudWatch Alarm payload");
 
         let record = parsed.records.first().unwrap();
         assert_eq!("EXAMPLE", record.sns.message.alarm_name);
@@ -291,19 +304,20 @@ mod test {
     #[test]
     #[cfg(feature = "sns")]
     fn my_example_sns_event_cloudwatch_multiple_metrics() {
-        let data = include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json");
-        let parsed: SnsEvent = serde_json::from_slice(data).unwrap();
+        let mut data =
+            include_bytes!("../../fixtures/example-cloudwatch-alarm-sns-payload-multiple-metrics.json").to_vec();
+        let parsed: SnsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         assert_eq!(2, parsed.records.len());
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SnsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SnsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
     #[test]
     #[cfg(feature = "sns")]
     fn my_example_sns_obj_event() {
-        let data = include_bytes!("../../fixtures/example-sns-event-obj.json");
+        let mut data = include_bytes!("../../fixtures/example-sns-event-obj.json").to_vec();
 
         #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
         struct CustStruct {
@@ -311,14 +325,14 @@ mod test {
             bar: i32,
         }
 
-        let parsed: SnsEventObj<CustStruct> = serde_json::from_slice(data).unwrap();
+        let parsed: SnsEventObj<CustStruct> = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
         println!("{:?}", parsed);
 
         assert_eq!(parsed.records[0].sns.message.foo, "Hello world!");
         assert_eq!(parsed.records[0].sns.message.bar, 123);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SnsEventObj<CustStruct> = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SnsEventObj<CustStruct> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/event/sqs/mod.rs b/lambda-events/src/event/sqs/mod.rs
index 9dd69f66..90929bc5 100644
--- a/lambda-events/src/event/sqs/mod.rs
+++ b/lambda-events/src/event/sqs/mod.rs
@@ -180,15 +180,19 @@ pub struct SqsApiMessage {
 
 #[cfg(test)]
 mod test {
+    // To save on boiler plate, JSON data is parsed from a mut byte slice rather than an &str. The slice isn't actually mutated
+    // when using serde-json, but it IS when using simd-json - so we also take care not to reuse the slice
+    // once it has been deserialized.
+
     use super::*;
 
     #[test]
     #[cfg(feature = "sqs")]
     fn example_sqs_event() {
-        let data = include_bytes!("../../fixtures/example-sqs-event.json");
-        let parsed: SqsEvent = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SqsEvent = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sqs-event.json").to_vec();
+        let parsed: SqsEvent = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SqsEvent = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
@@ -201,14 +205,14 @@ mod test {
             b: u32,
         }
 
-        let data = include_bytes!("../../fixtures/example-sqs-event-obj.json");
-        let parsed: SqsEventObj<CustStruct> = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sqs-event-obj.json").to_vec();
+        let parsed: SqsEventObj<CustStruct> = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert_eq!(parsed.records[0].body.a, "Test");
         assert_eq!(parsed.records[0].body.b, 123);
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SqsEventObj<CustStruct> = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SqsEventObj<CustStruct> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
@@ -217,10 +221,10 @@ mod test {
     fn example_sqs_batch_response() {
         // Example sqs batch response fetched 2022-05-13, from:
         // https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting
-        let data = include_bytes!("../../fixtures/example-sqs-batch-response.json");
-        let parsed: SqsBatchResponse = serde_json::from_slice(data).unwrap();
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SqsBatchResponse = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sqs-batch-response.json").to_vec();
+        let parsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SqsBatchResponse = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 
@@ -235,14 +239,14 @@ mod test {
             country: String,
         }
 
-        let data = include_bytes!("../../fixtures/example-sqs-api-event-obj.json");
-        let parsed: SqsApiEventObj<CustStruct> = serde_json::from_slice(data).unwrap();
+        let mut data = include_bytes!("../../fixtures/example-sqs-api-event-obj.json").to_vec();
+        let parsed: SqsApiEventObj<CustStruct> = aws_lambda_json_impl::from_slice(data.as_mut_slice()).unwrap();
 
         assert_eq!(parsed.messages[0].body.city, "provincetown");
         assert_eq!(parsed.messages[0].body.country, "usa");
 
-        let output: String = serde_json::to_string(&parsed).unwrap();
-        let reparsed: SqsApiEventObj<CustStruct> = serde_json::from_slice(output.as_bytes()).unwrap();
+        let mut output = aws_lambda_json_impl::to_string(&parsed).unwrap().into_bytes();
+        let reparsed: SqsApiEventObj<CustStruct> = aws_lambda_json_impl::from_slice(output.as_mut_slice()).unwrap();
         assert_eq!(parsed, reparsed);
     }
 }
diff --git a/lambda-events/src/time_window.rs b/lambda-events/src/time_window.rs
index edc9beb5..f6e1a220 100644
--- a/lambda-events/src/time_window.rs
+++ b/lambda-events/src/time_window.rs
@@ -68,12 +68,12 @@ mod test {
 
     #[test]
     fn test_window_deserializer() {
-        let v = serde_json::json!({
+        let v = aws_lambda_json_impl::json!({
             "start": "2020-12-09T07:04:00Z",
             "end": "2020-12-09T07:06:00Z",
         });
 
-        let parsed: Window = serde_json::from_value(v).unwrap();
+        let parsed: Window = aws_lambda_json_impl::from_value(v).unwrap();
         assert_eq!("2020-12-09T07:04:00+00:00", &parsed.start.to_rfc3339());
         assert_eq!("2020-12-09T07:06:00+00:00", &parsed.end.to_rfc3339());
     }
diff --git a/lambda-extension/Cargo.toml b/lambda-extension/Cargo.toml
index 16b6dace..09d7c878 100644
--- a/lambda-extension/Cargo.toml
+++ b/lambda-extension/Cargo.toml
@@ -16,6 +16,7 @@ readme = "README.md"
 [features]
 default = ["tracing"]
 tracing = ["lambda_runtime_api_client/tracing"]
+simd_json = [ "aws_lambda_json_impl/simd" ]
 
 [dependencies]
 async-stream = "0.3"
@@ -27,7 +28,7 @@ hyper = { workspace = true, features = ["http1", "client", "server"] }
 hyper-util = { workspace = true }
 lambda_runtime_api_client = { version = "0.11", path = "../lambda-runtime-api-client" }
 serde = { version = "1", features = ["derive"] }
-serde_json = "^1"
+aws_lambda_json_impl = { path = "../json-impl" }
 tokio = { version = "1.0", features = [
     "macros",
     "io-util",
diff --git a/lambda-extension/src/extension.rs b/lambda-extension/src/extension.rs
index d9717243..9170658c 100644
--- a/lambda-extension/src/extension.rs
+++ b/lambda-extension/src/extension.rs
@@ -396,7 +396,7 @@ where
 
             let body = body.collect().await?.to_bytes();
             trace!("{}", std::str::from_utf8(&body)?); // this may be very verbose
-            let event: NextEvent = serde_json::from_slice(&body)?;
+            let event: NextEvent = aws_lambda_json_impl::from_bytes(body)?;
             let is_invoke = event.is_invoke();
 
             let event = LambdaEvent::new(event);
@@ -541,7 +541,7 @@ async fn register<'a>(
 
     let (_, body) = res.into_parts();
     let body = body.collect().await?.to_bytes();
-    let response: RegisterResponseBody = serde_json::from_slice(&body)?;
+    let response: RegisterResponseBody = aws_lambda_json_impl::from_bytes(body)?;
 
     Ok(RegisterResponse {
         extension_id,
diff --git a/lambda-extension/src/logs.rs b/lambda-extension/src/logs.rs
index c3b0cda2..3c1c5025 100644
--- a/lambda-extension/src/logs.rs
+++ b/lambda-extension/src/logs.rs
@@ -208,7 +208,7 @@ where
                 .unwrap());
         }
     };
-    let logs: Vec<LambdaLog> = match serde_json::from_slice(&body.to_bytes()) {
+    let logs: Vec<LambdaLog> = match aws_lambda_json_impl::from_bytes(body.to_bytes()) {
         Ok(logs) => logs,
         Err(e) => {
             error!("Error parsing logs: {}", e);
@@ -237,7 +237,10 @@ mod tests {
 
     #[test]
     fn deserialize_full() {
-        let data = r#"{"time": "2020-08-20T12:31:32.123Z","type": "function", "record": "hello world"}"#;
+        // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse
+        // with serde_json the slice is not actually mutated
+        // with simd_json it is
+        let mut data = r#"{"time": "2020-08-20T12:31:32.123Z","type": "function", "record": "hello world"}"#.as_bytes().to_vec();
         let expected = LambdaLog {
             time: Utc
                 .with_ymd_and_hms(2020, 8, 20, 12, 31, 32)
@@ -247,7 +250,7 @@ mod tests {
             record: LambdaLogRecord::Function("hello world".to_string()),
         };
 
-        let actual = serde_json::from_str::<LambdaLog>(data).unwrap();
+        let actual = aws_lambda_json_impl::from_slice::<LambdaLog>(data.as_mut_slice()).unwrap();
 
         assert_eq!(expected, actual);
     }
@@ -258,7 +261,11 @@ mod tests {
                 #[test]
                 fn $name() {
                     let (input, expected) = $value;
-                    let actual = serde_json::from_str::<LambdaLog>(&input).expect("unable to deserialize");
+                    // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse
+                    // with serde_json the slice is not actually mutated
+                    // with simd_json it is
+                    let mut input = input.as_bytes().to_vec();
+                    let actual = aws_lambda_json_impl::from_slice::<LambdaLog>(input.as_mut_slice()).expect("unable to deserialize");
 
                     assert!(actual.record == expected);
                 }
diff --git a/lambda-extension/src/requests.rs b/lambda-extension/src/requests.rs
index 522b8402..42d48d4f 100644
--- a/lambda-extension/src/requests.rs
+++ b/lambda-extension/src/requests.rs
@@ -24,7 +24,7 @@ pub(crate) fn next_event_request(extension_id: &str) -> Result<Request<Body>, Er
 }
 
 pub(crate) fn register_request(extension_name: &str, events: &[&str]) -> Result<Request<Body>, Error> {
-    let events = serde_json::json!({ "events": events });
+    let events = aws_lambda_json_impl::json!({ "events": events });
 
     let req = build_request()
         .method(Method::POST)
@@ -32,7 +32,7 @@ pub(crate) fn register_request(extension_name: &str, events: &[&str]) -> Result<
         .header(EXTENSION_NAME_HEADER, extension_name)
         .header(EXTENSION_ACCEPT_FEATURE, EXTENSION_ACCEPT_FEATURE_VALUE)
         .header(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE)
-        .body(Body::from(serde_json::to_string(&events)?))?;
+        .body(Body::from(aws_lambda_json_impl::to_string(&events)?))?;
 
     Ok(req)
 }
@@ -67,7 +67,7 @@ pub(crate) fn subscribe_request(
 ) -> Result<Request<Body>, Error> {
     let types = types.unwrap_or(&["platform", "function"]);
 
-    let data = serde_json::json!({
+    let data = aws_lambda_json_impl::json!({
         "schemaVersion": api.schema_version(),
         "types": types,
         "buffering": buffering.unwrap_or_default(),
@@ -82,7 +82,7 @@ pub(crate) fn subscribe_request(
         .uri(api.uri())
         .header(EXTENSION_ID_HEADER, extension_id)
         .header(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE)
-        .body(Body::from(serde_json::to_string(&data)?))?;
+        .body(Body::from(aws_lambda_json_impl::to_string(&data)?))?;
 
     Ok(req)
 }
@@ -127,7 +127,7 @@ fn error_request(
 
     let body = match request {
         None => Body::empty(),
-        Some(err) => Body::from(serde_json::to_string(&err)?),
+        Some(err) => Body::from(aws_lambda_json_impl::to_string(&err)?),
     };
 
     let req = build_request()
diff --git a/lambda-extension/src/telemetry.rs b/lambda-extension/src/telemetry.rs
index a7760892..e84c4b0b 100644
--- a/lambda-extension/src/telemetry.rs
+++ b/lambda-extension/src/telemetry.rs
@@ -291,7 +291,7 @@ where
         }
     };
 
-    let telemetry: Vec<LambdaTelemetry> = match serde_json::from_slice(&body.to_bytes()) {
+    let telemetry: Vec<LambdaTelemetry> = match aws_lambda_json_impl::from_bytes(body.to_bytes()) {
         Ok(telemetry) => telemetry,
         Err(e) => {
             error!("Error parsing telemetry: {}", e);
@@ -324,7 +324,11 @@ mod deserialization_tests {
                 #[test]
                 fn $name() {
                     let (input, expected) = $value;
-                    let actual = serde_json::from_str::<LambdaTelemetry>(&input).expect("unable to deserialize");
+                    // To avoid lots of complex boilerplate, we use a mutable bytes slice in the parse
+                    // with serde_json the slice is not actually mutated
+                    // with simd_json it is
+                    let mut input = input.as_bytes().to_vec();
+                    let actual = aws_lambda_json_impl::from_slice::<LambdaTelemetry>(input.as_mut_slice()).expect("unable to deserialize");
 
                     assert!(actual.record == expected);
                 }
@@ -482,7 +486,7 @@ mod serialization_tests {
                 #[test]
                 fn $name() {
                     let (input, expected) = $value;
-                    let actual = serde_json::to_string(&input).expect("unable to serialize");
+                    let actual = aws_lambda_json_impl::to_string(&input).expect("unable to serialize");
                     println!("Input: {:?}\n", input);
                     println!("Expected:\n {:?}\n", expected);
                     println!("Actual:\n {:?}\n", actual);
diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml
index 08b70d4e..6a2d48a0 100644
--- a/lambda-http/Cargo.toml
+++ b/lambda-http/Cargo.toml
@@ -27,6 +27,7 @@ opentelemetry = ["lambda_runtime/opentelemetry"] # enables access to the OpenTel
 anyhow = ["lambda_runtime/anyhow"] # enables From<T> for Diagnostic for anyhow error types, see README.md for more info
 eyre = ["lambda_runtime/eyre"] # enables From<T> for Diagnostic for eyre error types, see README.md for more info
 miette = ["lambda_runtime/miette"] # enables From<T> for Diagnostic for miette error types, see README.md for more info
+simd_json = [ "aws_lambda_json_impl/simd", "aws_lambda_events/simd_json", "lambda_runtime/simd_json" ]
 
 [dependencies]
 base64 = { workspace = true }
@@ -43,10 +44,11 @@ mime = "0.3"
 percent-encoding = "2.2"
 pin-project-lite = { workspace = true }
 serde = { version = "1.0", features = ["derive"] }
-serde_json = { version = "1.0", features = ["raw_value"] }
+aws_lambda_json_impl = { path = "../json-impl" }
 serde_urlencoded = "0.7"
 tokio-stream = "0.1.2"
 url = "2.2"
+tracing = "0"
 
 [dependencies.aws_lambda_events]
 path = "../lambda-events"
diff --git a/lambda-http/README.md b/lambda-http/README.md
index 6b394964..3fbd8a5a 100644
--- a/lambda-http/README.md
+++ b/lambda-http/README.md
@@ -45,7 +45,7 @@ The code below creates a simple API Gateway proxy (HTTP, REST) that accepts in i
 ```rust
 use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, IntoResponse, Request, RequestPayloadExt};
 use serde::{Deserialize, Serialize};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 
 #[tokio::main]
 async fn main() -> Result<(), Error> {
@@ -83,7 +83,7 @@ pub struct MyPayload {
 
 ```rust
 use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 
 #[tokio::main]
 async fn main() -> Result<(), Error> {
@@ -124,7 +124,7 @@ use aws_lambda_events::apigw::{
     ApiGatewayCustomAuthorizerRequestTypeRequest, ApiGatewayCustomAuthorizerResponse, ApiGatewayCustomAuthorizerPolicy, IamPolicyStatement,
 };
 use lambda_runtime::{run, service_fn, Error, LambdaEvent};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 
 #[tokio::main]
 async fn main() -> Result<(), Error> {
@@ -183,7 +183,7 @@ One of the [best practices](https://docs.aws.amazon.com/lambda/latest/dg/best-pr
 use aws_sdk_dynamodb::model::AttributeValue;
 use chrono::Utc;
 use lambda_http::{run, http::{StatusCode, Response}, service_fn, Error, RequestExt, IntoResponse, Request};
-use serde_json::json;
+use aws_lambda_json_impl::json;
 
 #[tokio::main]
 async fn main() -> Result<(), Error> {
diff --git a/lambda-http/src/deserializer.rs b/lambda-http/src/deserializer.rs
index 4c0ad519..64f0cd0a 100644
--- a/lambda-http/src/deserializer.rs
+++ b/lambda-http/src/deserializer.rs
@@ -1,167 +1,11 @@
-use crate::request::LambdaRequest;
-#[cfg(feature = "alb")]
-use aws_lambda_events::alb::AlbTargetGroupRequest;
-#[cfg(feature = "apigw_rest")]
-use aws_lambda_events::apigw::ApiGatewayProxyRequest;
-#[cfg(feature = "apigw_http")]
-use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
-#[cfg(feature = "apigw_websockets")]
-use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest;
-use serde::{de::Error, Deserialize};
-use serde_json::value::RawValue;
-
-const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events";
-
-#[cfg(feature = "pass_through")]
-const PASS_THROUGH_ENABLED: bool = true;
-
-impl<'de> Deserialize<'de> for LambdaRequest {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: serde::Deserializer<'de>,
-    {
-        let raw_value: Box<RawValue> = Box::deserialize(deserializer)?;
-        let data = raw_value.get();
-
-        #[cfg(feature = "apigw_rest")]
-        if let Ok(res) = serde_json::from_str::<ApiGatewayProxyRequest>(data) {
-            return Ok(LambdaRequest::ApiGatewayV1(res));
-        }
-        #[cfg(feature = "apigw_http")]
-        if let Ok(res) = serde_json::from_str::<ApiGatewayV2httpRequest>(data) {
-            return Ok(LambdaRequest::ApiGatewayV2(res));
-        }
-        #[cfg(feature = "alb")]
-        if let Ok(res) = serde_json::from_str::<AlbTargetGroupRequest>(data) {
-            return Ok(LambdaRequest::Alb(res));
-        }
-        #[cfg(feature = "apigw_websockets")]
-        if let Ok(res) = serde_json::from_str::<ApiGatewayWebsocketProxyRequest>(data) {
-            return Ok(LambdaRequest::WebSocket(res));
-        }
-        #[cfg(feature = "pass_through")]
-        if PASS_THROUGH_ENABLED {
-            return Ok(LambdaRequest::PassThrough(data.to_string()));
-        }
-
-        Err(Error::custom(ERROR_CONTEXT))
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_deserialize_apigw_rest() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-request.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw rest data");
-        match req {
-            LambdaRequest::ApiGatewayV1(req) => {
-                assert_eq!("12345678912", req.request_context.account_id.unwrap());
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    fn test_deserialize_apigw_http() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw http data");
-        match req {
-            LambdaRequest::ApiGatewayV2(req) => {
-                assert_eq!("123456789012", req.request_context.account_id.unwrap());
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    fn test_deserialize_sam_rest() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize SAM rest data");
-        match req {
-            LambdaRequest::ApiGatewayV1(req) => {
-                assert_eq!("123456789012", req.request_context.account_id.unwrap());
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    fn test_deserialize_sam_http() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-apigw-sam-http-request.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize SAM http data");
-        match req {
-            LambdaRequest::ApiGatewayV2(req) => {
-                assert_eq!("123456789012", req.request_context.account_id.unwrap());
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    fn test_deserialize_alb() {
-        let data = include_bytes!(
-            "../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json"
-        );
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize alb rest data");
-        match req {
-            LambdaRequest::Alb(req) => {
-                assert_eq!(
-                    "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh",
-                    req.request_context.elb.target_group_arn.unwrap()
-                );
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    fn test_deserialize_apigw_websocket() {
-        let data =
-            include_bytes!("../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize apigw websocket data");
-        match req {
-            LambdaRequest::WebSocket(req) => {
-                assert_eq!("CONNECT", req.request_context.event_type.unwrap());
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    #[cfg(feature = "pass_through")]
-    fn test_deserialize_bedrock_agent() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json");
-
-        let req: LambdaRequest =
-            serde_json::from_slice(data).expect("failed to deserialize bedrock agent request data");
-        match req {
-            LambdaRequest::PassThrough(req) => {
-                assert_eq!(String::from_utf8_lossy(data), req);
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-
-    #[test]
-    #[cfg(feature = "pass_through")]
-    fn test_deserialize_sqs() {
-        let data = include_bytes!("../../lambda-events/src/fixtures/example-sqs-event.json");
-
-        let req: LambdaRequest = serde_json::from_slice(data).expect("failed to deserialize sqs event data");
-        match req {
-            LambdaRequest::PassThrough(req) => {
-                assert_eq!(String::from_utf8_lossy(data), req);
-            }
-            other => panic!("unexpected request variant: {:?}", other),
-        }
-    }
-}
+#[cfg(feature = "simd_json")]
+mod deserializer_simd_json;
+#[cfg(feature = "simd_json")]
+#[allow(unused_imports)]
+pub use deserializer_simd_json::*;
+
+#[cfg(not(feature = "simd_json"))]
+mod deserializer_serde_json;
+#[cfg(not(feature = "simd_json"))]
+#[allow(unused_imports)]
+pub use deserializer_serde_json::*;
\ No newline at end of file
diff --git a/lambda-http/src/deserializer/deserializer_serde_json.rs b/lambda-http/src/deserializer/deserializer_serde_json.rs
new file mode 100644
index 00000000..158e2344
--- /dev/null
+++ b/lambda-http/src/deserializer/deserializer_serde_json.rs
@@ -0,0 +1,167 @@
+use crate::request::LambdaRequest;
+#[cfg(feature = "alb")]
+use aws_lambda_events::alb::AlbTargetGroupRequest;
+#[cfg(feature = "apigw_rest")]
+use aws_lambda_events::apigw::ApiGatewayProxyRequest;
+#[cfg(feature = "apigw_http")]
+use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
+#[cfg(feature = "apigw_websockets")]
+use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest;
+use serde::{de::Error, Deserialize};
+use aws_lambda_json_impl::RawValue;
+
+const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events";
+
+#[cfg(feature = "pass_through")]
+const PASS_THROUGH_ENABLED: bool = true;
+
+impl<'de> Deserialize<'de> for LambdaRequest {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::Deserializer<'de>,
+    {
+        let raw_value: Box<RawValue> = Box::deserialize(deserializer)?;
+        let data = raw_value.get();
+
+        #[cfg(feature = "apigw_rest")]
+        if let Ok(res) = aws_lambda_json_impl::from_str::<ApiGatewayProxyRequest>(data) {
+            return Ok(LambdaRequest::ApiGatewayV1(res));
+        }
+        #[cfg(feature = "apigw_http")]
+        if let Ok(res) = aws_lambda_json_impl::from_str::<ApiGatewayV2httpRequest>(data) {
+            return Ok(LambdaRequest::ApiGatewayV2(res));
+        }
+        #[cfg(feature = "alb")]
+        if let Ok(res) = aws_lambda_json_impl::from_str::<AlbTargetGroupRequest>(data) {
+            return Ok(LambdaRequest::Alb(res));
+        }
+        #[cfg(feature = "apigw_websockets")]
+        if let Ok(res) = aws_lambda_json_impl::from_str::<ApiGatewayWebsocketProxyRequest>(data) {
+            return Ok(LambdaRequest::WebSocket(res));
+        }
+        #[cfg(feature = "pass_through")]
+        if PASS_THROUGH_ENABLED {
+            return Ok(LambdaRequest::PassThrough(data.to_string()));
+        }
+
+        Err(Error::custom(ERROR_CONTEXT))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_deserialize_apigw_rest() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-request.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw rest data");
+        match req {
+            LambdaRequest::ApiGatewayV1(req) => {
+                assert_eq!("12345678912", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_apigw_http() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw http data");
+        match req {
+            LambdaRequest::ApiGatewayV2(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_sam_rest() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM rest data");
+        match req {
+            LambdaRequest::ApiGatewayV1(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_sam_http() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-http-request.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize SAM http data");
+        match req {
+            LambdaRequest::ApiGatewayV2(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_alb() {
+        let data = include_bytes!(
+            "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json"
+        );
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize alb rest data");
+        match req {
+            LambdaRequest::Alb(req) => {
+                assert_eq!(
+                    "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh",
+                    req.request_context.elb.target_group_arn.unwrap()
+                );
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_apigw_websocket() {
+        let data =
+            include_bytes!("../../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize apigw websocket data");
+        match req {
+            LambdaRequest::WebSocket(req) => {
+                assert_eq!("CONNECT", req.request_context.event_type.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "pass_through")]
+    fn test_deserialize_bedrock_agent() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json");
+
+        let req: LambdaRequest =
+            aws_lambda_json_impl::from_slice(data).expect("failed to deserialize bedrock agent request data");
+        match req {
+            LambdaRequest::PassThrough(req) => {
+                assert_eq!(String::from_utf8_lossy(data), req);
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "pass_through")]
+    fn test_deserialize_sqs() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-sqs-event.json");
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data).expect("failed to deserialize sqs event data");
+        match req {
+            LambdaRequest::PassThrough(req) => {
+                assert_eq!(String::from_utf8_lossy(data), req);
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+}
diff --git a/lambda-http/src/deserializer/deserializer_simd_json.rs b/lambda-http/src/deserializer/deserializer_simd_json.rs
new file mode 100644
index 00000000..e15deab7
--- /dev/null
+++ b/lambda-http/src/deserializer/deserializer_simd_json.rs
@@ -0,0 +1,219 @@
+use crate::request::LambdaRequest;
+#[cfg(feature = "alb")]
+use aws_lambda_events::alb::AlbTargetGroupRequest;
+#[cfg(feature = "apigw_rest")]
+use aws_lambda_events::apigw::ApiGatewayProxyRequest;
+#[cfg(feature = "apigw_http")]
+use aws_lambda_events::apigw::ApiGatewayV2httpRequest;
+#[cfg(feature = "apigw_websockets")]
+use aws_lambda_events::apigw::ApiGatewayWebsocketProxyRequest;
+use aws_lambda_json_impl::{JsonDeserializer,Writable};
+use serde::{de::Error, Deserialize};
+use tracing::debug;
+
+const ERROR_CONTEXT: &str = "this function expects a JSON payload from Amazon API Gateway, Amazon Elastic Load Balancer, or AWS Lambda Function URLs, but the data doesn't match any of those services' events";
+
+#[cfg(feature = "pass_through")]
+const PASS_THROUGH_ENABLED: bool = true;
+
+
+// simd_json and LambdaRequest don't sit well together due to how the request variant is discovered
+// 
+// To get there, we have to get a bit hacky - we panic if the deserializer we have been offered is not
+// a simd_json::Deserializer (please someone show me a better way if there is one!) because we need the
+// the Tape from it - THEN we can do some peeking to see what's there and try to deduce the type we are
+// looking for.
+//
+impl<'de> Deserialize<'de> for LambdaRequest {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::Deserializer<'de>
+    {
+        
+        // We can't do this because D is not enforced to be 'static
+        //if TypeId::of::<D>() != TypeId::of::<JsonDeserializer<'_>>() {panic!("Deserializer must be simd_json::Deserializer")};
+
+        //
+        // There is a future feature of simd_json being considered that is very similar to serde_json's RawValue - effectively a
+        // Deserializer-implementation-specific way of introspecting/peeking at the parsed JSON before continuing with deserialization.
+        // That's what the serde_json implementation of this uses, but, for now we have to resort to this wildly unsafe cast of the
+        // the incoming D to &mut simd_json::Deserializer.
+        //
+        // HOWEVER... IF we are here, then someone has built this code with the simd_json feature enabled - which means that all KNOWN 
+        // invokers have ALSO been built with simd_json enabled - which means that this is, in fact, "safe"... IF users ONLY exploit the 
+        // standard invokers (i.e. the Lambda Runtime or the standard entry-point functions in aws_lambda_json_impl).
+        // 
+        // If not ... well, expect bad things to happen!
+        //
+        let d = unsafe { &*(&deserializer as *const _ as *mut &mut JsonDeserializer<'de>) };
+
+        // Get a simd_json "raw" Value representing what is in the deserializer;
+        let v = d.as_value();
+
+        // Introspect for the type markers on V2 payloads
+        let (rc_present, http_context, alb_context, websocket_context) = if let Some(rc) = v.get("requestContext") {
+            (true, rc.contains_key("http"), rc.contains_key("elb"), rc.contains_key("connectedAt"))
+        } else {
+            (false, false, false, false)
+        };
+
+        #[cfg(feature = "apigw_rest")]
+        // If it's not a V2 payload, then we try to deserialize a V1 payload
+        if rc_present && !(http_context || alb_context || websocket_context) {
+            debug!("Parsing REST API request");
+            return ApiGatewayProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV1);
+        }
+
+        #[cfg(feature = "apigw_http")]
+        if http_context {
+            debug!("Parsing HTTP API request");
+            return ApiGatewayV2httpRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::ApiGatewayV2);
+        }
+
+        #[cfg(feature = "alb")]
+        if alb_context {
+            debug!("Parsing ALB request");
+            return AlbTargetGroupRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::Alb);   
+        }
+
+        #[cfg(feature = "apigw_websockets")]
+        if websocket_context {
+            debug!("Parsing WebSocket request");
+            return ApiGatewayWebsocketProxyRequest::deserialize(deserializer).map_err(Error::custom).map(LambdaRequest::WebSocket); 
+        }
+
+        #[cfg(feature = "pass_through")]
+        if PASS_THROUGH_ENABLED {
+            let mut buf = Vec::new();
+            v.write(&mut buf).map_err(D::Error::custom)?;
+            let s = String::from_utf8_lossy(&buf);
+            debug!("Defaulting to pass_through");
+            return Ok(LambdaRequest::PassThrough(s.into_owned()));
+        }
+
+        debug!("Failed to find a candidate request type");
+        Err(Error::custom(ERROR_CONTEXT))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_deserialize_apigw_rest() {
+        let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-request.json").to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw rest data");
+        match req {
+            LambdaRequest::ApiGatewayV1(req) => {
+                assert_eq!("12345678912", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_apigw_http() {
+        let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-v2-request-iam.json").to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw http data");
+        match req {
+            LambdaRequest::ApiGatewayV2(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_sam_rest() {
+        let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-rest-request.json").to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize SAM rest data");
+        match req {
+            LambdaRequest::ApiGatewayV1(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_sam_http() {
+        let mut data = include_bytes!("../../../lambda-events/src/fixtures/example-apigw-sam-http-request.json").to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize SAM http data");
+        match req {
+            LambdaRequest::ApiGatewayV2(req) => {
+                assert_eq!("123456789012", req.request_context.account_id.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_alb() {
+        let mut data = include_bytes!(
+            "../../../lambda-events/src/fixtures/example-alb-lambda-target-request-multivalue-headers.json"
+        ).to_vec();
+        
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize alb rest data");
+        match req {
+            LambdaRequest::Alb(req) => {
+                assert_eq!(
+                    "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-target/abcdefgh",
+                    req.request_context.elb.target_group_arn.unwrap()
+                );
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    fn test_deserialize_apigw_websocket() {
+        let mut data =
+            include_bytes!("../../../lambda-events/src/fixtures/example-apigw-websocket-request-without-method.json").to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data.as_mut_slice()).expect("failed to deserialize apigw websocket data");
+        match req {
+            LambdaRequest::WebSocket(req) => {
+                assert_eq!("CONNECT", req.request_context.event_type.unwrap());
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "pass_through")]
+    fn test_deserialize_bedrock_agent() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-bedrock-agent-runtime-event.json");
+        let mut data_vec = data.to_vec();
+
+        let req: LambdaRequest =
+        aws_lambda_json_impl::from_slice(data_vec.as_mut_slice()).expect("failed to deserialize bedrock agent request data");
+        match req {
+            LambdaRequest::PassThrough(req) => {
+                assert_eq!(String::from_utf8_lossy(data).replace(|c: char| c.is_ascii_whitespace(), ""), req);
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "pass_through")]
+    fn test_deserialize_sqs() {
+        let data = include_bytes!("../../../lambda-events/src/fixtures/example-sqs-event.json");
+        let mut data_vec = data.to_vec();
+
+        let req: LambdaRequest = aws_lambda_json_impl::from_slice(data_vec.as_mut_slice()).expect("failed to deserialize sqs event data");
+        match req {
+            LambdaRequest::PassThrough(req) => {
+                //We have to hack a bit
+
+                assert_eq!(String::from_utf8_lossy(data).replace(|c: char| c.is_ascii_whitespace(), ""), req.replace("Message Body","MessageBody"));
+            }
+            other => panic!("unexpected request variant: {:?}", other),
+        }
+    }
+}
diff --git a/lambda-http/src/ext/request.rs b/lambda-http/src/ext/request.rs
index c56518f6..ac27caba 100644
--- a/lambda-http/src/ext/request.rs
+++ b/lambda-http/src/ext/request.rs
@@ -15,7 +15,7 @@ use crate::Body;
 #[derive(Debug)]
 pub enum PayloadError {
     /// Returned when `application/json` bodies fail to deserialize a payload
-    Json(serde_json::Error),
+    Json(aws_lambda_json_impl::JsonError),
     /// Returned when `application/x-www-form-urlencoded` bodies fail to deserialize a payload
     WwwFormUrlEncoded(SerdeError),
 }
@@ -24,7 +24,7 @@ pub enum PayloadError {
 #[derive(Debug)]
 pub enum JsonPayloadError {
     /// Problem deserializing a JSON payload.
-    Parsing(serde_json::Error),
+    Parsing(aws_lambda_json_impl::JsonError),
 }
 
 /// Indicates a problem processing an x-www-form-urlencoded payload.
@@ -244,6 +244,7 @@ impl RequestPayloadExt for http::Request<Body> {
             .unwrap_or_else(|| Ok(None))
     }
 
+    #[cfg(not(feature = "simd_json"))]
     fn json<D>(&self) -> Result<Option<D>, JsonPayloadError>
     where
         D: DeserializeOwned,
@@ -251,7 +252,21 @@ impl RequestPayloadExt for http::Request<Body> {
         if self.body().is_empty() {
             return Ok(None);
         }
-        serde_json::from_slice::<D>(self.body().as_ref())
+        aws_lambda_json_impl::from_slice::<D>(self.body().as_ref())
+            .map(Some)
+            .map_err(JsonPayloadError::Parsing)
+    }
+
+    #[cfg(feature = "simd_json")]
+    fn json<D>(&self) -> Result<Option<D>, JsonPayloadError>
+    where
+        D: DeserializeOwned,
+    {
+        if self.body().is_empty() {
+            return Ok(None);
+        }
+        let mut body = self.body().to_vec();
+        aws_lambda_json_impl::from_slice::<D>(body.as_mut_slice())
             .map(Some)
             .map_err(JsonPayloadError::Parsing)
     }
@@ -512,7 +527,7 @@ mod tests {
         assert!(payload.is_err());
 
         if let Err(JsonPayloadError::Parsing(err)) = payload {
-            assert!(err.is_syntax())
+            assert!(err.is_syntax(), "Error should be syntax: {:?}", err)
         } else {
             panic!(
                 "{}",
@@ -529,7 +544,7 @@ mod tests {
         let result = request.json::<Payload>();
 
         if let Err(JsonPayloadError::Parsing(err)) = result {
-            assert!(err.is_data())
+            assert!(err.is_data(), "Error should be data: {:?}", err)
         } else {
             panic!(
                 "{}",
diff --git a/lambda-http/src/request.rs b/lambda-http/src/request.rs
index a9281b46..58ca664d 100644
--- a/lambda-http/src/request.rs
+++ b/lambda-http/src/request.rs
@@ -27,12 +27,10 @@ use aws_lambda_events::apigw::{ApiGatewayV2httpRequest, ApiGatewayV2httpRequestC
 use aws_lambda_events::apigw::{ApiGatewayWebsocketProxyRequest, ApiGatewayWebsocketProxyRequestContext};
 use aws_lambda_events::{encodings::Body, query_map::QueryMap};
 use http::{header::HeaderName, HeaderMap, HeaderValue};
-
 use serde::{Deserialize, Serialize};
-use serde_json::error::Error as JsonError;
-
 use std::{env, future::Future, io::Read, pin::Pin};
 use url::Url;
+use aws_lambda_json_impl::JsonError;
 
 /// Internal representation of an Lambda http event from
 /// ALB, API Gateway REST and HTTP API proxy event perspectives
@@ -463,7 +461,7 @@ pub fn from_reader<R>(rdr: R) -> Result<crate::Request, JsonError>
 where
     R: Read,
 {
-    serde_json::from_reader(rdr).map(LambdaRequest::into)
+    aws_lambda_json_impl::from_reader(rdr).map(LambdaRequest::into)
 }
 
 /// Deserializes a `Request` from a string of JSON text.
@@ -482,8 +480,55 @@ where
 ///     Ok(println!("{:#?}", request))
 /// }
 /// ```
+#[cfg(not(feature = "simd_json"))]
 pub fn from_str(s: &str) -> Result<crate::Request, JsonError> {
-    serde_json::from_str(s).map(LambdaRequest::into)
+    aws_lambda_json_impl::from_str(s).map(LambdaRequest::into)
+}
+
+/// Deserializes a `Request` from a string of JSON text using simd_json
+///
+/// # Example
+///
+/// ```rust,no_run
+/// use lambda_http::request::from_str;
+/// use std::fs::File;
+/// use std::error::Error;
+///
+/// fn main() -> Result<(), Box<dyn Error>> {
+///     let mut json = r#"{ ...raw json here... }"#.to_owned();
+///     let request = unsafe{ from_str(&mut json) }?;
+///     Ok(println!("{:#?}", request))
+/// }
+/// ```
+/// 
+/// # Safety
+/// 
+/// simd_json requires mutable access to the string slice and may
+/// leave the slice with invalid UTF8 data.
+/// 
+#[cfg(feature = "simd_json")]
+pub unsafe fn from_str(s: &mut str) -> Result<crate::Request, JsonError> {
+    aws_lambda_json_impl::from_str(s).map(LambdaRequest::into)
+}
+
+/// Deserializes a `Request` from an owned String of JSON text.
+///
+/// # Example
+///
+/// ```rust,no_run
+/// use lambda_http::request::from_string;
+/// use std::fs::File;
+/// use std::error::Error;
+///
+/// fn main() -> Result<(), Box<dyn Error>> {
+///     let mut json = r#"{ ...raw json here... }"#.to_owned();
+///     let request = from_string(json);
+///     Ok(println!("{:#?}", request))
+/// }
+/// ```
+pub fn from_string(s: String) -> Result<crate::Request, JsonError> {
+    let mut v = s.into_bytes();
+    aws_lambda_json_impl::from_slice(v.as_mut_slice()).map(LambdaRequest::into)
 }
 
 fn x_forwarded_proto() -> HeaderName {
@@ -529,6 +574,8 @@ mod tests {
     use super::*;
     use crate::ext::RequestExt;
     use std::fs::File;
+    #[cfg(feature = "simd_json")]
+    use aws_lambda_json_impl::simd_json::prelude::ValueAsScalar;
 
     #[test]
     fn deserializes_apigw_request_events_from_readables() {
@@ -539,6 +586,7 @@ mod tests {
         assert!(result.is_ok(), "event was not parsed as expected {result:?}");
     }
 
+    #[cfg(not(feature = "simd_json"))]
     #[test]
     fn deserializes_minimal_apigw_http_request_events() {
         // from the docs
@@ -561,12 +609,41 @@ mod tests {
         );
     }
 
+    #[cfg(feature = "simd_json")]
+    #[test]
+    fn deserializes_minimal_apigw_http_request_events_with_simd() {
+        // from the docs
+        // https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-api-gateway-request
+        let mut input = include_str!("../tests/data/apigw_v2_proxy_request_minimal.json").to_owned();
+        let result = unsafe{ from_str(&mut input) };
+        assert!(
+            result.is_ok(),
+            "event was not parsed as expected {result:?} given {input}" //SO not safe to do!
+        );
+        let req = result.expect("failed to parse request");
+        assert_eq!(req.method(), "GET");
+        assert_eq!(req.uri(), "https://xxx.execute-api.us-east-1.amazonaws.com/");
+
+        // Ensure this is an APIGWv2 request
+        let req_context = req.request_context_ref().expect("Request is missing RequestContext");
+        assert!(
+            matches!(req_context, &RequestContext::ApiGatewayV2(_)),
+            "expected ApiGatewayV2 context, got {req_context:?}"
+        );
+    }
+
+    //
+    // From here on, for testing, we use the from_string function in order top avoid
+    // duplicating test sources and having to deal with safety and mutability differences
+    // between the two JSON parsers we support
+    //
+
     #[test]
     fn deserializes_apigw_http_request_events() {
         // from the docs
         // https://docs.aws.amazon.com/lambda/latest/dg/eventsources.html#eventsources-api-gateway-request
         let input = include_str!("../tests/data/apigw_v2_proxy_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -599,7 +676,7 @@ mod tests {
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
         let input = include_str!("../tests/data/apigw_proxy_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -624,7 +701,7 @@ mod tests {
         // from the docs
         // https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads
         let input = include_str!("../tests/data/lambda_function_url_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -657,7 +734,7 @@ mod tests {
         // from the docs
         // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers
         let input = include_str!("../tests/data/alb_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -682,7 +759,7 @@ mod tests {
         // from the docs
         // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers
         let input = include_str!("../tests/data/alb_request_encoded_query_parameters.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -707,7 +784,7 @@ mod tests {
         // from docs
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
         let input = include_str!("../tests/data/apigw_multi_value_proxy_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event is was not parsed as expected {result:?} given {input}"
@@ -737,7 +814,7 @@ mod tests {
         // from docs
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
         let input = include_str!("../tests/data/alb_multi_value_request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event is was not parsed as expected {result:?} given {input}"
@@ -763,7 +840,7 @@ mod tests {
         // from docs
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
         let input = include_str!("../tests/data/alb_multi_value_request_encoded_query_parameters.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event is was not parsed as expected {result:?} given {input}"
@@ -794,7 +871,7 @@ mod tests {
         // * sam local start-api
         // * Invoke the API
         let input = include_str!("../tests/data/apigw_v2_sam_local.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -808,7 +885,7 @@ mod tests {
     fn deserialize_apigw_no_host() {
         // generated from the 'apigateway-aws-proxy' test event template in the Lambda console
         let input = include_str!("../tests/data/apigw_no_host.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -822,7 +899,7 @@ mod tests {
     fn deserialize_alb_no_host() {
         // generated from ALB health checks
         let input = include_str!("../tests/data/alb_no_host.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -836,7 +913,7 @@ mod tests {
     fn deserialize_apigw_path_with_space() {
         // generated from ALB health checks
         let input = include_str!("../tests/data/apigw_request_path_with_space.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -854,7 +931,7 @@ mod tests {
     #[test]
     fn deserializes_apigw_http_request_with_stage_in_path() {
         let input = include_str!("../tests/data/apigw_v2_proxy_request_with_stage_in_path.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
@@ -880,7 +957,7 @@ mod tests {
         // from docs
         // https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
         let input = include_str!("../tests/data/apigw_multi_value_proxy_request.json");
-        let request = from_str(input).expect("failed to parse request");
+        let request = from_string(input.to_owned()).expect("failed to parse request");
         let (mut parts, _) = request.into_parts();
 
         #[derive(Deserialize)]
@@ -902,7 +979,7 @@ mod tests {
         use axum_core::extract::FromRequestParts;
         use axum_extra::extract::Query;
         let input = include_str!("../tests/data/apigw_v2_proxy_request.json");
-        let request = from_str(input).expect("failed to parse request");
+        let request = from_string(input.to_owned()).expect("failed to parse request");
         let (mut parts, _) = request.into_parts();
 
         #[derive(Deserialize)]
@@ -923,7 +1000,7 @@ mod tests {
         use axum_core::extract::FromRequestParts;
         use axum_extra::extract::Query;
         let input = include_str!("../tests/data/alb_multi_value_request.json");
-        let request = from_str(input).expect("failed to parse request");
+        let request = from_string(input.to_owned()).expect("failed to parse request");
         let (mut parts, _) = request.into_parts();
 
         #[derive(Deserialize)]
@@ -943,7 +1020,7 @@ mod tests {
     #[cfg(feature = "apigw_rest")]
     fn deserializes_request_authorizer() {
         let input = include_str!("../../lambda-events/src/fixtures/example-apigw-request.json");
-        let result = from_str(input);
+        let result = from_string(input.to_owned());
         assert!(
             result.is_ok(),
             "event was not parsed as expected {result:?} given {input}"
diff --git a/lambda-http/src/response.rs b/lambda-http/src/response.rs
index e8528fdf..60ed5bf9 100644
--- a/lambda-http/src/response.rs
+++ b/lambda-http/src/response.rs
@@ -51,7 +51,7 @@ pub enum LambdaResponse {
     #[cfg(feature = "alb")]
     Alb(AlbTargetGroupResponse),
     #[cfg(feature = "pass_through")]
-    PassThrough(serde_json::Value),
+    PassThrough(aws_lambda_json_impl::Value),
 }
 
 /// Transformation from http type to internal type
@@ -133,9 +133,15 @@ impl LambdaResponse {
             RequestOrigin::PassThrough => {
                 match body {
                     // text body must be a valid json string
-                    Some(Body::Text(body)) => {LambdaResponse::PassThrough(serde_json::from_str(&body).unwrap_or_default())},
+                    #[cfg(not(feature = "simd_json"))]
+                    Some(Body::Text(body)) => {LambdaResponse::PassThrough(aws_lambda_json_impl::from_str(&body).unwrap_or_default())},
+                    #[cfg(feature = "simd_json")]
+                    Some(Body::Text(body)) => {LambdaResponse::PassThrough(aws_lambda_json_impl::from_string(body).unwrap_or_default())},
                     // binary body and other cases return Value::Null
-                    _ => LambdaResponse::PassThrough(serde_json::Value::Null),
+                    #[cfg(not(feature = "simd_json"))]
+                    _ => LambdaResponse::PassThrough(aws_lambda_json_impl::Value::Null),
+                    #[cfg(feature = "simd_json")]
+                    _ => LambdaResponse::PassThrough(aws_lambda_json_impl::Value::Static(aws_lambda_json_impl::StaticNode::Null)),
                 }
             }
             #[cfg(not(any(
@@ -195,14 +201,14 @@ impl IntoResponse for Vec<u8> {
     }
 }
 
-impl IntoResponse for serde_json::Value {
+impl IntoResponse for aws_lambda_json_impl::Value {
     fn into_response(self) -> ResponseFuture {
         Box::pin(async move {
             Response::builder()
                 .header(CONTENT_TYPE, "application/json")
                 .body(
-                    serde_json::to_string(&self)
-                        .expect("unable to serialize serde_json::Value")
+                    aws_lambda_json_impl::to_string(&self)
+                        .expect("unable to serialize aws_lambda_json_impl::Value")
                         .into(),
                 )
                 .expect("unable to build http::Response")
@@ -258,7 +264,7 @@ impl IntoResponse for (StatusCode, Vec<u8>) {
     }
 }
 
-impl IntoResponse for (StatusCode, serde_json::Value) {
+impl IntoResponse for (StatusCode, aws_lambda_json_impl::Value) {
     fn into_response(self) -> ResponseFuture {
         let (status, body) = self;
         Box::pin(async move {
@@ -266,8 +272,8 @@ impl IntoResponse for (StatusCode, serde_json::Value) {
                 .status(status)
                 .header(CONTENT_TYPE, "application/json")
                 .body(
-                    serde_json::to_string(&body)
-                        .expect("unable to serialize serde_json::Value")
+                    aws_lambda_json_impl::to_string(&body)
+                        .expect("unable to serialize aws_lambda_json_impl::Value")
                         .into(),
                 )
                 .expect("unable to build http::Response")
@@ -373,12 +379,12 @@ pub type BodyFuture = Pin<Box<dyn Future<Output = Body> + Send>>;
 #[cfg(test)]
 mod tests {
     use super::{Body, IntoResponse, LambdaResponse, RequestOrigin, X_LAMBDA_HTTP_CONTENT_ENCODING};
+    use aws_lambda_json_impl::json;
     use http::{
         header::{CONTENT_ENCODING, CONTENT_TYPE},
         Response, StatusCode,
     };
     use lambda_runtime_api_client::body::Body as HyperBody;
-    use serde_json::{self, json};
 
     const SVG_LOGO: &str = include_str!("../tests/data/svg_logo.svg");
 
@@ -475,7 +481,7 @@ mod tests {
         let response = response.into_response().await;
         let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response);
 
-        let json = serde_json::to_string(&response).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{"content-encoding":"gzip"},"multiValueHeaders":{},"body":"MDAwMDAw","isBase64Encoded":true,"cookies":[]}"#
@@ -493,7 +499,7 @@ mod tests {
         let response = response.into_response().await;
         let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response);
 
-        let json = serde_json::to_string(&response).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{"content-type":"application/json"},"multiValueHeaders":{},"body":"000000","isBase64Encoded":false,"cookies":[]}"#
@@ -511,7 +517,7 @@ mod tests {
         let response = response.into_response().await;
         let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response);
 
-        let json = serde_json::to_string(&response).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{"content-type":"application/json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
@@ -529,7 +535,7 @@ mod tests {
         let response = response.into_response().await;
         let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response);
 
-        let json = serde_json::to_string(&response).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{"content-type":"application/graphql-response+json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
@@ -546,7 +552,7 @@ mod tests {
         let response = response.into_response().await;
         let response = LambdaResponse::from_response(&RequestOrigin::ApiGatewayV2, response);
 
-        let json = serde_json::to_string(&response).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&response).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{},"multiValueHeaders":{},"body":"000000","isBase64Encoded":false,"cookies":[]}"#
@@ -563,7 +569,7 @@ mod tests {
                 .body(Body::from(()))
                 .expect("failed to create response"),
         );
-        let json = serde_json::to_string(&res).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&res).expect("failed to serialize to json");
         assert_eq!(
             json,
             r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"multi":["a","b"]},"isBase64Encoded":false}"#
@@ -580,7 +586,7 @@ mod tests {
                 .body(Body::from(()))
                 .expect("failed to create response"),
         );
-        let json = serde_json::to_string(&res).expect("failed to serialize to json");
+        let json = aws_lambda_json_impl::to_string(&res).expect("failed to serialize to json");
         assert_eq!(
             "{\"statusCode\":200,\"headers\":{},\"multiValueHeaders\":{},\"isBase64Encoded\":false,\"cookies\":[\"cookie1=a\",\"cookie2=b\"]}",
             json
diff --git a/lambda-integration-tests/Cargo.toml b/lambda-integration-tests/Cargo.toml
index ee44a969..b46feeff 100644
--- a/lambda-integration-tests/Cargo.toml
+++ b/lambda-integration-tests/Cargo.toml
@@ -13,10 +13,13 @@ readme = "../README.md"
 [dependencies]
 lambda_runtime = { path = "../lambda-runtime" }
 aws_lambda_events = { path = "../lambda-events" }
-serde_json = "1.0.121"
+aws_lambda_json_impl = { path = "../json-impl" }
 tokio = { version = "1", features = ["full"] }
 serde = { version = "1.0.204", features = ["derive"] }
 
+[features]
+simd_json = [ "aws_lambda_json_impl/simd", "lambda_runtime/simd_json", "aws_lambda_events/simd_json" ]
+
 [dev-dependencies]
 reqwest = { version = "0.12.5", features = ["blocking"] }
 openssl = { version = "0.10", features = ["vendored"] }
diff --git a/lambda-integration-tests/src/authorizer.rs b/lambda-integration-tests/src/authorizer.rs
index 41ddd2d8..42de319a 100644
--- a/lambda-integration-tests/src/authorizer.rs
+++ b/lambda-integration-tests/src/authorizer.rs
@@ -4,9 +4,9 @@ use aws_lambda_events::{
     apigw::{ApiGatewayCustomAuthorizerPolicy, ApiGatewayCustomAuthorizerResponse},
     event::iam::IamPolicyStatement,
 };
+use aws_lambda_json_impl::json;
 use lambda_runtime::{service_fn, tracing, Error, LambdaEvent};
 use serde::Deserialize;
-use serde_json::json;
 
 #[derive(Deserialize)]
 #[serde(rename_all = "camelCase")]
diff --git a/lambda-runtime/Cargo.toml b/lambda-runtime/Cargo.toml
index 0f63cd47..e380b20c 100644
--- a/lambda-runtime/Cargo.toml
+++ b/lambda-runtime/Cargo.toml
@@ -20,6 +20,7 @@ opentelemetry = ["opentelemetry-semantic-conventions"] # enables access to the O
 anyhow = ["dep:anyhow"] # enables From<T> for Diagnostic for anyhow error types, see README.md for more info
 eyre = ["dep:eyre"] # enables From<T> for Diagnostic for eyre error types, see README.md for more info
 miette = ["dep:miette"] # enables From<T> for Diagnostic for miette error types, see README.md for more info
+simd_json = [ "aws_lambda_json_impl/simd" ]
 
 [dependencies]
 anyhow = { version = "1.0.86", optional = true }
@@ -44,7 +45,7 @@ miette = { version = "7.2.0", optional = true }
 opentelemetry-semantic-conventions = { version = "0.14", optional = true }
 pin-project = "1"
 serde = { version = "1", features = ["derive", "rc"] }
-serde_json = "^1"
+aws_lambda_json_impl = { path = "../json-impl" }
 serde_path_to_error = "0.1.11"
 tokio = { version = "1.0", features = [
     "macros",
diff --git a/lambda-runtime/src/deserializer.rs b/lambda-runtime/src/deserializer.rs
index 1841c050..41c0e5c4 100644
--- a/lambda-runtime/src/deserializer.rs
+++ b/lambda-runtime/src/deserializer.rs
@@ -6,38 +6,94 @@ use crate::{Context, LambdaEvent};
 
 const ERROR_CONTEXT: &str = "failed to deserialize the incoming data into the function's payload type";
 
-/// Event payload deserialization error.
-/// Returned when the data sent to the function cannot be deserialized
-/// into the type that the function receives.
-#[derive(Debug)]
-pub(crate) struct DeserializeError {
-    inner: serde_path_to_error::Error<serde_json::Error>,
-}
+use bytes::Bytes;
+
+#[cfg(not(feature = "simd_json"))]
+mod deser_error {
+    use super::*;
+
+    /// Event payload deserialization error.
+    /// Returned when the data sent to the function cannot be deserialized
+    /// into the type that the function receives.
+    #[derive(Debug)]
+    #[cfg(not(feature = "simd_json"))]
+    pub(crate) struct DeserializeError {
+        pub(super) inner: serde_path_to_error::Error<aws_lambda_json_impl::JsonError>,
+    }
+    impl fmt::Display for DeserializeError {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            let path = self.inner.to_string();
+            if path == "." {
+                writeln!(f, "{ERROR_CONTEXT}: {}", self.inner)
+            } else {
+                writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner)
+            }
+        }
+    }
 
-impl fmt::Display for DeserializeError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let path = self.inner.path().to_string();
-        if path == "." {
-            writeln!(f, "{ERROR_CONTEXT}: {}", self.inner)
-        } else {
-            writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner)
+    impl Error for DeserializeError {
+        fn source(&self) -> Option<&(dyn Error + 'static)> {
+            Some(&self.inner)
         }
     }
 }
 
-impl Error for DeserializeError {
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Some(&self.inner)
+#[cfg(feature = "simd_json")]
+mod deser_error {
+    use super::*;
+
+    /// Event payload deserialization error.
+    /// Returned when the data sent to the function cannot be deserialized
+    /// into the type that the function receives.
+    /// For simd_json, we can't get serde_path_to_error to work at the moment
+
+    #[derive(Debug)]
+    pub(crate) struct DeserializeError {
+        pub(super) inner: aws_lambda_json_impl::JsonError
+    }
+
+    impl fmt::Display for DeserializeError {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            let path = self.inner.to_string();
+            if path == "." {
+                writeln!(f, "{ERROR_CONTEXT}: {}", self.inner)
+            } else {
+                writeln!(f, "{ERROR_CONTEXT}: [{path}] {}", self.inner)
+            }
+        }
+    }
+
+    impl Error for DeserializeError {
+        fn source(&self) -> Option<&(dyn Error + 'static)> {
+            Some(&self.inner)
+        }
     }
 }
 
+pub(crate) use deser_error::*;
+
 /// Deserialize the data sent to the function into the type that the function receives.
-pub(crate) fn deserialize<T>(body: &[u8], context: Context) -> Result<LambdaEvent<T>, DeserializeError>
+#[cfg(not(feature = "simd_json"))]
+pub(crate) fn deserialize<T>(body: Bytes, context: Context) -> Result<LambdaEvent<T>, DeserializeError>
 where
     T: for<'de> Deserialize<'de>,
 {
-    let jd = &mut serde_json::Deserializer::from_slice(body);
+    use aws_lambda_json_impl::JsonDeserializer;
+    let jd = &mut JsonDeserializer::from_slice(&body);
     serde_path_to_error::deserialize(jd)
         .map(|payload| LambdaEvent::new(payload, context))
         .map_err(|inner| DeserializeError { inner })
 }
+
+#[cfg(feature = "simd_json")]
+pub(crate) fn deserialize<T>(body: Bytes, context: Context) -> Result<LambdaEvent<T>, DeserializeError>
+where
+    T: for<'de> Deserialize<'de>,
+{
+    //TODO: Find a way to make serde_path_to_json work
+    aws_lambda_json_impl::from_bytes(body)
+        .map(|payload| LambdaEvent::new(payload, context))
+        .map_err(|inner| DeserializeError { inner })
+}
+
+
diff --git a/lambda-runtime/src/diagnostic.rs b/lambda-runtime/src/diagnostic.rs
index c03ce284..d4742639 100644
--- a/lambda-runtime/src/diagnostic.rs
+++ b/lambda-runtime/src/diagnostic.rs
@@ -158,7 +158,7 @@ mod test {
 
     #[test]
     fn round_trip_lambda_error() {
-        use serde_json::{json, Value};
+        use aws_lambda_json_impl::{json, Value};
         let expected = json!({
             "errorType": "InvalidEventDataError",
             "errorMessage": "Error parsing event data.",
@@ -168,7 +168,7 @@ mod test {
             error_type: "InvalidEventDataError".into(),
             error_message: "Error parsing event data.".into(),
         };
-        let actual: Value = serde_json::to_value(actual).expect("failed to serialize diagnostic");
+        let actual: Value = aws_lambda_json_impl::to_value(actual).expect("failed to serialize diagnostic");
         assert_eq!(expected, actual);
     }
 
diff --git a/lambda-runtime/src/layers/api_response.rs b/lambda-runtime/src/layers/api_response.rs
index e744cde1..59e24fc0 100644
--- a/lambda-runtime/src/layers/api_response.rs
+++ b/lambda-runtime/src/layers/api_response.rs
@@ -102,7 +102,7 @@ where
         };
 
         let request_id = req.context.request_id.clone();
-        let lambda_event = match deserializer::deserialize::<EventPayload>(&req.body, req.context) {
+        let lambda_event = match deserializer::deserialize::<EventPayload>(req.body, req.context) {
             Ok(lambda_event) => lambda_event,
             Err(err) => match build_event_error_request(&request_id, err) {
                 Ok(request) => return RuntimeApiResponseFuture::Ready(Some(Ok(request))),
diff --git a/lambda-runtime/src/requests.rs b/lambda-runtime/src/requests.rs
index 729272f2..96e8ad8e 100644
--- a/lambda-runtime/src/requests.rs
+++ b/lambda-runtime/src/requests.rs
@@ -86,7 +86,7 @@ where
                 let uri = format!("/2018-06-01/runtime/invocation/{}/response", self.request_id);
                 let uri = Uri::from_str(&uri)?;
 
-                let body = serde_json::to_vec(&body)?;
+                let body = aws_lambda_json_impl::to_vec(&body)?;
                 let body = Body::from(body);
 
                 let req = build_request().method(Method::POST).uri(uri).body(body)?;
@@ -116,7 +116,7 @@ where
                     .entry(CONTENT_TYPE)
                     .or_insert("application/octet-stream".parse()?);
 
-                let metadata_prelude = serde_json::to_string(&response.metadata_prelude)?;
+                let metadata_prelude = aws_lambda_json_impl::to_string(&response.metadata_prelude)?;
 
                 tracing::trace!(?metadata_prelude);
 
@@ -174,7 +174,7 @@ impl<'a> IntoRequest for EventErrorRequest<'a> {
     fn into_req(self) -> Result<Request<Body>, Error> {
         let uri = format!("/2018-06-01/runtime/invocation/{}/error", self.request_id);
         let uri = Uri::from_str(&uri)?;
-        let body = serde_json::to_vec(&self.diagnostic)?;
+        let body = aws_lambda_json_impl::to_vec(&self.diagnostic)?;
         let body = Body::from(body);
 
         let req = build_request()
diff --git a/lambda-runtime/src/runtime.rs b/lambda-runtime/src/runtime.rs
index 1c676480..818b82c1 100644
--- a/lambda-runtime/src/runtime.rs
+++ b/lambda-runtime/src/runtime.rs
@@ -327,7 +327,7 @@ mod endpoint_tests {
             error_type: "InvalidEventDataError".into(),
             error_message: "Error parsing event data".into(),
         };
-        let body = serde_json::to_string(&diagnostic)?;
+        let body = aws_lambda_json_impl::to_string(&diagnostic)?;
 
         let server = MockServer::start();
         let mock = server.mock(|when, then| {
@@ -377,7 +377,7 @@ mod endpoint_tests {
         let base = server.base_url().parse().expect("Invalid mock server Uri");
         let client = Client::builder().with_endpoint(base).build()?;
 
-        async fn func(event: crate::LambdaEvent<serde_json::Value>) -> Result<serde_json::Value, Error> {
+        async fn func(event: crate::LambdaEvent<aws_lambda_json_impl::Value>) -> Result<aws_lambda_json_impl::Value, Error> {
             let (event, _) = event.into_parts();
             Ok(event)
         }
@@ -421,7 +421,7 @@ mod endpoint_tests {
 
     async fn run_panicking_handler<F>(func: F) -> Result<(), Error>
     where
-        F: FnMut(crate::LambdaEvent<serde_json::Value>) -> BoxFuture<'static, Result<serde_json::Value, Error>>
+        F: FnMut(crate::LambdaEvent<aws_lambda_json_impl::Value>) -> BoxFuture<'static, Result<aws_lambda_json_impl::Value, Error>>
             + Send
             + 'static,
     {
diff --git a/lambda-runtime/src/types.rs b/lambda-runtime/src/types.rs
index ee09978f..f01c412a 100644
--- a/lambda-runtime/src/types.rs
+++ b/lambda-runtime/src/types.rs
@@ -4,12 +4,16 @@ use bytes::Bytes;
 use http::{header::ToStrError, HeaderMap, HeaderValue, StatusCode};
 use lambda_runtime_api_client::body::Body;
 use serde::{Deserialize, Serialize};
+#[cfg(feature = "simd_json")]
+use serde::de::DeserializeOwned;
+
 use std::{
     collections::HashMap,
     fmt::Debug,
     time::{Duration, SystemTime},
 };
 use tokio_stream::Stream;
+use aws_lambda_json_impl::JsonError;
 
 /// Client context sent by the AWS Mobile SDK.
 #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
@@ -99,18 +103,31 @@ impl Default for Context {
     }
 }
 
+#[cfg(not(feature = "simd_json"))]
+fn parse_header<'a,T>(h: &'a HeaderValue) -> Result<T, JsonError>
+where T: Deserialize<'a> {
+    aws_lambda_json_impl::from_slice(h.as_bytes())
+}
+
+#[cfg(feature = "simd_json")]
+fn parse_header<T>(h: &HeaderValue) -> Result<T, JsonError>
+where T: DeserializeOwned {
+    let v = h.as_bytes().to_vec();
+    aws_lambda_json_impl::from_vec(v)
+}
+
 impl Context {
     /// Create a new [Context] struct based on the function configuration
     /// and the incoming request data.
     pub fn new(request_id: &str, env_config: RefConfig, headers: &HeaderMap) -> Result<Self, Error> {
         let client_context: Option<ClientContext> = if let Some(value) = headers.get("lambda-runtime-client-context") {
-            serde_json::from_str(value.to_str()?)?
+            parse_header(value)?
         } else {
             None
         };
 
         let identity: Option<CognitoIdentity> = if let Some(value) = headers.get("lambda-runtime-cognito-identity") {
-            serde_json::from_str(value.to_str()?)?
+            parse_header(value)?
         } else {
             None
         };
@@ -323,7 +340,7 @@ mod test {
             custom,
             environment,
         };
-        let client_context_str = serde_json::to_string(&client_context).unwrap();
+        let client_context_str = aws_lambda_json_impl::to_string(&client_context).unwrap();
         let mut headers = HeaderMap::new();
         headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id"));
         headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123"));
@@ -360,7 +377,7 @@ mod test {
             identity_id: String::new(),
             identity_pool_id: String::new(),
         };
-        let cognito_identity_str = serde_json::to_string(&cognito_identity).unwrap();
+        let cognito_identity_str = aws_lambda_json_impl::to_string(&cognito_identity).unwrap();
         let mut headers = HeaderMap::new();
         headers.insert("lambda-runtime-aws-request-id", HeaderValue::from_static("my-id"));
         headers.insert("lambda-runtime-deadline-ms", HeaderValue::from_static("123"));