diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index a6e3a14b8d6ea24a3b37f764167ad4cd65a9e16b..6ac0940fdf199b7484803f0552c21769555cb4d7 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -44,9 +44,13 @@
 #endif
 #include <sys/param.h>
 
-#ifndef NL_ARGMAX
-#define NL_ARGMAX 16
-#endif
+/*
+ * We used to use the platform's NL_ARGMAX here, but that's a bad idea,
+ * first because the point of this module is to remove platform dependencies
+ * not perpetuate them, and second because some platforms use ridiculously
+ * large values, leading to excessive stack consumption in dopr().
+ */
+#define PG_NL_ARGMAX 31
 
 
 /*
@@ -345,8 +349,8 @@ dopr(PrintfTarget *target, const char *format, va_list args)
 	double		fvalue;
 	char	   *strvalue;
 	int			i;
-	PrintfArgType argtypes[NL_ARGMAX + 1];
-	PrintfArgValue argvalues[NL_ARGMAX + 1];
+	PrintfArgType argtypes[PG_NL_ARGMAX + 1];
+	PrintfArgValue argvalues[PG_NL_ARGMAX + 1];
 
 	/*
 	 * Parse the format string to determine whether there are %n$ format
@@ -396,7 +400,7 @@ nextch1:
 				goto nextch1;
 			case '$':
 				have_dollar = true;
-				if (accum <= 0 || accum > NL_ARGMAX)
+				if (accum <= 0 || accum > PG_NL_ARGMAX)
 					goto bad_format;
 				if (afterstar)
 				{