diff --git a/configure.ac b/configure.ac
index e5cac45b..7f2b6b11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -692,7 +692,7 @@ if test x"$magick6" = x"yes"; then
   # IM
   save_LIBS="$LIBS"
   LIBS="$LIBS $MAGICK_LIBS"
-  AC_CHECK_FUNCS([InheritException AcquireExceptionInfo SetImageProperty SetImageExtent AcquireImage GetVirtualPixels ResetImageProfileIterator ResetImageAttributeIterator ResetImagePropertyIterator MagickCoreGenesis SetImageOption BlobToStringInfo])
+  AC_CHECK_FUNCS([InheritException AcquireExceptionInfo SetImageProperty SetImageExtent AcquireImage GetVirtualPixels ResetImageProfileIterator ResetImageAttributeIterator ResetImagePropertyIterator MagickCoreGenesis SetImageOption BlobToStringInfo OptimizePlusImageLayers OptimizeImageTransparency])
   LIBS="$save_LIBS"
 fi
 
diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c
index 5d1312e9..304809d7 100644
--- a/libvips/foreign/magick.c
+++ b/libvips/foreign/magick.c
@@ -205,6 +205,31 @@ magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
 	image_info->scenes = strdup( page );
 }
 
+int
+magick_optimize_image_layers( Image **images, ExceptionInfo *exception )
+{
+	Image *tmp;
+
+	tmp = OptimizePlusImageLayers(*images, exception );
+
+	if ( exception->severity != UndefinedException )
+		return MagickFalse;
+
+	VIPS_FREEF( DestroyImageList, *images );
+
+	*images = tmp;
+
+	return MagickTrue;
+}
+
+int
+magick_optimize_image_transparency( const Image *images,
+	ExceptionInfo *exception )
+{
+	OptimizeImageTransparency(images, exception);
+	return ( exception->severity == UndefinedException );
+}
+
 /* Does a few bytes look like a file IM can handle?
  */
 gboolean
@@ -445,6 +470,43 @@ magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
 #endif
 }
 
+int
+magick_optimize_image_layers( Image **images, ExceptionInfo *exception )
+{
+#ifdef HAS_OPTIMIZEPLUSIMAGELAYERS
+	Image *tmp;
+
+	tmp = OptimizePlusImageLayers(*images, exception );
+
+	if ( exception->severity != UndefinedException )
+		return MagickFalse;
+
+	VIPS_FREEF( DestroyImageList, *images );
+
+	*images = tmp;
+
+	return MagickTrue;
+#else
+	g_warning( "%s", _( "layers optimization is not supported by your version "
+		"of libMagick" ) );
+	return MagickTrue;
+#endif
+}
+
+int
+magick_optimize_image_transparency( const Image *images,
+	ExceptionInfo *exception )
+{
+#ifdef HAS_OPTIMIZEIMAGETRANSPARENCY
+	OptimizeImageTransparency(images, exception);
+	return ( exception->severity == UndefinedException );
+#else
+	g_warning( "%s", _( "transparency optimization is not supported by your "
+		"version of libMagick" ) );
+	return MagickTrue;
+#endif
+}
+
 /* Does a few bytes look like a file IM can handle?
  */
 gboolean
diff --git a/libvips/foreign/magick.h b/libvips/foreign/magick.h
index 05304134..21b56bed 100644
--- a/libvips/foreign/magick.h
+++ b/libvips/foreign/magick.h
@@ -84,6 +84,10 @@ int magick_set_vips_profile( VipsImage *im, Image *image );
 int magick_set_magick_profile( Image *image, 
 	VipsImage *im, ExceptionInfo *exception );
 
+int magick_optimize_image_layers( Image **images, ExceptionInfo *exception );
+int magick_optimize_image_transparency( const Image *images,
+    ExceptionInfo *exception );
+
 gboolean magick_ismagick( const unsigned char *bytes, size_t length );
 
 #endif /*HAVE_MAGICK6*/
