diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
new file mode 100644
index f6e2a28..64dcad8
*** a/contrib/vacuumlo/vacuumlo.c
--- b/contrib/vacuumlo/vacuumlo.c
***************
*** 23,28 ****
--- 23,29 ----
  
  #include "libpq-fe.h"
  #include "libpq/libpq-fs.h"
+ #include <limits.h>
  
  #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
  
*************** struct _param
*** 48,53 ****
--- 49,55 ----
  	char	   *pg_host;
  	int			verbose;
  	int			dry_run;
+ 	int			transaction_limit;
  };
  
  int			vacuumlo(char *, struct _param *);
*************** vacuumlo(char *database, struct _param *
*** 70,75 ****
--- 72,78 ----
  	int			i;
  	static char *password = NULL;
  	bool		new_pass;
+ 	bool        success = true;
  
  	if (param->pg_prompt == TRI_YES && password == NULL)
  		password = simple_prompt("Password: ", 100, false);
*************** vacuumlo(char *database, struct _param *
*** 280,291 ****
--- 283,303 ----
  			{
  				fprintf(stderr, "\nFailed to remove lo %u: ", lo);
  				fprintf(stderr, "%s", PQerrorMessage(conn));
+ 				if (PQtransactionStatus(conn) == PQTRANS_INERROR) {
+ 					fprintf(stderr, 
+ 							"Bailing out. Try using -l LIMIT flag, "
+ 							"with a LIMIT of %d\n", i);
+ 					success = false;
+ 					break;
+ 				}
  			}
  			else
  				deleted++;
  		}
  		else
  			deleted++;
+ 		if (param->transaction_limit != 0 && deleted >= param->transaction_limit)
+ 			break;
  	}
  	PQclear(res);
  
*************** vacuumlo(char *database, struct _param *
*** 297,307 ****
  
  	PQfinish(conn);
  
! 	if (param->verbose)
! 		fprintf(stdout, "\r%s %d large objects from %s.\n",
! 		   (param->dry_run ? "Would remove" : "Removed"), deleted, database);
  
! 	return 0;
  }
  
  void
--- 309,326 ----
  
  	PQfinish(conn);
  
! 	if (param->verbose) {
! 		if (param->dry_run)
! 			fprintf(stdout, "\rWould remove");
! 		else if (success)
! 			fprintf(stdout, "\rSuccessfully removed");
! 		else
! 			fprintf(stdout, "\rFailed to remove");
  
! 		fprintf(stdout, " %d large objects from %s.\n", deleted, database);
! 	}
! 
! 	return ((param->dry_run || success) ? 0 : -1);
  }
  
  void
*************** usage(const char *progname)
*** 311,316 ****
--- 330,336 ----
  	printf("Usage:\n  %s [OPTION]... DBNAME...\n\n", progname);
  	printf("Options:\n");
  	printf("  -h HOSTNAME  database server host or socket directory\n");
+ 	printf("  -l LIMIT     stop after removing LIMIT large objects\n");
  	printf("  -n           don't remove large objects, just show what would be done\n");
  	printf("  -p PORT      database server port\n");
  	printf("  -U USERNAME  user name to connect as\n");
*************** main(int argc, char **argv)
*** 342,347 ****
--- 362,368 ----
  	param.pg_port = NULL;
  	param.verbose = 0;
  	param.dry_run = 0;
+ 	param.transaction_limit = 0;
  
  	if (argc > 1)
  	{
*************** main(int argc, char **argv)
*** 359,365 ****
  
  	while (1)
  	{
! 		c = getopt(argc, argv, "h:U:p:vnwW");
  		if (c == -1)
  			break;
  
--- 380,386 ----
  
  	while (1)
  	{
! 		c = getopt(argc, argv, "h:l:U:p:vnwW");
  		if (c == -1)
  			break;
  
*************** main(int argc, char **argv)
*** 395,400 ****
--- 416,429 ----
  				}
  				param.pg_port = strdup(optarg);
  				break;
+ 			case 'l':
+ 				param.transaction_limit = strtol(optarg, NULL, 10);
+ 				if ((param.transaction_limit < 0) || (param.transaction_limit > INT_MAX))
+ 				{
+ 					fprintf(stderr, "%s: invalid transaction limit number: %s, valid range is form 0(disabled) to INT_MAX(%i).\n", progname, optarg, INT_MAX);
+ 					exit(1);
+ 				}
+ 				break;
  			case 'h':
  				param.pg_host = strdup(optarg);
  				break;
diff --git a/doc/src/sgml/vacuumlo.sgml b/doc/src/sgml/vacuumlo.sgml
new file mode 100644
index 471a6ca..905eae1
*** a/doc/src/sgml/vacuumlo.sgml
--- b/doc/src/sgml/vacuumlo.sgml
*************** vacuumlo [options] database [database2 .
*** 57,62 ****
--- 57,72 ----
     </varlistentry>
  
     <varlistentry>
+     <term><option>-l</option> <replaceable>limit</></term>
+     <listitem>
+      <para>
+       Stop after removing LIMIT large objects. Useful to avoid 
+       exceeding <varname>max_locks_per_transaction</varname>.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><option>-w</></term>
      <term><option>--no-password</></term>
      <listitem>
