diff --git a/src/ring.c b/src/ring.c
index aa4e364..c00acda 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -124,8 +124,8 @@ _vte_ring_freeze_row (VteRing *ring, gulong position, const VteRowData *row)
 
 	_vte_debug_print (VTE_DEBUG_RING, "Freezing row %lu.\n", position);
 
-	record.text_start_offset = _vte_stream_head (ring->text_stream, 0);
-	record.attr_start_offset = _vte_stream_head (ring->attr_stream, 0);
+	record.text_start_offset = _vte_stream_head (ring->text_stream);
+	record.attr_start_offset = _vte_stream_head (ring->attr_stream);
 
 	g_string_set_size (buffer, 0);
 	for (i = 0, cell = row->cells; i < row->len; i++, cell++) {
@@ -199,11 +199,11 @@ _vte_ring_thaw_row (VteRing *ring, gulong position, VteRowData *row, gboolean do
 
 	if (!_vte_ring_read_row_record (ring, &records[0], position))
 		return;
-	if ((position + 1) * sizeof (records[0]) < _vte_stream_head (ring->row_stream, 0)) {
+	if ((position + 1) * sizeof (records[0]) < _vte_stream_head (ring->row_stream)) {
 		if (!_vte_ring_read_row_record (ring, &records[1], position + 1))
 			return;
 	} else
-		records[1].text_start_offset = _vte_stream_head (ring->text_stream, 0);
+		records[1].text_start_offset = _vte_stream_head (ring->text_stream);
 
 	g_string_set_size (buffer, records[1].text_start_offset - records[0].text_start_offset);
 	if (!_vte_stream_read (ring->text_stream, records[0].text_start_offset, buffer->str, buffer->len))
@@ -301,24 +301,8 @@ _vte_ring_reset_streams (VteRing *ring, gulong position)
 
 	ring->last_attr_text_start_offset = 0;
 	ring->last_attr.i = basic_cell.i.attr;
-
-	ring->last_page = position;
-}
-
-static void
-_vte_ring_new_page (VteRing *ring)
-{
-	_vte_debug_print (VTE_DEBUG_RING, "Starting new stream page at %lu.\n", ring->writable);
-
-	_vte_stream_new_page (ring->attr_stream);
-	_vte_stream_new_page (ring->text_stream);
-	_vte_stream_new_page (ring->row_stream);
-
-	ring->last_page = ring->writable;
 }
 
-
-
 static inline VteRowData *
 _vte_ring_writable_index (VteRing *ring, gulong position)
 {
@@ -365,9 +349,6 @@ _vte_ring_freeze_one_row (VteRing *ring)
 	_vte_ring_freeze_row (ring, ring->writable, row);
 
 	ring->writable++;
-
-	if (G_UNLIKELY (ring->writable == ring->last_page || ring->writable - ring->last_page >= ring->max))
-		_vte_ring_new_page (ring);
 }
 
 static void
@@ -394,7 +375,14 @@ _vte_ring_discard_one_row (VteRing *ring)
 {
 	ring->start++;
 	if (G_UNLIKELY (ring->start == ring->writable)) {
-		_vte_ring_reset_streams (ring, 0);
+		_vte_ring_reset_streams (ring, ring->writable);
+	} else {
+		VteRowRecord record;
+		_vte_stream_advance_tail (ring->row_stream, ring->start * sizeof (record));
+		if (G_LIKELY (_vte_ring_read_row_record (ring, &record, ring->start))) {
+			_vte_stream_advance_tail (ring->text_stream, record.text_start_offset);
+			_vte_stream_advance_tail (ring->attr_stream, record.attr_start_offset);
+		}
 	}
 	if (ring->start > ring->writable)
 		ring->writable = ring->start;
@@ -475,7 +463,7 @@ _vte_ring_resize (VteRing *ring, gulong max_rows)
 	if ((gulong) _vte_ring_length (ring) > max_rows) {
 		ring->start = ring->end - max_rows;
 		if (ring->start >= ring->writable) {
-			_vte_ring_reset_streams (ring, 0);
+			_vte_ring_reset_streams (ring, ring->writable);
 			ring->writable = ring->start;
 		}
 	}
@@ -665,7 +653,7 @@ _vte_ring_write_contents (VteRing *ring,
 		if (_vte_ring_read_row_record (ring, &record, ring->start))
 		{
 			gsize start_offset = record.text_start_offset;
-			gsize end_offset = _vte_stream_head (ring->text_stream, 0);
+			gsize end_offset = _vte_stream_head (ring->text_stream);
 			char buf[4096];
 			while (start_offset < end_offset)
 			{
diff --git a/src/ring.h b/src/ring.h
index d4cab96..bd98e4a 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -53,7 +53,6 @@ struct _VteRing {
 	VteRowData *array;
 
 	/* Storage */
-	gulong last_page;
 	VteStream *attr_stream, *text_stream, *row_stream;
 	gsize last_attr_text_start_offset;
 	VteIntCellAttr last_attr;
diff --git a/src/vtestream-base.h b/src/vtestream-base.h
index 2732b20..f40fd6a 100644
--- a/src/vtestream-base.h
+++ b/src/vtestream-base.h
@@ -36,8 +36,8 @@ typedef struct _VteStreamClass {
 	void (*append) (VteStream *stream, const char *data, gsize len);
 	gboolean (*read) (VteStream *stream, gsize offset, char *data, gsize len);
 	void (*truncate) (VteStream *stream, gsize offset);
-	void (*new_page) (VteStream *stream);
-	gsize (*head) (VteStream *stream, guint index);
+	void (*advance_tail) (VteStream *stream, gsize offset);
+	gsize (*head) (VteStream *stream);
 } VteStreamClass;
 
 static GType _vte_stream_get_type (void);
@@ -81,15 +81,13 @@ _vte_stream_truncate (VteStream *stream, gsize offset)
 }
 
 void
-_vte_stream_new_page (VteStream *stream)
+_vte_stream_advance_tail (VteStream *stream, gsize offset)
 {
-	VTE_STREAM_GET_CLASS (stream)->new_page (stream);
+	VTE_STREAM_GET_CLASS (stream)->advance_tail (stream, offset);
 }
 
 gsize
-_vte_stream_head (VteStream *stream, guint index)
+_vte_stream_head (VteStream *stream)
 {
-	g_assert (index < 3);
-
-	return VTE_STREAM_GET_CLASS (stream)->head (stream, index);
+	return VTE_STREAM_GET_CLASS (stream)->head (stream);
 }
diff --git a/src/vtestream-file.h b/src/vtestream-file.h
index e9d8d77..06de79d 100644
--- a/src/vtestream-file.h
+++ b/src/vtestream-file.h
@@ -460,22 +460,24 @@ _vte_file_stream_truncate (VteStream *astream, gsize offset)
 }
 
 static void
-_vte_file_stream_new_page (VteStream *astream)
+_vte_file_stream_advance_tail (VteStream *astream, gsize offset)
 {
 	VteFileStream *stream = (VteFileStream *) astream;
 
-	stream->offset[1] = stream->offset[0];
-	stream->offset[0] = stream->head;
-	_vte_file_stream_swap_fds (stream);
-	_file_reset (&stream->file[0]);
+	if (offset >= stream->offset[0]) {
+		stream->offset[1] = stream->offset[0];
+		stream->offset[0] = stream->head;
+		_vte_file_stream_swap_fds (stream);
+		_file_reset (&stream->file[0]);
+	}
 }
 
 static gsize
-_vte_file_stream_head (VteStream *astream, guint _index)
+_vte_file_stream_head (VteStream *astream)
 {
 	VteFileStream *stream = (VteFileStream *) astream;
 
-	return _index == 0 ? stream->head : stream->offset[_index - 1];
+	return stream->head;
 }
 
 static void
@@ -489,6 +491,6 @@ _vte_file_stream_class_init (VteFileStreamClass *klass)
 	klass->append = _vte_file_stream_append;
 	klass->read = _vte_file_stream_read;
 	klass->truncate = _vte_file_stream_truncate;
-	klass->new_page = _vte_file_stream_new_page;
+	klass->advance_tail = _vte_file_stream_advance_tail;
 	klass->head = _vte_file_stream_head;
 }
diff --git a/src/vtestream.h b/src/vtestream.h
index e968d42..ada51e9 100644
--- a/src/vtestream.h
+++ b/src/vtestream.h
@@ -32,13 +32,8 @@ void _vte_stream_reset (VteStream *stream, gsize offset);
 void _vte_stream_append (VteStream *stream, const char *data, gsize len);
 gboolean _vte_stream_read (VteStream *stream, gsize offset, char *data, gsize len);
 void _vte_stream_truncate (VteStream *stream, gsize offset);
-void _vte_stream_new_page (VteStream *stream);
-/* The stream has two pages at each time.  This function returns three positions:
- * - index == 0 -> position of writing head,
- * - index == 1 -> start of current page,
- * - index == 2 -> start of previous page (ie. last offset available in stream)
- */
-gsize _vte_stream_head (VteStream *stream, guint index);
+void _vte_stream_advance_tail (VteStream *stream, gsize offset);
+gsize _vte_stream_head (VteStream *stream);
 
 /* Various streams */
 