diff --git a/libvips/foreign/magicksave.c b/libvips/foreign/magicksave.c
index 68a80e31..78142784 100644
--- a/libvips/foreign/magicksave.c
+++ b/libvips/foreign/magicksave.c
@@ -10,6 +10,8 @@
  * 	- support "strip" option
  * 6/7/19 [deftomat]
  * 	- support array of delays 
+ * 5/8/19 DarthSim
+ * 	- support GIF optimization
  */
 
 /*
@@ -63,6 +65,8 @@ typedef struct _VipsForeignSaveMagick {
 	char *filename;		/* NULL during buffer output */
 	char *format;
 	int quality;
+	gboolean optimize_gif_frames;
+	gboolean optimize_gif_transparency;
 
 	ImageInfo *image_info;
 	ExceptionInfo *exception;
@@ -365,6 +369,24 @@ vips_foreign_save_magick_build( VipsObject *object )
 		vips_foreign_save_magick_write_block, magick ) ) 
 		return( -1 );
 
+	if( magick->optimize_gif_frames ) {
+		if( !magick_optimize_image_layers(&magick->images, magick->exception ) ) {
+			magick_inherit_exception( magick->exception, magick->images );
+			magick_vips_error( class->nickname, magick->exception );
+
+			return( -1 );
+		}
+	}
+
+	if( magick->optimize_gif_transparency ) {
+		if( !magick_optimize_image_transparency(magick->images, magick->exception) ) {
+			magick_inherit_exception( magick->exception, magick->images );
+			magick_vips_error( class->nickname, magick->exception );
+
+			return( -1 );
+		}
+	}
+
 	return( 0 );
 }
 
@@ -428,6 +450,20 @@ vips_foreign_save_magick_class_init( VipsForeignSaveMagickClass *class )
 		VIPS_ARGUMENT_OPTIONAL_INPUT,
 		G_STRUCT_OFFSET( VipsForeignSaveMagick, quality ),
 		0, 100, 0 );
+
+	VIPS_ARG_BOOL( class, "optimize_gif_frames", 4,
+		_( "Optimize_gif_frames" ),
+		_( "Apply GIF frames optimization" ),
+		VIPS_ARGUMENT_OPTIONAL_INPUT,
+		G_STRUCT_OFFSET( VipsForeignSaveMagick, optimize_gif_frames ),
+		FALSE );
+
+	VIPS_ARG_BOOL( class, "optimize_gif_transparency", 5,
+		_( "Optimize_gif_transparency" ),
+		_( "Apply GIF transparency optimization" ),
+		VIPS_ARGUMENT_OPTIONAL_INPUT,
+		G_STRUCT_OFFSET( VipsForeignSaveMagick, optimize_gif_transparency ),
+		FALSE );
 }
 
 static void
@@ -586,6 +622,8 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
  *
  * * @quality: %gint, quality factor
  * * @format: %gchararray, format to save as
+ * * @optimize_gif_frames: %gboolean, apply GIF frames optimization
+ * * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
  *
  * Write an image using libMagick.
  *
@@ -594,6 +632,15 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
  * Use @format to explicitly set the save format, for example, "BMP". Otherwise
  * the format is guessed from the filename suffix.
  *
+ * If @optimize_gif_frames is set, GIF frames are cropped to the smallest size
+ * while preserving the results of the GIF animation. This takes some time for
+ * computation but saves some time on encoding and produces smaller files in
+ * some cases.
+ *
+ * If @optimize_gif_transparency is set, pixels that don't change the image
+ * through animation are made transparent. This takes some time for computation
+ * but saves some time on encoding and produces smaller files in some cases.
+ *
  * See also: vips_magicksave_buffer(), vips_magickload().
  *
  * Returns: 0 on success, -1 on error.
@@ -622,6 +669,8 @@ vips_magicksave( VipsImage *in, const char *filename, ... )
  *
  * * @quality: %gint, quality factor
  * * @format: %gchararray, format to save as
+ * * @optimize_gif_frames: %gboolean, apply GIF frames optimization
+ * * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization
  *
  * As vips_magicksave(), but save to a memory buffer. 
  *