Skip to content

Commit c161069

Browse files
committed
fix: resolve memory leak with gradual buffer shrinking strategy
Implement sophisticated buffer management that only shrinks when buffer is more than half empty, and reduces to half size (not exact size) to provide wiggle room for incoming data. This prevents both memory leaks from oversized buffers and performance issues from excessive reallocations in high-throughput scenarios. - Only shrink when buffer utilization < 50% - When shrinking, reduce to max(half current size, 2x remaining data) - Gradual reduction allows large buffers to shrink progressively - Falls back to cursor strategy when buffer utilization is reasonable
1 parent 34b5c51 commit c161069

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

packages/pg-protocol/src/parser.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,25 @@ export class Parser {
113113
this.bufferOffset = 0
114114
} else {
115115
// A partial message remains.
116-
// Create a new, smaller buffer and copy only the remaining data into it.
117-
// This breaks the reference to the original, potentially huge buffer.
116+
// Use a gradual shrinking strategy: only shrink if buffer is at least half empty,
117+
// and when shrinking, reduce to half size (not exact size) to provide wiggle room.
118118
const remainingLength = bufferFullLength - offset
119-
const newBuffer = Buffer.allocUnsafe(remainingLength)
120-
this.buffer.copy(newBuffer, 0, offset, offset + remainingLength)
121-
122-
this.buffer = newBuffer
123-
this.bufferOffset = 0
124-
this.bufferLength = remainingLength
119+
const bufferUtilization = remainingLength / this.buffer.byteLength
120+
121+
if (bufferUtilization < 0.5) {
122+
// Buffer is more than half empty - shrink it to half its current size
123+
const newBufferSize = Math.max(this.buffer.byteLength / 2, remainingLength * 2)
124+
const newBuffer = Buffer.allocUnsafe(newBufferSize)
125+
this.buffer.copy(newBuffer, 0, offset, offset + remainingLength)
126+
127+
this.buffer = newBuffer
128+
this.bufferOffset = 0
129+
this.bufferLength = remainingLength
130+
} else {
131+
// Buffer utilization is reasonable - use existing cursor strategy
132+
this.bufferLength = remainingLength
133+
this.bufferOffset = offset
134+
}
125135
}
126136
}
127137

0 commit comments

Comments
 (0)