3 Commits

Author SHA1 Message Date
vakabunga
67fed57118 fix: disable gzip and pad SSE events to prevent proxy buffering
Add gzip off to Nginx import location — the global gzip on was
buffering text/event-stream responses. Pad each SSE event to 4 KB
with comment lines to push past any remaining proxy buffer threshold.
2026-03-14 19:45:33 +03:00
45a6f3d374 Merge pull request 'fix: eliminate SSE buffering through Nginx proxy' (#8) from fix/sse-proxy-buffering into main
Reviewed-on: #8
2026-03-14 14:31:16 +00:00
vakabunga
aaf8cacf75 fix: eliminate SSE buffering through Nginx proxy
Add 2 KB padding comment after headers to push past proxy buffer
threshold, enable TCP_NODELAY on the socket, and remove erroneous
chunked_transfer_encoding off from Nginx that caused full response
buffering.
2026-03-14 17:30:52 +03:00
2 changed files with 9 additions and 2 deletions

View File

@@ -28,8 +28,14 @@ function isJsonFile(file: { mimetype: string; originalname: string }): boolean {
); );
} }
const SSE_PAD_TARGET = 4096;
function sseWrite(res: import('express').Response, data: Record<string, unknown>) { function sseWrite(res: import('express').Response, data: Record<string, unknown>) {
res.write(`data: ${JSON.stringify(data)}\n\n`); const payload = `data: ${JSON.stringify(data)}\n\n`;
const pad = Math.max(0, SSE_PAD_TARGET - payload.length);
// SSE comment lines (": ...") are ignored by the browser but push
// data past proxy buffer thresholds so each event is delivered immediately.
res.write(pad > 0 ? `: ${' '.repeat(pad)}\n${payload}` : payload);
} }
const router = Router(); const router = Router();
@@ -60,6 +66,7 @@ router.post(
res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive'); res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no'); res.setHeader('X-Accel-Buffering', 'no');
res.socket?.setNoDelay(true);
res.flushHeaders(); res.flushHeaders();
try { try {

View File

@@ -15,7 +15,7 @@ server {
proxy_connect_timeout 5s; proxy_connect_timeout 5s;
proxy_read_timeout 600s; proxy_read_timeout 600s;
proxy_buffering off; proxy_buffering off;
chunked_transfer_encoding off; gzip off;
client_max_body_size 15m; client_max_body_size 15m;
} }