diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index 794aef4..19dc440
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** SET ENABLE_SEQSCAN TO OFF;
*** 1025,1030 ****
--- 1025,1067 ----
       </variablelist>
       </sect2>
  
+      <sect2 id="runtime-config-resource-disk">
+      <title>Disk</title>
+      <variablelist>
+ 
+      <varlistentry id="guc-temp-file-limit" xreflabel="temp_file_limit">
+       <term><varname>temp_file_limit</varname> (<type>integer</type>)</term>
+       <indexterm>
+        <primary><varname>temp_file_limit</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         Specifies the amount of disk space used by internal sort operations
+         and hash tables whist writing to temporary disk files. The value
+         defaults to unlimited (<literal>-1</>). Values larger than zero
+         constraint the temporary file space usage to be that number of
+         kilobytes.
+        </para>
+        <para>
+         A given sort or hash operation may write a number of temporary files,
+         the total space used by all the files produced by one backend is
+         constrained to be this value or less. If further bytes are written
+         the current query is canceled.  Only superusers can change this
+         setting.
+        </para>
+        <para>
+         It should be noted that this parameter does <emphasis>not</emphasis>
+         constrain disk space used for temporary table storage. However if
+         the temporary table is created from a query then the any sort
+         and hash files used in query execution will have their space
+         controlled as above.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      </variablelist>
+      </sect2>
+ 
       <sect2 id="runtime-config-resource-kernel">
       <title>Kernel Resource Usage</title>
       <variablelist>
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
new file mode 100644
index 820e6db..5c00889
*** a/src/backend/storage/file/fd.c
--- b/src/backend/storage/file/fd.c
*************** static int	max_safe_fds = 32;	/* default
*** 131,136 ****
--- 131,141 ----
  /* Flag to tell whether there are files to close/delete at end of transaction */
  static bool have_pending_fd_cleanup = false;
  
+ /*
+  * Track the total size of all temporary files
+  */
+ static double temporary_files_size = 0.0;
+ 
  typedef struct vfd
  {
  	int			fd;				/* current FD, or VFD_CLOSED if none */
*************** typedef struct vfd
*** 140,145 ****
--- 145,151 ----
  	File		lruMoreRecently;	/* doubly linked recency-of-use list */
  	File		lruLessRecently;
  	off_t		seekPos;		/* current logical file position */
+ 	off_t		fileSize;		/* current size of file */
  	char	   *fileName;		/* name of file, or NULL for unused VFD */
  	/* NB: fileName is malloc'd, and must be free'd when closing the VFD */
  	int			fileFlags;		/* open(2) flags for (re)opening the file */
*************** PathNameOpenFile(FileName fileName, int
*** 887,892 ****
--- 893,899 ----
  	vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
  	vfdP->fileMode = fileMode;
  	vfdP->seekPos = 0;
+ 	vfdP->fileSize = 0;
  	vfdP->fdstate = 0x0;
  	vfdP->resowner = NULL;
  
*************** FileClose(File file)
*** 1123,1128 ****
--- 1130,1142 ----
  			if (unlink(vfdP->fileName))
  				elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
  		}
+ 
+ 		if (temp_file_limit >= 0)
+ 		{
+ 			/* subtract the unlinked file size from the total */
+ 			temporary_files_size -= (double)vfdP->fileSize;
+ 			vfdP->fileSize = 0;
+ 		}
  	}
  
  	/* Unregister it from the resource owner */
*************** retry:
*** 1251,1257 ****
--- 1265,1291 ----
  		errno = ENOSPC;
  
  	if (returnCode >= 0)
+ 	{
  		VfdCache[file].seekPos += returnCode;
+ 
+ 		if (temp_file_limit >= 0 && VfdCache[file].fdstate & FD_TEMPORARY)
+ 		{
+ 			/*
+ 			 * if we increase the file size, add it to the total, then check it is
+ 			 * not too big
+ 			 */
+ 			if (VfdCache[file].seekPos >= VfdCache[file].fileSize )
+ 			{
+ 				temporary_files_size += (double)(VfdCache[file].seekPos - VfdCache[file].fileSize);
+ 				VfdCache[file].fileSize = VfdCache[file].seekPos;
+ 
+ 				if (temporary_files_size / 1024.0 > (double)temp_file_limit)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_QUERY_CANCELED),
+ 							 errmsg("aborting due to exceeding temp file limit")));
+ 			}
+ 		}
+ 	}
  	else
  	{
  		/*
*************** CleanupTempFiles(bool isProcExit)
*** 1887,1892 ****
--- 1921,1927 ----
  		}
  
  		have_pending_fd_cleanup = false;
+ 		temporary_files_size = 0.0;
  	}
  
  	/* Clean up "allocated" stdio files and dirs. */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index 92391ed..8ba6dce
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** int			log_min_messages = WARNING;
*** 423,428 ****
--- 423,429 ----
  int			client_min_messages = NOTICE;
  int			log_min_duration_statement = -1;
  int			log_temp_files = -1;
+ int			temp_file_limit = -1;
  int			trace_recovery_messages = LOG;
  
  int			num_temp_buffers = 1024;
*************** const char *const config_group_names[] =
*** 535,540 ****
--- 536,543 ----
  	gettext_noop("Resource Usage"),
  	/* RESOURCES_MEM */
  	gettext_noop("Resource Usage / Memory"),
+ 	/* RESOURCES_DISK */
+ 	gettext_noop("Resource Usage / Disk"),
  	/* RESOURCES_KERNEL */
  	gettext_noop("Resource Usage / Kernel Resources"),
  	/* RESOURCES_VACUUM_DELAY */
*************** static struct config_int ConfigureNamesI
*** 2185,2190 ****
--- 2188,2203 ----
  		RELSEG_SIZE, RELSEG_SIZE, RELSEG_SIZE,
  		NULL, NULL, NULL
  	},
