diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 8e2a2c5..1c13f20 100644
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** SET ENABLE_SEQSCAN TO OFF;
*** 1638,1649 ****
        </indexterm>
        <listitem>
         <para>
!         The amount of memory used in shared memory for WAL data.  The
!         default is 64 kilobytes (<literal>64kB</>).  The setting need only
!         be large enough to hold the amount of WAL data generated by one
!         typical transaction, since the data is written out to disk at
!         every transaction commit.  This parameter can only be set at server
!         start.
         </para>
  
         <para>
--- 1638,1659 ----
        </indexterm>
        <listitem>
         <para>
!         The amount of shared memory used for storing WAL data.  The
!         default setting of -1 adjusts this automatically based on the size
!         of <varname>shared_buffers</varname>, making it 1/32 (about 3%) of
!         the size of that normally larger shared memory block.  Automatically
!         set values are limited to a maximum sufficient to hold one WAL
! 		segment worth of data, normally 16 megabytes (<literal>16MB</>).
!         The smallest allowable setting is 32 kilobytes (<literal>32kB</>).
!        </para>
! 
!        <para>
!         Since the data is written out to disk at every transaction commit,
!         the setting many only need to be be large enough to hold the amount
!         of WAL data generated by one typical transaction.  Larger values,
!         typically at least a few megabytes, can improve write performance
!         on a busy server where many clients are committing at once.
!         Extremely large settings are unlikely to provide additional benefit.
         </para>
  
         <para>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 5b6a230..d057773 100644
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 69,75 ****
  /* User-settable parameters */
  int			CheckPointSegments = 3;
  int			wal_keep_segments = 0;
! int			XLOGbuffers = 8;
  int			XLogArchiveTimeout = 0;
  bool		XLogArchiveMode = false;
  char	   *XLogArchiveCommand = NULL;
--- 69,76 ----
  /* User-settable parameters */
  int			CheckPointSegments = 3;
  int			wal_keep_segments = 0;
! int			XLOGbuffers = -1;
! int			XLOGbuffersMin = 8;
  int			XLogArchiveTimeout = 0;
  bool		XLogArchiveMode = false;
  char	   *XLogArchiveCommand = NULL;
*************** GetSystemIdentifier(void)
*** 4780,4790 ****
--- 4781,4819 ----
  /*
   * Initialization of shared memory for XLOG
   */
+ 
+ void XLOGTuneNumBuffers(void)
+ {
+ 	int one_segment = XLOG_SEG_SIZE / XLOG_BLCKSZ;
+ 
+ 	/*
+ 	 * If automatic setting was requested, use about 3% as much memory as
+ 	 * requested for the buffer cache.  Clamp the automatic maximum to the
+ 	 * size of one XLOG segment, while still allowing a larger manual
+ 	 * setting.  Don't go below the default setting in earlier versions:
+ 	 * twice the size of the minimum, which at default build options is 64kB.
+ 	 */	 
+ 	if (XLOGbuffers == -1)  /* set automatically */
+ 		{
+ 		XLOGbuffers = NBuffers / 32;
+ 		if (XLOGbuffers > one_segment)
+ 			XLOGbuffers = one_segment;
+ 		if (XLOGbuffers < (XLOGbuffersMin * 2))
+ 			XLOGbuffers = XLOGbuffersMin * 2;
+ 		}
+ 
+ 	/* Enforce a 32KB minimum in every case */
+ 	if (XLOGbuffers < XLOGbuffersMin)
+ 		XLOGbuffers = XLOGbuffersMin;
+ }
+ 
  Size
  XLOGShmemSize(void)
  {
  	Size		size;
  
+ 	XLOGTuneNumBuffers();
+ 	
  	/* XLogCtl */
  	size = sizeof(XLogCtlData);
  	/* xlblocks array */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index e4dea31..7c014cb 100644
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static struct config_int ConfigureNamesI
*** 1765,1771 ****
  			GUC_UNIT_XBLOCKS
  		},
  		&XLOGbuffers,
! 		8, 4, INT_MAX, NULL, NULL
  	},
  
  	{
--- 1765,1771 ----
  			GUC_UNIT_XBLOCKS
  		},
  		&XLOGbuffers,
! 		-1, -1, INT_MAX, NULL, NULL
  	},
  
  	{
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index f436b83..6c6f9a9 100644
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 162,168 ****
  					#   fsync_writethrough
  					#   open_sync
  #full_page_writes = on			# recover from partial page writes
! #wal_buffers = 64kB			# min 32kB
  					# (change requires restart)
  #wal_writer_delay = 200ms		# 1-10000 milliseconds
  
--- 162,168 ----
  					#   fsync_writethrough
  					#   open_sync
  #full_page_writes = on			# recover from partial page writes
! #wal_buffers = -1			# min 32kB, -1 sets based on shared_buffers
  					# (change requires restart)
  #wal_writer_delay = 200ms		# 1-10000 milliseconds
  
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 74d3427..b475867 100644
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
*************** typedef struct XLogRecord
*** 85,90 ****
--- 85,93 ----
   */
  #define XLR_BKP_REMOVABLE		0x01
  
+ /* Minimum setting used for a lower bound on wal_buffers */
+ #define XLOG_BUFFER_MIN			4
+ 
  /* Sync methods */
  #define SYNC_METHOD_FSYNC		0
  #define SYNC_METHOD_FDATASYNC	1
*************** extern void GetXLogReceiptTime(Timestamp
*** 293,298 ****
--- 296,302 ----
  
  extern void UpdateControlFile(void);
  extern uint64 GetSystemIdentifier(void);
+ extern void XLOGTuneNumBuffers(void);
  extern Size XLOGShmemSize(void);
  extern void XLOGShmemInit(void);
  extern void BootStrapXLOG(void);
