diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index 77a9303..1200ad6
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** include 'filename'
*** 1156,1163 ****
         </para>
         <para>
          Note that when autovacuum runs, up to
!         <xref linkend="guc-autovacuum-max-workers"> times this memory may be
!         allocated, so be careful not to set the default value too high.
         </para>
        </listitem>
       </varlistentry>
--- 1156,1181 ----
         </para>
         <para>
          Note that when autovacuum runs, up to
!         <xref linkend="guc-autovacuum-max-workers"> times this memory
!         may be allocated, so be careful not to set the default value
!         too high.  It may be useful to control for this by separately
!         setting <xref linkend="guc-autovacuum-work-mem">.
!        </para>
!       </listitem>
!      </varlistentry>
! 
!      <varlistentry id="guc-autovacuum-work-mem" xreflabel="autovacuum_work_mem">
!       <term><varname>autovacuum_work_mem</varname> (<type>integer</type>)</term>
!       <indexterm>
!        <primary><varname>autovacuum_work_mem</> configuration parameter</primary>
!       </indexterm>
!       <listitem>
!        <para>
!         Specifies the maximum amount of memory to be used by each
!         autovacuum worker process.  It defaults to -1, indicating that
!         the value of <xref linkend="guc-maintenance-work-mem"> should
!         be used instead.  The setting has no effect on the behavior of
!         <command>VACUUM</command> when run in other contexts.
         </para>
        </listitem>
       </varlistentry>
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
new file mode 100644
index e1d6d1c..62bd2f0
*** a/src/backend/commands/vacuumlazy.c
--- b/src/backend/commands/vacuumlazy.c
***************
*** 10,22 ****
   * relations with finite memory space usage.  To do that, we set upper bounds
   * on the number of tuples and pages we will keep track of at once.
   *
!  * We are willing to use at most maintenance_work_mem memory space to keep
!  * track of dead tuples.  We initially allocate an array of TIDs of that size,
!  * with an upper limit that depends on table size (this limit ensures we don't
!  * allocate a huge area uselessly for vacuuming small tables).	If the array
!  * threatens to overflow, we suspend the heap scan phase and perform a pass of
!  * index cleanup and page compaction, then resume the heap scan with an empty
!  * TID array.
   *
   * If we're processing a table with no indexes, we can just vacuum each page
   * as we go; there's no need to save up multiple tuples to minimize the number
--- 10,22 ----
   * relations with finite memory space usage.  To do that, we set upper bounds
   * on the number of tuples and pages we will keep track of at once.
   *
!  * We are willing to use at most maintenance_work_mem (or perhaps
!  * autovacuum_work_mem) memory space to keep track of dead tuples.  We
!  * initially allocate an array of TIDs of that size, with an upper limit that
!  * depends on table size (this limit ensures we don't allocate a huge area
!  * uselessly for vacuuming small tables).  If the array threatens to overflow,
!  * we suspend the heap scan phase and perform a pass of index cleanup and page
!  * compaction, then resume the heap scan with an empty TID array.
   *
   * If we're processing a table with no indexes, we can just vacuum each page
   * as we go; there's no need to save up multiple tuples to minimize the number
*************** static void
*** 1581,1590 ****
  lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
  {
  	long		maxtuples;
  
  	if (vacrelstats->hasindex)
  	{
! 		maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData);
  		maxtuples = Min(maxtuples, INT_MAX);
  		maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));
  
--- 1581,1593 ----
  lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
  {
  	long		maxtuples;
+ 	int			vac_work_mem =  IsAutoVacuumWorkerProcess() &&
+ 									autovacuum_work_mem != -1 ?
+ 								autovacuum_work_mem : maintenance_work_mem;
  
  	if (vacrelstats->hasindex)
  	{
! 		maxtuples = (vac_work_mem * 1024L) / sizeof(ItemPointerData);
  		maxtuples = Min(maxtuples, INT_MAX);
  		maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));
  
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
new file mode 100644
index 8c14d0f..0b881c0
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 110,115 ****
--- 110,116 ----
   */
  bool		autovacuum_start_daemon = false;
  int			autovacuum_max_workers;
+ int			autovacuum_work_mem = -1;
  int			autovacuum_naptime;
  int			autovacuum_vac_thresh;
  double		autovacuum_vac_scale;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index 54d8078..d33048f
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static const char *show_tcp_keepalives_c
*** 192,197 ****
--- 192,198 ----
  static bool check_maxconnections(int *newval, void **extra, GucSource source);
  static bool check_max_worker_processes(int *newval, void **extra, GucSource source);
  static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
+ static bool check_autovacuum_work_mem(int *newval, void **extra, GucSource source);
  static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source);
  static void assign_effective_io_concurrency(int newval, void *extra);
  static void assign_pgstat_temp_directory(const char *newval, void *extra);
*************** static struct config_int ConfigureNamesI
*** 2347,2352 ****
--- 2348,2364 ----
  	},
  
  	{
+ 		{"autovacuum_work_mem", PGC_SIGHUP, RESOURCES_MEM,
+ 			gettext_noop("Sets the maximum memory to be used by each autovacuum worker process."),
+ 			NULL,
+ 			GUC_UNIT_KB
+ 		},
+ 		&autovacuum_work_mem,
+ 		-1, -1, MAX_KILOBYTES,
+ 		check_autovacuum_work_mem, NULL, NULL
+ 	},
+ 
+ 	{
  		{"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
  			gettext_noop("Time between issuing TCP keepalives."),
  			gettext_noop("A value of 0 uses the system default."),
*************** check_autovacuum_max_workers(int *newval
*** 8751,8756 ****
--- 8763,8791 ----
  	return true;
  }
  
+ static bool
+ check_autovacuum_work_mem(int *newval, void **extra, GucSource source)
+ {
+ 	/*
+ 	 * -1 indicates fallback.
+ 	 *
+ 	 * If we haven't yet changed the boot_val default of -1, just let it be.
+ 	 * Autovacuum will look to maintenance_work_mem instead.
+ 	 */
+ 	if (*newval == -1)
+ 		return true;
+ 
+ 	/*
+ 	 * We clamp manually-set values to at least 1MB.  Since
+ 	 * maintenance_work_mem is always set to at least this value, do the same
+ 	 * here.
+ 	 */
+ 	if (*newval < 1024)
+ 		*newval = 1024;
+ 
+ 	return true;
+ }
+ 
  static bool
  check_max_worker_processes(int *newval, void **extra, GucSource source)
  {
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
new file mode 100644
index 34a2d05..4737ede
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 122,127 ****
--- 122,128 ----
  # actively intend to use prepared transactions.
  #work_mem = 1MB				# min 64kB
  #maintenance_work_mem = 16MB		# min 1MB
+ #autovacuum_work_mem = -1		# min 1MB, or -1 to use maintenance_work_mem
  #max_stack_depth = 2MB			# min 100kB
  #dynamic_shared_memory_type = posix # the default is the first option
  					# supported by the operating system:
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
new file mode 100644
index e96f07a..92560fe
*** a/src/include/postmaster/autovacuum.h
--- b/src/include/postmaster/autovacuum.h
***************
*** 18,23 ****
--- 18,24 ----
  /* GUC variables */
  extern bool autovacuum_start_daemon;
  extern int	autovacuum_max_workers;
+ extern int	autovacuum_work_mem;
  extern int	autovacuum_naptime;
  extern int	autovacuum_vac_thresh;
  extern double autovacuum_vac_scale;