+ 	{
+ 		{"temp_file_limit", PGC_SUSET, RESOURCES_DISK,
+ 			gettext_noop("Sets the maximum size of all temp files used by each session."),
+ 			gettext_noop("-1 turns this feature off."),
+ 			GUC_UNIT_KB
+ 		},
+ 		&temp_file_limit,
+ 		-1, -1, MAX_KILOBYTES,
+ 		NULL, NULL, NULL
+ 	},
  
  	{
  		{"wal_block_size", PGC_INTERNAL, PRESET_OPTIONS,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
new file mode 100644
index 655dad4..cc468c7
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 118,123 ****
--- 118,124 ----
  #work_mem = 1MB				# min 64kB
  #maintenance_work_mem = 16MB		# min 1MB
  #max_stack_depth = 2MB			# min 100kB
+ #temp_file_limit = -1    	# limit backend temp file space
  
  # - Kernel Resource Usage -
  
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
new file mode 100644
index ee52cd7..35321ee
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
*************** extern int	log_min_messages;
*** 208,213 ****
--- 208,214 ----
  extern int	client_min_messages;
  extern int	log_min_duration_statement;
  extern int	log_temp_files;
+ extern int	temp_file_limit;
  
  extern int	num_temp_buffers;
  
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
new file mode 100644
index a1ca012..3d9ab37
*** a/src/include/utils/guc_tables.h
--- b/src/include/utils/guc_tables.h
*************** enum config_group
*** 59,64 ****
--- 59,65 ----
  	CONN_AUTH_SECURITY,
  	RESOURCES,
  	RESOURCES_MEM,
+ 	RESOURCES_DISK,
  	RESOURCES_KERNEL,
  	RESOURCES_VACUUM_DELAY,
  	RESOURCES_BGWRITER,
diff --git a/src/test/regress/expected/resource.out b/src/test/regress/expected/resource.out
new file mode 100644
index ...571fa8f
*** a/src/test/regress/expected/resource.out
--- b/src/test/regress/expected/resource.out
***************
*** 0 ****
--- 1,18 ----
+ --
+ -- RESOURCE
+ -- Test resource management capabilities
+ --
+ -- temp_file_limit
+ CREATE TEMPORARY TABLE resourcetemp1 AS SELECT generate_series(1,100000);
+ -- Should succeed
+ SET temp_file_limit = 10000;
+ SELECT count(*) FROM (select * FROM resourcetemp1  ORDER BY 1) AS a;
+  count
+ --------
+  100000
+ (1 row)
+ 
+ -- Should fail
+ SET temp_file_limit = 1000;
+ SELECT count(*) FROM (select * FROM resourcetemp1  ORDER BY 1) AS a;
+ ERROR:  aborting due to exceeding temp file limit
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
new file mode 100644
index bb654f9..325cb3d
*** a/src/test/regress/serial_schedule
--- b/src/test/regress/serial_schedule
*************** test: largeobject
*** 127,129 ****
--- 127,130 ----
  test: with
  test: xml
  test: stats
+ test: resource
diff --git a/src/test/regress/sql/resource.sql b/src/test/regress/sql/resource.sql
new file mode 100644
index ...c593a58
*** a/src/test/regress/sql/resource.sql
--- b/src/test/regress/sql/resource.sql
***************
*** 0 ****
--- 1,17 ----
+ --
+ -- RESOURCE
+ -- Test resource management capabilities
+ --
+ 
+ -- temp_file_limit
+ CREATE TEMPORARY TABLE resourcetemp1 AS SELECT generate_series(1,100000);
+ 
+ -- Should succeed
+ SET temp_file_limit = 10000;
+ 
+ SELECT count(*) FROM (select * FROM resourcetemp1  ORDER BY 1) AS a;
+ 
+ -- Should fail
+ SET temp_file_limit = 1000;
+ 
+ SELECT count(*) FROM (select * FROM resourcetemp1  ORDER BY 1) AS a;
