diff --git a/src/modules/systemlib/bson/tinybson.c b/src/modules/systemlib/bson/tinybson.c
index a12485423d036166d9e28f2a83e5d8407d556d63..fa6f6924d055f340c2d2550e8f80e2a3c4a42539 100644
--- a/src/modules/systemlib/bson/tinybson.c
+++ b/src/modules/systemlib/bson/tinybson.c
@@ -338,12 +338,35 @@ write_x(bson_encoder_t encoder, const void *p, size_t s)
 {
 	CODER_CHECK(encoder);
 
-	if (encoder->fd > -1) {
+	/* bson file encoder (non-buffered) */
+	if (encoder->fd > -1 && encoder->buf == NULL) {
 		return (BSON_WRITE(encoder->fd, p, s) == (int)s) ? 0 : -1;
 	}
 
 	/* do we need to extend the buffer? */
 	while ((encoder->bufpos + s) > encoder->bufsize) {
+
+		/* bson buffered file encoder */
+		if (encoder->fd > -1) {
+			// write to disk
+			debug("writing buffer (%d) to disk", encoder->bufpos);
+			int ret = BSON_WRITE(encoder->fd, encoder->buf, encoder->bufpos);
+
+			if (ret == encoder->bufpos) {
+				// reset buffer to beginning and continue
+				encoder->bufpos = 0;
+
+				if ((encoder->bufpos + s) > encoder->bufsize) {
+					CODER_KILL(encoder, "fixed-size buffer overflow");
+				}
+
+				break;
+
+			} else {
+				CODER_KILL(encoder, "file write error");
+			}
+		}
+
 		if (!encoder->realloc_ok) {
 			CODER_KILL(encoder, "fixed-size buffer overflow");
 		}
@@ -416,6 +439,23 @@ bson_encoder_init_file(bson_encoder_t encoder, int fd)
 	return 0;
 }
 
+int
+bson_encoder_init_buf_file(bson_encoder_t encoder, int fd, void *buf, unsigned bufsize)
+{
+	encoder->fd = fd;
+	encoder->buf = (uint8_t *)buf;
+	encoder->bufpos = 0;
+	encoder->bufsize = bufsize;
+	encoder->dead = false;
+	encoder->realloc_ok = false;
+
+	if (write_int32(encoder, 0)) {
+		CODER_KILL(encoder, "write error on document length");
+	}
+
+	return 0;
+}
+
 int
 bson_encoder_init_buf(bson_encoder_t encoder, void *buf, unsigned bufsize)
 {
@@ -449,6 +489,20 @@ bson_encoder_fini(bson_encoder_t encoder)
 		CODER_KILL(encoder, "write error on document terminator");
 	}
 
+	if (encoder->fd > -1 && encoder->buf != NULL) {
+		/* write final buffer to disk */
+		int ret = BSON_WRITE(encoder->fd, encoder->buf, encoder->bufpos);
+
+		if (ret != encoder->bufpos) {
+			CODER_KILL(encoder, "write error");
+		}
+
+	} else if (encoder->buf != NULL) {
+		/* update buffer length */
+		int32_t len = bson_encoder_buf_size(encoder);
+		memcpy(encoder->buf, &len, sizeof(len));
+	}
+
 	/* sync file */
 	if (encoder->fd > -1) {
 		BSON_FSYNC(encoder->fd);
diff --git a/src/modules/systemlib/bson/tinybson.h b/src/modules/systemlib/bson/tinybson.h
index 10c244e503c2aa72d93a1ca6d53df92969a5ea20..79b7e5a2ca82371170ad67a46bdcfe6c02227fae 100644
--- a/src/modules/systemlib/bson/tinybson.h
+++ b/src/modules/systemlib/bson/tinybson.h
@@ -193,6 +193,17 @@ typedef struct bson_encoder_s {
  */
 __EXPORT int bson_encoder_init_file(bson_encoder_t encoder, int fd);
 
+/**
+ * Initialze the encoder for writing to a file.
+ *
+ * @param encoder		Encoder state structure to be initialised.
+ * @param fd			File to write to.
+ * @param buf			Buffer pointer to use, can't be NULL
+ * @param bufsize		Supplied buffer size
+ * @return			Zero on success.
+ */
+__EXPORT int bson_encoder_init_buf_file(bson_encoder_t encoder, int fd, void *buf, unsigned bufsize);
+
 /**
  * Initialze the encoder for writing to a buffer.
  *
diff --git a/src/modules/systemlib/param/CMakeLists.txt b/src/modules/systemlib/param/CMakeLists.txt
index 3abfd318bcdf9117c0e8c8212deefd864ee324da..ee24a8927b9e9003c8521668f8ab27956b94312c 100644
--- a/src/modules/systemlib/param/CMakeLists.txt
+++ b/src/modules/systemlib/param/CMakeLists.txt
@@ -78,7 +78,13 @@ add_custom_command(OUTPUT ${parameters_xml}
 		--inject-xml ${CMAKE_CURRENT_SOURCE_DIR}/parameters_injected.xml
 		--overrides ${PARAM_DEFAULT_OVERRIDES}
 		#--verbose
-	DEPENDS ${param_src_files} px_process_params.py px4params/srcparser.py px4params/srcscanner.py px4params/xmlout.py parameters_injected.xml
+	DEPENDS
+		${param_src_files}
+		parameters_injected.xml
+		px4params/srcparser.py
+		px4params/srcscanner.py
+		px4params/xmlout.py
+		px_process_params.py
 	COMMENT "Generating parameters.xml"
 )
 add_custom_target(parameters_xml DEPENDS ${parameters_xml})
diff --git a/src/modules/systemlib/param/param.c b/src/modules/systemlib/param/param.c
index 322b1fc5c3279b7cdbc8cbc004b63ff136da5a9b..ba3ed5803b4a1f5119183fced463a5be884debbc 100644
--- a/src/modules/systemlib/param/param.c
+++ b/src/modules/systemlib/param/param.c
@@ -76,7 +76,7 @@ static const char *param_default_file = PX4_ROOTFSDIR"/eeprom/parameters";
 static char *param_user_file = NULL;
 
 #if 0
-# define debug(fmt, args...)		do { warnx(fmt, ##args); } while(0)
+# define debug(fmt, args...)		do { PX4_INFO(fmt, ##args); } while(0)
 #else
 # define debug(fmt, args...)		do { } while(0)
 #endif
@@ -950,28 +950,27 @@ param_get_default_file(void)
 int
 param_save_default(void)
 {
-	int res;
+	int res = PX4_ERROR;
 #if !defined(FLASH_BASED_PARAMS)
-	int fd;
 
 	const char *filename = param_get_default_file();
 
 	/* write parameters to temp file */
-	fd = PARAM_OPEN(filename, O_WRONLY | O_CREAT, PX4_O_MODE_666);
+	int fd = PARAM_OPEN(filename, O_WRONLY | O_CREAT, PX4_O_MODE_666);
 
 	if (fd < 0) {
 		PX4_ERR("failed to open param file: %s", filename);
 		return ERROR;
 	}
 
-	res = 1;
 	int attempts = 5;
 
 	while (res != OK && attempts > 0) {
 		res = param_export(fd, false);
 		attempts--;
 
-		if (res != OK) {
+		if (res != PX4_OK) {
+			PX4_ERR("param_export failed, retrying %d", attempts);
 			lseek(fd, 0, SEEK_SET); // jump back to the beginning of the file
 		}
 	}
@@ -1047,7 +1046,7 @@ param_export(int fd, bool only_unsaved)
 	param_lock_reader();
 
 	uint8_t bson_buffer[256];
-	bson_encoder_init_buf(&encoder, &bson_buffer, sizeof(bson_buffer));
+	bson_encoder_init_buf_file(&encoder, fd, &bson_buffer, sizeof(bson_buffer));
 
 	/* no modified parameters -> we are done */
 	if (param_values == NULL) {
@@ -1069,31 +1068,14 @@ param_export(int fd, bool only_unsaved)
 		const char *name = param_name(s->param);
 		const size_t size = param_size(s->param);
 
-		// check remaining buffer size and commit to disk
-		//  total size = strlen(name) + 1 (null char) + param size + 1 (bson header) + 1 (bson end)
-		// size is doubled (floats saved as doubles)
-		const size_t total_size = strlen(name) + 2 * size + 3;
-
-		if (encoder.bufpos > encoder.bufsize - total_size) {
-			// write buffer to disk and continue
-			int ret = write(fd, encoder.buf, encoder.bufpos);
-
-			if (ret == encoder.bufpos) {
-				// reset buffer to beginning and continue
-				encoder.bufpos = 0;
-
-			} else {
-				PX4_ERR("param write error %d %d", ret, encoder.bufpos);
-				goto out;
-			}
-		}
-
 		/* append the appropriate BSON type object */
 		switch (param_type(s->param)) {
 
 		case PARAM_TYPE_INT32: {
 				const int32_t i = s->val.i;
 
+				debug("exporting: %s (%d) size: %d val: %d", name, s->param, size, i);
+
 				if (bson_encoder_append_int(&encoder, name, i)) {
 					PX4_ERR("BSON append failed for '%s'", name);
 					goto out;
@@ -1104,6 +1086,8 @@ param_export(int fd, bool only_unsaved)
 		case PARAM_TYPE_FLOAT: {
 				const float f = s->val.f;
 
+				debug("exporting: %s (%d) size: %d val: %.3f", name, s->param, size, (double)f);
+
 				if (bson_encoder_append_double(&encoder, name, f)) {
 					PX4_ERR("BSON append failed for '%s'", name);
 					goto out;
@@ -1138,14 +1122,8 @@ param_export(int fd, bool only_unsaved)
 out:
 
 	if (result == 0) {
-		result = bson_encoder_fini(&encoder);
-
-		// write and finish
-		if ((result != 0) || write(fd, encoder.buf, encoder.bufpos) != encoder.bufpos) {
-			PX4_ERR("param write error");
-
-		} else {
-			fsync(fd);
+		if (bson_encoder_fini(&encoder) != PX4_OK) {
+			PX4_ERR("bson encoder finish failed");
 		}
 	}
 
@@ -1209,6 +1187,8 @@ param_import_callback(bson_decoder_t decoder, void *private, bson_node_t node)
 
 		i = node->i;
 		v = &i;
+
+		debug("importing: %s (%d) = %d", node->name, param, i);
 		break;
 
 	case BSON_DOUBLE:
@@ -1220,6 +1200,8 @@ param_import_callback(bson_decoder_t decoder, void *private, bson_node_t node)
 
 		f = node->d;
 		v = &f;
+
+		debug("importing: %s (%d) = %.3f", node->name, param, (double)f);
 		break;
 
 	case BSON_BINDATA: