diff --git a/libraries/AP_GPS/AP_GPS_Auto.cpp b/libraries/AP_GPS/AP_GPS_Auto.cpp
index 42b6a276f1e449abc4ffe40650d5789da49edef9..8be05dfdd32f96b7b7af588457ecac0da143fd23 100644
--- a/libraries/AP_GPS/AP_GPS_Auto.cpp
+++ b/libraries/AP_GPS/AP_GPS_Auto.cpp
@@ -54,11 +54,13 @@ AP_GPS_Auto::read(void)
 			last_baud = 0;
 		}
 		// write config strings for the types of GPS we support
-		_write_progstr_block(_fs, _mtk_set_binary, sizeof(_mtk_set_binary));
-		_write_progstr_block(_fs, AP_GPS_UBLOX::_ublox_set_binary, AP_GPS_UBLOX::_ublox_set_binary_size);
-		_write_progstr_block(_fs, _sirf_set_binary, sizeof(_sirf_set_binary));
+		_send_progstr(_fs, _mtk_set_binary, sizeof(_mtk_set_binary));
+		_send_progstr(_fs, AP_GPS_UBLOX::_ublox_set_binary, AP_GPS_UBLOX::_ublox_set_binary_size);
+		_send_progstr(_fs, _sirf_set_binary, sizeof(_sirf_set_binary));
 	}
 
+	_update_progstr();
+
 	if (NULL != (gps = _detect())) {
 		// configure the detected GPS
 		gps->init(_nav_setting);
@@ -115,3 +117,6 @@ AP_GPS_Auto::_detect(void)
 	return NULL;
 }
 
+
+
+
diff --git a/libraries/AP_GPS/GPS.cpp b/libraries/AP_GPS/GPS.cpp
index a97e6636c06234276453b0bc58f0326632ed43df..d5dfbcdf23f9f7e7d08bb7e5c569d13264f956f8 100644
--- a/libraries/AP_GPS/GPS.cpp
+++ b/libraries/AP_GPS/GPS.cpp
@@ -96,3 +96,60 @@ void GPS::_write_progstr_block(Stream *_fs, const prog_char *pstr, uint8_t size)
         _fs->write(pgm_read_byte(pstr++));
     }
 }
+
+/*
+  a prog_char block queue, used to send out config commands to a GPS
+  in 16 byte chunks. This saves us having to have a 128 byte GPS send
+  buffer, while allowing us to avoid a long delay in sending GPS init
+  strings while waiting for the GPS auto detection to happen
+ */
+
+// maximum number of pending progstrings
+#define PROGSTR_QUEUE_SIZE 3
+
+struct progstr_queue {
+	const prog_char *pstr;
+	uint8_t ofs, size;
+};
+
+static struct {
+    FastSerial *fs;
+	uint8_t queue_size;
+	uint8_t idx, next_idx;
+	struct progstr_queue queue[PROGSTR_QUEUE_SIZE];
+} progstr_state;
+
+void GPS::_send_progstr(Stream *_fs, const prog_char *pstr, uint8_t size)
+{
+	progstr_state.fs = (FastSerial *)_fs;
+	struct progstr_queue *q = &progstr_state.queue[progstr_state.next_idx];
+	q->pstr = pstr;
+	q->size = size;
+	q->ofs = 0;
+	progstr_state.next_idx++;
+	if (progstr_state.next_idx == PROGSTR_QUEUE_SIZE) {
+		progstr_state.next_idx = 0;
+	}
+}
+
+void GPS::_update_progstr(void)
+{
+	struct progstr_queue *q = &progstr_state.queue[progstr_state.idx];
+	// quick return if nothing to do
+	if (q->size == 0 || progstr_state.fs->tx_pending()) {
+		return;
+	}
+	uint8_t nbytes = q->size - q->ofs;
+	if (nbytes > 16) {
+		nbytes = 16;
+	}
+	_write_progstr_block(progstr_state.fs, q->pstr+q->ofs, nbytes);
+	q->ofs += nbytes;
+	if (q->ofs == q->size) {
+		q->size = 0;
+		progstr_state.idx++;
+		if (progstr_state.idx == PROGSTR_QUEUE_SIZE) {
+			progstr_state.idx = 0;
+		}
+	}
+}
diff --git a/libraries/AP_GPS/GPS.h b/libraries/AP_GPS/GPS.h
index 9e09633052c4ad4f509f7810bc93a81a571b1bda..2a1d50bdf9500d389a604fca094319d56737c003 100644
--- a/libraries/AP_GPS/GPS.h
+++ b/libraries/AP_GPS/GPS.h
@@ -195,6 +195,8 @@ protected:
     enum GPS_Engine_Setting _nav_setting;
 
     void _write_progstr_block(Stream *_fs, const prog_char *pstr, uint8_t size);
+    void _send_progstr(Stream *_fs, const prog_char *pstr, uint8_t size);
+    void _update_progstr(void);
 
     // velocities in cm/s if available from the GPS
     int32_t _vel_north;