diff --git a/TODO.md b/TODO.md
index f27d17a921..f28633e825 100644
--- a/TODO.md
+++ b/TODO.md
@@ -33,8 +33,8 @@
 - [x] block variable captures
 - [x] improved history and config paths
 - [x] ctrl-c support
+- [x] operator overflow
 - [ ] Support for `$in`
-- [ ] operator overflow
 - [ ] shells
 - [ ] plugins
 - [ ] dataframes
diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs
index 516cd31dbf..ca64f22665 100644
--- a/crates/nu-protocol/src/value/mod.rs
+++ b/crates/nu-protocol/src/value/mod.rs
@@ -535,16 +535,24 @@ impl Value {
                 span,
             }),
             (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
-                Ok(Value::Duration {
-                    val: *lhs + *rhs,
-                    span,
-                })
+                if let Some(val) = lhs.checked_add(*rhs) {
+                    Ok(Value::Duration { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "add operation overflowed".into(),
+                        span,
+                    ))
+                }
             }
             (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => {
-                Ok(Value::Filesize {
-                    val: *lhs + *rhs,
-                    span,
-                })
+                if let Some(val) = lhs.checked_add(*rhs) {
+                    Ok(Value::Filesize { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "add operation overflowed".into(),
+                        span,
+                    ))
+                }
             }
 
             _ => Err(ShellError::OperatorMismatch {
@@ -560,10 +568,16 @@ impl Value {
         let span = span(&[self.span()?, rhs.span()?]);
 
         match (self, rhs) {
-            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
-                val: lhs - rhs,
-                span,
-            }),
+            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
+                if let Some(val) = lhs.checked_sub(*rhs) {
+                    Ok(Value::Int { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "subtraction operation overflowed".into(),
+                        span,
+                    ))
+                }
+            }
             (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float {
                 val: *lhs as f64 - *rhs,
                 span,
@@ -577,16 +591,24 @@ impl Value {
                 span,
             }),
             (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
-                Ok(Value::Duration {
-                    val: *lhs - *rhs,
-                    span,
-                })
+                if let Some(val) = lhs.checked_sub(*rhs) {
+                    Ok(Value::Duration { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "subtraction operation overflowed".into(),
+                        span,
+                    ))
+                }
             }
             (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => {
-                Ok(Value::Filesize {
-                    val: *lhs - *rhs,
-                    span,
-                })
+                if let Some(val) = lhs.checked_sub(*rhs) {
+                    Ok(Value::Filesize { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "add operation overflowed".into(),
+                        span,
+                    ))
+                }
             }
 
             _ => Err(ShellError::OperatorMismatch {
@@ -602,10 +624,16 @@ impl Value {
         let span = span(&[self.span()?, rhs.span()?]);
 
         match (self, rhs) {
-            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
-                val: lhs * rhs,
-                span,
-            }),
+            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
+                if let Some(val) = lhs.checked_mul(*rhs) {
+                    Ok(Value::Int { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "multiply operation overflowed".into(),
+                        span,
+                    ))
+                }
+            }
             (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float {
                 val: *lhs as f64 * *rhs,
                 span,
@@ -983,10 +1011,16 @@ impl Value {
         let span = span(&[self.span()?, rhs.span()?]);
 
         match (self, rhs) {
-            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
-                val: lhs.pow(*rhs as u32),
-                span,
-            }),
+            (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
+                if let Some(val) = lhs.checked_pow(*rhs as u32) {
+                    Ok(Value::Int { val, span })
+                } else {
+                    Err(ShellError::OperatorOverflow(
+                        "pow operation overflowed".into(),
+                        span,
+                    ))
+                }
+            }
             (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float {
                 val: (*lhs as f64).powf(*rhs),
                 span,