diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 0b63b759242cc6a4bb9fb165ad22ba48a37395ad_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw==..334258743b5cab7256a33cb304f7f209ea2c4c8b_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw== 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -17,6 +17,13 @@
 
 #define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '/' && c != '"')
 
+#define MIN_EXPANSION 6
+#ifdef Py_UNICODE_WIDE
+#define MAX_EXPANSION (2 * MIN_EXPANSION)
+#else
+#define MAX_EXPANSION MIN_EXPANSION
+#endif
+
 static Py_ssize_t
 ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars) {
     Py_UNICODE x;
@@ -75,7 +82,7 @@
     input_chars = PyUnicode_GET_SIZE(pystr);
     input_unicode = PyUnicode_AS_UNICODE(pystr);
     /* One char input can be up to 6 chars output, estimate 4 of these */
-    output_size = 32 + input_chars;
+    output_size = 2 + (MIN_EXPANSION * 4) + input_chars;
     rval = PyString_FromStringAndSize(NULL, output_size);
     if (rval == NULL) {
         return NULL;
@@ -90,6 +97,6 @@
         } else {
             chars = ascii_escape_char(c, output, chars);
         }
-        if (output_size - chars < 7) {
+        if (output_size - chars < (1 + MAX_EXPANSION)) {
             /* There's more than four, so let's resize by a lot */
             output_size *= 2;
@@ -94,7 +101,8 @@
             /* There's more than four, so let's resize by a lot */
             output_size *= 2;
-            if (output_size > 2 + (input_chars * 6)) {
-                output_size = 2 + (input_chars * 6);
+            /* This is an upper bound */
+            if (output_size > 2 + (input_chars * MAX_EXPANSION)) {
+                output_size = 2 + (input_chars * MAX_EXPANSION);
             }
             if (_PyString_Resize(&rval, output_size) == -1) {
                 return NULL;
@@ -122,7 +130,7 @@
     input_chars = PyString_GET_SIZE(pystr);
     input_str = PyString_AS_STRING(pystr);
     /* One char input can be up to 6 chars output, estimate 4 of these */
-    output_size = 32 + input_chars;
+    output_size = 2 + (MIN_EXPANSION * 4) + input_chars;
     rval = PyString_FromStringAndSize(NULL, output_size);
     if (rval == NULL) {
         return NULL;
@@ -148,6 +156,7 @@
         } else {
             chars = ascii_escape_char(c, output, chars);
         }
-        if (output_size - chars < 7) {
+        /* An ASCII char can't possibly expand to a surrogate! */
+        if (output_size - chars < (1 + MIN_EXPANSION)) {
             /* There's more than four, so let's resize by a lot */
             output_size *= 2;
@@ -152,7 +161,7 @@
             /* There's more than four, so let's resize by a lot */
             output_size *= 2;
-            if (output_size > 2 + (input_chars * 6)) {
-                output_size = 2 + (input_chars * 6);
+            if (output_size > 2 + (input_chars * MIN_EXPANSION)) {
+                output_size = 2 + (input_chars * MIN_EXPANSION);
             }
             if (_PyString_Resize(&rval, output_size) == -1) {
                 return NULL;