diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index aa90503..3a307b1 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -85,6 +85,7 @@ extern uint32 bootstrap_data_checksum_version;
 int			max_wal_size = 64;	/* 1 GB */
 int			min_wal_size = 5;	/* 80 MB */
 int			wal_keep_segments = 0;
+int			wal_write_chunk_size = 4096; /* 4K */
 int			XLOGbuffers = -1;
 int			XLogArchiveTimeout = 0;
 int			XLogArchiveMode = ARCHIVE_MODE_OFF;
@@ -2154,10 +2155,13 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 	bool		last_iteration;
 	bool		finishing_seg;
 	bool		use_existent;
+	bool		first_write;
 	int			curridx;
 	int			npages;
 	int			startidx;
 	uint32		startoffset;
+	uint32		startidx_offset;
+	XLogRecPtr	startXLogPtr;
 
 	/* We should always be inside a critical section here */
 	Assert(CritSectionCount > 0);
@@ -2174,11 +2178,20 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 	 * written together; startidx is the cache block index of the first one,
 	 * and startoffset is the file offset at which it should go. The latter
 	 * two variables are only valid when npages > 0, but we must initialize
-	 * all of them to keep the compiler quiet.
+	 * all of them to keep the compiler quiet.  startidx_offset is the offset
+	 * of the cached block which indicates from where to start writing and
+	 * startXLogPtr is used to calculate the startoffset for the first write.
+	 * startidx_offset and startXLogPtr helps to calculate the starting position
+	 * of write, we need to start writing from the wal_write_chunk_size boundary
+	 * or from beginning of page.  Writing in wal_write_chunk_size sized chunks
+	 * helps in reducing the re-write of data.
 	 */
 	npages = 0;
 	startidx = 0;
 	startoffset = 0;
+	startidx_offset = 0;
+	startXLogPtr = LogwrtResult.Write;
+	first_write = true;
 
 	/*
 	 * Within the loop, curridx is the cache block index of the page to
@@ -2236,7 +2249,26 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 		{
 			/* first of group */
 			startidx = curridx;
-			startoffset = (LogwrtResult.Write - XLOG_BLCKSZ) % XLogSegSize;
+			startidx_offset = 0;
+
+			/*
+			 * for first page, we need to start writing from wal_write_chunk_size
+			 * boundary or beginning of page.
+			 */
+			if (first_write)
+			{
+				uint32	start_chunk_pos = 0;
+
+				/* position the start at wal_write_chunk_size boundary. */
+				start_chunk_pos = floor((double) (startXLogPtr % XLOG_BLCKSZ) / wal_write_chunk_size);
+				startidx_offset = start_chunk_pos * wal_write_chunk_size;
+
+				startoffset = (LogwrtResult.Write - XLOG_BLCKSZ + startidx_offset) % XLogSegSize;
+			}
+			else
+				startoffset = (LogwrtResult.Write - XLOG_BLCKSZ) % XLogSegSize;
+
+			first_write = false;
 		}
 		npages++;
 
@@ -2273,8 +2305,45 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 			}
 
 			/* OK to write the page(s) */
-			from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ;
-			nbytes = npages * (Size) XLOG_BLCKSZ;
+			from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ + startidx_offset;
+
+			/*
+			 * Write in wal_write_chunk_size sized chunks.  In case, previous
+			 * write finishes at page boundary less than wal_write_chunk_size
+			 * and current write (WriteRqst.Write) falls in next chunk of page,
+			 * then we need to write the data in both the chunks.
+			 */
+			if (last_iteration)
+			{
+				uint32		chunk_pos = 0;
+				uint32		chunk_size = 0;
+
+				if (npages > 1)
+				{
+					nbytes = (npages - 1) * (Size) XLOG_BLCKSZ - startidx_offset;
+
+					if (((uint32) WriteRqst.Write) % XLOG_BLCKSZ == 0)
+						chunk_pos = ceil((double) XLOG_BLCKSZ / wal_write_chunk_size);
+					else
+						chunk_pos = ceil((double) (((uint32) WriteRqst.Write) % XLOG_BLCKSZ) / wal_write_chunk_size);
+
+					chunk_size = chunk_pos * wal_write_chunk_size;
+					nbytes += chunk_size;
+				}
+				else
+				{
+					if (((uint32) WriteRqst.Write) % XLOG_BLCKSZ == 0)
+						chunk_pos = ceil((double) XLOG_BLCKSZ / wal_write_chunk_size);
+					else
+						chunk_pos = ceil((double) (((uint32) WriteRqst.Write) % XLOG_BLCKSZ) / wal_write_chunk_size);
+
+					chunk_size = chunk_pos * wal_write_chunk_size;
+					nbytes = chunk_size - startidx_offset;
+				}
+			}
+			else
+				nbytes = npages * (Size) XLOG_BLCKSZ - startidx_offset;
+
 			nleft = nbytes;
 			do
 			{
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 38ba82f..876c934 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2220,6 +2220,16 @@ static struct config_int ConfigureNamesInt[] =
 	},
 
 	{
+		{"wal_write_chunk_size", PGC_POSTMASTER, WAL_SETTINGS,
+			gettext_noop("Sets the chunk size used for wal writing."),
+			NULL
+		},
+		&wal_write_chunk_size,
+		4096, 512, XLOG_BLCKSZ,
+		NULL, NULL, NULL
+	},
+
+	{
 		{"wal_writer_delay", PGC_SIGHUP, WAL_SETTINGS,
 			gettext_noop("WAL writer sleep time between WAL flushes."),
 			NULL,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 029114f..62423a7 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -192,6 +192,7 @@
 #wal_buffers = -1			# min 32kB, -1 sets based on shared_buffers
 					# (change requires restart)
 #wal_writer_delay = 200ms		# 1-10000 milliseconds
+#wal_write_chunk_size = 4096		# chunk size used for wal writing
 
 #commit_delay = 0			# range 0-100000, in microseconds
 #commit_siblings = 5			# range 1-1000
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 3de337a..93c2ac8 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -95,6 +95,7 @@ extern bool reachedConsistency;
 extern int	min_wal_size;
 extern int	max_wal_size;
 extern int	wal_keep_segments;
+extern int	wal_write_chunk_size;
 extern int	XLOGbuffers;
 extern int	XLogArchiveTimeout;
 extern int	wal_retrieve_retry_interval;
